File: [local] / sys / dev / i2c / i2c_scan.c (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:09:57 2008 UTC (16 years, 5 months ago) by nbrk
Branch: OPENBSD_4_2_BASE, MAIN
CVS Tags: jornada-partial-support-wip, HEAD Changes since 1.1: +0 -0 lines
Import of OpenBSD 4.2 release kernel tree with initial code to support
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO
Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)
|
/* $OpenBSD: i2c_scan.c,v 1.97 2007/04/10 17:47:55 miod Exp $ */
/*
* Copyright (c) 2005 Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* I2C bus scanning.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#define _I2C_PRIVATE
#include <dev/i2c/i2cvar.h>
#undef I2C_DEBUG
#define I2C_VERBOSE
void iic_probe(struct device *, struct i2cbus_attach_args *, u_int8_t);
/*
* Addresses at which to probe for sensors. Skip address 0x4f, since
* probing it seems to crash at least one Sony VAIO laptop. Only a
* few chips can actually sit at that address, and vendors seem to
* place those at other addresses, so this isn't a big loss.
*/
struct {
u_int8_t start, end;
} probe_addrs[] = {
{ 0x18, 0x18 },
{ 0x1a, 0x1a },
{ 0x20, 0x2f },
{ 0x48, 0x4e }
};
#define MAX_IGNORE 8
u_int8_t ignore_addrs[MAX_IGNORE];
/*
* Some Maxim 1617 clones MAY NOT even read cmd 0xfc! When it is
* read, they will power-on-reset. Their default condition
* (control register bit 0x80) therefore will be that they assert
* /ALERT for the 5 potential errors that may occur. One of those
* errors is that the external temperature diode is missing. This
* is unfortunately a common choice of system designers, except
* suddenly now we get a /ALERT, which may on some chipsets cause
* us to receive an entirely unexpected SMI .. and then an NMI.
*
* As we probe each device, if we hit something which looks suspiciously
* like it may potentially be a 1617 or clone, we immediately set this
* variable to avoid reading that register offset.
*/
int skip_fc;
static i2c_tag_t probe_ic;
static u_int8_t probe_addr;
static u_int8_t probe_val[256];
void iicprobeinit(struct i2cbus_attach_args *, u_int8_t);
u_int8_t iicprobenc(u_int8_t);
u_int8_t iicprobe(u_int8_t);
u_int16_t iicprobew(u_int8_t);
char *lm75probe(void);
char *adm1032cloneprobe(u_int8_t);
void iic_dump(struct device *, u_int8_t, char *);
void
iicprobeinit(struct i2cbus_attach_args *iba, u_int8_t addr)
{
probe_ic = iba->iba_tag;
probe_addr = addr;
memset(probe_val, 0xff, sizeof probe_val);
}
u_int8_t
iicprobenc(u_int8_t cmd)
{
u_int8_t data;
/*
* If we think we are talking to an evil Maxim 1617 or clone,
* avoid accessing this register because it is death.
*/
if (skip_fc && cmd == 0xfc)
return (0xff);
iic_acquire_bus(probe_ic, 0);
if (iic_exec(probe_ic, I2C_OP_READ_WITH_STOP,
probe_addr, &cmd, 1, &data, 1, 0) != 0)
data = 0xff;
iic_release_bus(probe_ic, 0);
return (data);
}
u_int16_t
iicprobew(u_int8_t cmd)
{
u_int8_t data[2];
/*
* If we think we are talking to an evil Maxim 1617 or clone,
* avoid accessing this register because it is death.
*/
if (skip_fc && cmd == 0xfc)
return (0xffff);
iic_acquire_bus(probe_ic, 0);
if (iic_exec(probe_ic, I2C_OP_READ_WITH_STOP,
probe_addr, &cmd, 1, &data, 2, 0) != 0)
data[0] = data[1] = 0xff;
iic_release_bus(probe_ic, 0);
return ((data[0] << 8) | data[1]);
}
u_int8_t
iicprobe(u_int8_t cmd)
{
if (probe_val[cmd] != 0xff)
return probe_val[cmd];
probe_val[cmd] = iicprobenc(cmd);
return (probe_val[cmd]);
}
#define LM75TEMP 0x00
#define LM75CONF 0x01
#define LM75Thyst 0x02
#define LM75Tos 0x03
#define LM77Tlow 0x04
#define LM77Thigh 0x05
#define LM75TMASK 0xff80 /* 9 bits in temperature registers */
#define LM77TMASK 0xfff8 /* 13 bits in temperature registers */
/*
* The LM75/LM75A/LM77 family are very hard to detect. Thus, we check
* for all other possible chips first. These chips do not have an
* ID register. They do have a few quirks though:
* - on the LM75 and LM77, registers 0x06 and 0x07 return whatever
* value was read before
* - the LM75 lacks registers 0x04 and 0x05, so those act as above
* - the LM75A returns 0xffff for registers 0x04, 0x05, 0x06 and 0x07
* - the chip registers loop every 8 registers
* The downside is that we must read almost every register to guess
* if this is an LM75, LM75A or LM77.
*/
char *
lm75probe(void)
{
u_int16_t temp, thyst, tos, tlow, thigh, mask = LM75TMASK;
u_int8_t conf;
int i, echocount, ffffcount, score;
int echoreg67, echoreg45, ffffreg67, ffffreg45;
temp = iicprobew(LM75TEMP);
/*
* Sometimes the other probes can upset the chip, if we get 0xffff
* the first time, try it once more.
*/
if (temp == 0xffff)
temp = iicprobew(LM75TEMP);
conf = iicprobenc(LM75CONF);
thyst = iicprobew(LM75Thyst);
tos = iicprobew(LM75Tos);
/* totally bogus data */
if (conf == 0xff && temp == 0xffff && thyst == 0xffff)
return (NULL);
temp &= mask;
thyst &= mask;
tos &= mask;
/* All values the same? Very unlikely */
if (temp == thyst && thyst == tos)
return (NULL);
#if notsure
/* more register aliasing effects that indicate not a lm75 */
if ((temp >> 8) == conf)
return (NULL);
#endif
/*
* LM77/LM75 registers 6, 7
* echo whatever was read just before them from reg 0, 1, or 2
*
* LM75A doesn't appear to do this, but does appear to reliably
* return 0xffff
*/
for (i = 6, echocount = 2, ffffcount = 0; i <= 7; i++) {
if ((iicprobew(LM75TEMP) & mask) != (iicprobew(i) & mask) ||
(iicprobew(LM75Thyst) & mask) != (iicprobew(i) & mask) ||
(iicprobew(LM75Tos) & mask) != (iicprobew(i) & mask))
echocount--;
if (iicprobew(i) == 0xffff)
ffffcount++;
}
/* Make sure either both registers echo, or neither does */
if (echocount == 1 || ffffcount == 1)
return (NULL);
echoreg67 = (echocount == 0) ? 0 : 1;
ffffreg67 = (ffffcount == 0) ? 0 : 1;
/*
* LM75 has no registers 4 or 5, and they will act as echos too
*
* LM75A doesn't appear to do this either, but does appear to
* reliably return 0xffff
*/
for (i = 4, echocount = 2, ffffcount = 0; i <= 5; i++) {
if ((iicprobew(LM75TEMP) & mask) != (iicprobew(i) & mask) ||
(iicprobew(LM75Thyst) & mask) != (iicprobew(i) & mask) ||
(iicprobew(LM75Tos) & mask) != (iicprobew(i) & mask))
echocount--;
if (iicprobew(i) == 0xffff)
ffffcount++;
}
/* Make sure either both registers echo, or neither does */
if (echocount == 1 || ffffcount == 1)
return (NULL);
echoreg45 = (echocount == 0) ? 0 : 1;
ffffreg45 = (ffffcount == 0) ? 0 : 1;
/*
* If we find that 4 and 5 are not echos, and don't return 0xffff
* then based on whether the echo test of registers 6 and 7
* succeeded or not, we may have an LM77
*/
if (echoreg45 == 0 && ffffreg45 == 0 && echoreg67 == 1) {
mask = LM77TMASK;
/* mask size changed, must re-read for the next checks */
thyst = iicprobew(LM75Thyst) & mask;
tos = iicprobew(LM75Tos) & mask;
tlow = iicprobew(LM77Tlow) & mask;
thigh = iicprobew(LM77Thigh) & mask;
}
/* a real LM75/LM75A/LM77 repeats its registers.... */
for (i = 0x08; i <= 0xf8; i += 8) {
if (conf != iicprobenc(LM75CONF + i) ||
thyst != (iicprobew(LM75Thyst + i) & mask) ||
tos != (iicprobew(LM75Tos + i) & mask))
return (NULL);
/*
* Check that the repeated registers 0x06 and 0x07 still
* either echo or return 0xffff
*/
if (echoreg67 == 1) {
tos = iicprobew(LM75Tos) & mask;
if (tos != (iicprobew(0x06 + i) & mask) ||
tos != (iicprobew(0x07 + i) & mask))
return (NULL);
} else if (ffffreg67 == 1)
if (iicprobew(0x06 + i) != 0xffff ||
iicprobew(0x07 + i) != 0xffff)
return (NULL);
/*
* Check that the repeated registers 0x04 and 0x05 still
* either echo or return 0xffff. If they do neither, and
* registers 0x06 and 0x07 echo, then we will be probing
* for an LM77, so make sure those still repeat
*/
if (echoreg45 == 1) {
tos = iicprobew(LM75Tos) & mask;
if (tos != (iicprobew(LM77Tlow + i) & mask) ||
tos != (iicprobew(LM77Thigh + i) & mask))
return (NULL);
} else if (ffffreg45 == 1) {
if (iicprobew(LM77Tlow + i) != 0xffff ||
iicprobew(LM77Thigh + i) != 0xffff)
return (NULL);
} else if (echoreg67 == 1)
if (tlow != (iicprobew(LM77Tlow + i) & mask) ||
thigh != (iicprobew(LM77Thigh + i) & mask))
return (NULL);
}
/*
* Given that we now know how the first eight registers behave and
* that this behaviour is consistently repeated, we can now use
* the following table:
*
* echoreg67 | echoreg45 | ffffreg67 | ffffreg45 | chip
* ----------+-----------+-----------+-----------+------
* 1 | 1 | 0 | 0 | LM75
* 1 | 0 | 0 | 0 | LM77
* 0 | 0 | 1 | 1 | LM75A
*/
/* Convert the various flags into a single score */
score = (echoreg67 << 3) + (echoreg45 << 2) + (ffffreg67 << 1) +
ffffreg45;
switch (score) {
case 12:
return ("lm75");
case 8:
return ("lm77");
case 3:
return ("lm75a");
default:
#if defined(I2C_DEBUG)
printf("lm75probe: unknown chip, scored %d\n", score);
#endif /* defined(I2C_DEBUG) */
return (NULL);
}
}
char *
adm1032cloneprobe(u_int8_t addr)
{
if (addr == 0x18 || addr == 0x1a || addr == 0x29 ||
addr == 0x2b || addr == 0x4c || addr == 0x4e) {
u_int8_t reg, val;
int zero = 0, copy = 0;
val = iicprobe(0x00);
for (reg = 0x00; reg < 0x09; reg++) {
if (iicprobe(reg) == 0xff)
return (NULL);
if (iicprobe(reg) == 0x00)
zero++;
if (val == iicprobe(reg))
copy++;
}
if (zero > 6 || copy > 6)
return (NULL);
val = iicprobe(0x09);
for (reg = 0x0a; reg < 0xfc; reg++) {
if (iicprobe(reg) != val)
return (NULL);
}
/* 0xfe may be Maxim, or some other vendor */
if (iicprobe(0xfe) == 0x4d)
return ("max1617");
/*
* "xeontemp" is the name we choose for clone chips
* which have all sorts of buggy bus interactions, such
* as those we just probed. Why?
* Intel is partly to blame for this situation.
*/
return ("xeontemp");
}
return (NULL);
}
void
iic_ignore_addr(u_int8_t addr)
{
int i;
for (i = 0; i < sizeof(ignore_addrs); i++)
if (ignore_addrs[i] == 0) {
ignore_addrs[i] = addr;
return;
}
}
#if defined(I2C_DEBUG) || defined(I2C_VERBOSE)
void
iic_dump(struct device *dv, u_int8_t addr, char *name)
{
static u_int8_t iicvalcnt[256];
u_int8_t val, val2, max;
int i, cnt = 0;
/*
* Don't bother printing the most often repeated register
* value, since it is often weird devices that respond
* incorrectly, busted controller driver, or in the worst
* case, it in mosts cases, the value 0xff.
*/
bzero(iicvalcnt, sizeof iicvalcnt);
val = iicprobe(0);
iicvalcnt[val]++;
for (i = 1; i <= 0xff; i++) {
val2 = iicprobe(i);
iicvalcnt[val2]++;
if (val == val2)
cnt++;
}
for (val = max = i = 0; i <= 0xff; i++)
if (max < iicvalcnt[i]) {
max = iicvalcnt[i];
val = i;
}
if (cnt <= 254) {
printf("%s: addr 0x%x", dv->dv_xname, addr);
for (i = 0; i <= 0xff; i++) {
if (iicprobe(i) != val)
printf(" %02x=%02x", i, iicprobe(i));
}
if (name)
printf(": %s", name);
printf("\n");
}
}
#endif /* defined(I2C_DEBUG) || defined(I2C_VERBOSE) */
void
iic_probe(struct device *self, struct i2cbus_attach_args *iba, u_int8_t addr)
{
struct i2c_attach_args ia;
char *name = NULL;
int i;
for (i = 0; i < sizeof(ignore_addrs); i++)
if (ignore_addrs[i] == addr)
return;
iicprobeinit(iba, addr);
skip_fc = 0;
/*
* Many I2C/SMBus devices use register 0x3e as a vendor ID
* register.
*/
switch (iicprobe(0x3e)) {
case 0x01: /* National Semiconductor */
/*
* Some newer National products use a vendor code at
* 0x3e of 0x01, and then 0x3f contains a product code
* But some older products are missing a product code,
* and contain who knows what in that register. We assume
* that some employee was smart enough to keep the numbers
* unique.
*/
if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
iicprobe(0x3f) == 0x73)
name = "lm93";
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
iicprobe(0x3f) == 0x68)
name = "lm96000"; /* adt7460 compat? */
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
(iicprobe(0x3f) == 0x60 || iicprobe(0x3f) == 0x62))
name = "lm85"; /* lm85C/B == adt7460 compat */
else if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */
iicprobe(0x48) == addr &&
(iicprobe(0x3f) == 0x03 || iicprobe(0x3f) == 0x04) &&
(iicprobe(0x40) & 0x80) == 0x00)
name = "lm81";
break;
case 0x02: /* National Semiconductor? */
if ((iicprobe(0x3f) & 0xfc) == 0x04)
name = "lm87"; /* complete check */
break;
case 0x23: /* Analog Devices? */
if (iicprobe(0x48) == addr &&
(iicprobe(0x40) & 0x80) == 0x00 &&
(addr & 0x7c) == 0x2c)
name = "adm9240"; /* lm87 clone */
break;
case 0x41: /* Analog Devices */
/*
* Newer chips have a valid 0x3d product number, while
* older ones sometimes encoded the product into the
* upper half of the "step register" at 0x3f.
*/
if ((addr == 0x2c || addr == 0x2e || addr == 0x2f) &&
iicprobe(0x3d) == 0x70)
name = "adt7470";
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
iicprobe(0x3d) == 0x76)
name = "adt7476";
else if (addr == 0x2e && iicprobe(0x3d) == 0x75)
name = "adt7475";
else if (iicprobe(0x3d) == 0x27 &&
(iicprobe(0x3f) == 0x60 || iicprobe(0x3f) == 0x6a))
name = "adm1027"; /* complete check */
else if (iicprobe(0x3d) == 0x27 &&
(iicprobe(0x3f) == 0x62 || iicprobe(0x3f) == 0x6a))
name = "adt7460"; /* complete check */
else if (addr == 0x2e &&
iicprobe(0x3d) == 0x68 && (iicprobe(0x3f) & 0xf0) == 0x70)
name = "adt7467";
else if (iicprobe(0x3d) == 0x33)
name = "adm1033";
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
iicprobe(0x3d) == 0x30 &&
(iicprobe(0x01) & 0x80) == 0x00 &&
(iicprobe(0x0d) & 0x70) == 0x00 &&
(iicprobe(0x0e) & 0x70) == 0x00)
/*
* Revision 3 seems to be an adm1031 with
* remote diode 2 shorted. Therefore we
* cannot assume the reserved/unused bits of
* register 0x03 and 0x06 are set to zero.
*/
name = "adm1030"; /* complete check */
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
iicprobe(0x3d) == 0x31 &&
(iicprobe(0x01) & 0x80) == 0x00 &&
(iicprobe(0x0d) & 0x70) == 0x00 &&
(iicprobe(0x0e) & 0x70) == 0x00 &&
(iicprobe(0x0f) & 0x70) == 0x00)
name = "adm1031"; /* complete check */
else if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */
(iicprobe(0x3f) & 0xf0) == 0x20 &&
(iicprobe(0x40) & 0x80) == 0x00 &&
(iicprobe(0x41) & 0xc0) == 0x00 &&
(iicprobe(0x42) & 0xbc) == 0x00)
name = "adm1025"; /* complete check */
else if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */
(iicprobe(0x3f) & 0xf0) == 0x10 &&
(iicprobe(0x40) & 0x80) == 0x00)
name = "adm1024"; /* complete check */
else if ((iicprobe(0xff) & 0xf0) == 0x30)
name = "adm1023";
else if (addr == 0x2e &&
(iicprobe(0x3f) & 0xf0) == 0xd0 &&
(iicprobe(0x40) & 0x80) == 0x00)
name = "adm1028"; /* adm1022 clone? */
else if ((addr == 0x2c || addr == 0x2e || addr == 0x2f) &&
(iicprobe(0x3f) & 0xf0) == 0xc0 &&
(iicprobe(0x40) & 0x80) == 0x00)
name = "adm1022";
break;
case 0x49: /* Texas Instruments */
if ((addr == 0x2c || addr == 0x2e || addr == 0x2f) &&
(iicprobe(0x3f) & 0xf0) == 0xc0 &&
(iicprobe(0x40) & 0x80) == 0x00)
name = "thmc50"; /* adm1022 clone */
break;
case 0x55: /* SMSC */
if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */
iicprobe(0x3f) == 0x20 &&
(iicprobe(0x47) & 0x70) == 0x00 &&
(iicprobe(0x49) & 0xfe) == 0x80)
name = "47m192"; /* adm1025 compat */
break;
case 0x5c: /* SMSC */
if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
(iicprobe(0x3f) & 0xf0) == 0x60)
name = "emc6d100"; /* emc6d101, emc6d102, emc6d103 */
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
(iicprobe(0x3f) & 0xf0) == 0x80)
name = "sch5017";
else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
(iicprobe(0x3f) & 0xf0) == 0xb0)
name = "emc6w201";
break;
case 0xa1: /* Philips */
if ((iicprobe(0x3f) & 0xf0) == 0x20 &&
(iicprobe(0x40) & 0x80) == 0x00 &&
(iicprobe(0x41) & 0xc0) == 0x00 &&
(iicprobe(0x42) & 0xbc) == 0x00)
name = "ne1619"; /* adm1025 compat */
break;
case 0xda: /* Dallas Semiconductor */
if (iicprobe(0x3f) == 0x01 && iicprobe(0x48) == addr &&
(iicprobe(0x40) & 0x80) == 0x00)
name = "ds1780"; /* lm87 clones */
break;
}
switch (iicprobe(0x4e)) {
case 0x41: /* Analog Devices */
if ((addr == 0x48 || addr == 0x4a || addr == 0x4b) &&
(iicprobe(0x4d) == 0x03 || iicprobe(0x4d) == 0x08 ||
iicprobe(0x4d) == 0x07))
name = "adt7516"; /* adt7517, adt7519 */
break;
}
switch (iicprobe(0xfe)) {
case 0x01: /* National Semiconductor */
if (addr == 0x4c &&
iicprobe(0xff) == 0x41 && (iicprobe(0x03) & 0x18) == 0 &&
iicprobe(0x04) <= 0x0f && (iicprobe(0xbf) & 0xf8) == 0)
name = "lm63";
else if (addr == 0x4c &&
iicprobe(0xff) == 0x11 && (iicprobe(0x03) & 0x2a) == 0 &&
iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0)
name = "lm86";
else if (addr == 0x4c &&
iicprobe(0xff) == 0x31 && (iicprobe(0x03) & 0x2a) == 0 &&
iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0)
name = "lm89"; /* or lm99 */
else if (addr == 0x4d &&
iicprobe(0xff) == 0x34 && (iicprobe(0x03) & 0x2a) == 0 &&
iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0)
name = "lm89-1"; /* or lm99-1 */
else if (addr == 0x4c &&
iicprobe(0xff) == 0x21 && (iicprobe(0x03) & 0x2a) == 0 &&
iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0)
name = "lm90";
break;
case 0x23: /* Genesys Logic? */
if ((addr == 0x4c) &&
(iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08)
/*
* Genesys Logic doesn't make the datasheet
* for the GL523SM publically available, so
* the checks above are nothing more than a
* (conservative) educated guess.
*/
name = "gl523sm";
break;
case 0x41: /* Analog Devices */
if ((addr == 0x4c || addr == 0x4d) &&
iicprobe(0xff) == 0x51 &&
(iicprobe(0x03) & 0x1f) == 0x04 &&
iicprobe(0x04) <= 0x0a) {
/* If not in adm1032 compatibility mode. */
name = "adt7461";
} else if ((addr == 0x18 || addr == 0x19 || addr == 0x1a ||
addr == 0x29 || addr == 0x2a || addr == 0x2b ||
addr == 0x4c || addr == 0x4d || addr == 0x4e) &&
(iicprobe(0xff) & 0xf0) == 0x00 &&
(iicprobe(0x03) & 0x3f) == 0x00 &&
iicprobe(0x04) <= 0x07) {
name = "adm1021";
skip_fc = 1;
} else if ((addr == 0x18 || addr == 0x19 || addr == 0x1a ||
addr == 0x29 || addr == 0x2a || addr == 0x2b ||
addr == 0x4c || addr == 0x4d || addr == 0x4e) &&
(iicprobe(0xff) & 0xf0) == 0x30 &&
(iicprobe(0x03) & 0x3f) == 0x00 &&
iicprobe(0x04) <= 0x07) {
name = "adm1023"; /* or adm1021a */
skip_fc = 1;
} else if ((addr == 0x4c || addr == 0x4d || addr == 0x4e) &&
(iicprobe(0x03) & 0x3f) == 0x00 &&
iicprobe(0x04) <= 0x0a) {
name = "adm1032"; /* or adm1020 */
skip_fc = 1;
}
break;
case 0x47: /* Global Mixed-mode Technology */
if (addr == 0x4c && iicprobe(0xff) == 0x01 &&
(iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08)
name = "g781";
if (addr == 0x4d && iicprobe(0xff) == 0x03 &&
(iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08)
name = "g781-1";
break;
case 0x4d: /* Maxim */
if ((addr == 0x18 || addr == 0x19 || addr == 0x1a ||
addr == 0x29 || addr == 0x2a || addr == 0x2b ||
addr == 0x4c || addr == 0x4d || addr == 0x4e) &&
iicprobe(0xff) == 0x08 && (iicprobe(0x02) & 0x03) == 0 &&
(iicprobe(0x03) & 0x07) == 0 && iicprobe(0x04) <= 0x08)
name = "max6690";
else if ((addr == 0x4c || addr == 0x4d || addr == 0x4e) &&
iicprobe(0xff) == 0x59 && (iicprobe(0x03) & 0x1f) == 0 &&
iicprobe(0x04) <= 0x07)
name = "max6646"; /* max6647/8/9, max6692 */
else if ((addr == 0x4c || addr == 0x4d || addr == 0x4e) &&
(iicprobe(0x02) & 0x2b) == 0 &&
(iicprobe(0x03) & 0x0f) == 0 && iicprobe(0x04) <= 0x09) {
name = "max6657"; /* max6658, max6659 */
skip_fc = 1;
} else if ((addr >= 0x48 && addr <= 0x4f) &&
(iicprobe(0x02) & 0x2b) == 0 &&
(iicprobe(0x03) & 0x0f) == 0)
name = "max6642";
break;
}
if (addr == iicprobe(0x48) &&
((iicprobe(0x4f) == 0x5c && (iicprobe(0x4e) & 0x80)) ||
(iicprobe(0x4f) == 0xa3 && !(iicprobe(0x4e) & 0x80)))) {
/*
* We could toggle 0x4e bit 0x80, then re-read 0x4f to
* see if the value changes to 0xa3 (indicating Winbond).
* But we are trying to avoid writes.
*/
if ((iicprobe(0x4e) & 0x07) == 0) {
switch (iicprobe(0x58)) {
case 0x10:
case 0x11: /* rev 2? */
name = "w83781d";
break;
case 0x21:
name = "w83627hf";
break;
case 0x30:
name = "w83782d";
break;
case 0x31:
name = "as99127f"; /* rev 2 */
break;
case 0x40:
name = "w83783s";
break;
case 0x71:
name = "w83791d";
break;
case 0x72:
name = "w83791sd";
break;
case 0x7a:
name = "w83792d";
break;
}
} else {
/*
* The BIOS left the chip in a non-zero
* register bank. Assume it's a W83781D and
* let lm(4) sort out the real model.
*/
name = "w83781d";
}
} else if (addr == iicprobe (0x4a) && iicprobe(0x4e) == 0x50 &&
iicprobe(0x4c) == 0xa3 && iicprobe(0x4d) == 0x5c) {
name = "w83l784r";
} else if (addr == 0x2d && iicprobe(0x4e) == 0x60 &&
iicprobe(0x4c) == 0xa3 && iicprobe(0x4d) == 0x5c) {
name = "w83l785r";
} else if (addr == 0x2e && iicprobe(0x4e) == 0x70 &&
iicprobe(0x4c) == 0xa3 && iicprobe(0x4d) == 0x5c) {
name = "w83l785ts-l";
} else if (addr >= 0x28 && addr <= 0x2f &&
iicprobe(0x4f) == 0x12 && (iicprobe(0x4e) & 0x80)) {
/*
* We could toggle 0x4e bit 0x80, then re-read 0x4f to
* see if the value changes to 0xc3 (indicating ASUS).
* But we are trying to avoid writes.
*/
if (iicprobe(0x58) == 0x31)
name = "as99127f"; /* rev 1 */
} else if ((addr == 0x2d || addr == 0x2e) &&
addr * 2 == iicprobe(0x04) &&
iicprobe(0x5d) == 0x19 && iicprobe(0x5e) == 0x34 &&
iicprobe(0x5a) == 0x03 && iicprobe(0x5b) == 0x06) {
name = "f75375"; /* Fintek */
} else if (addr == 0x2d &&
((iicprobe(0x4f) == 0x06 && (iicprobe(0x4e) & 0x80)) ||
(iicprobe(0x4f) == 0x94 && !(iicprobe(0x4e) & 0x80)))) {
/*
* We could toggle 0x4e bit 0x80, then re-read 0x4f to
* see if the value changes to 0x94 (indicating ASUS).
* But we are trying to avoid writes.
*
* NB. we won't match if the BIOS has selected a non-zero
* register bank (set via 0x4e). We could select bank 0 so
* we see the right registers, but that would require a
* write. In general though, we bet no BIOS would leave us
* in the wrong state.
*/
if ((iicprobe(0x58) & 0x7f) == 0x31 &&
(iicprobe(0x4e) & 0xf) == 0x00)
name = "asb100";
} else if ((addr == 0x2c || addr == 0x2d) &&
iicprobe(0x00) == 0x80 &&
(iicprobe(0x01) == 0x00 || iicprobe(0x01) == 0x80) &&
iicprobe(0x02) == 0x00 && (iicprobe(0x03) & 0x83) == 0x00 &&
(iicprobe(0x0f) & 0x07) == 0x00 &&
(iicprobe(0x11) & 0x80) == 0x00 &&
(iicprobe(0x12) & 0x80) == 0x00) {
/*
* The GL518SM is really crappy. It has both byte and
* word registers, and reading a word register with a
* byte read command will make the device crap out and
* hang the bus. This has nasty consequences on some
* machines, like preventing warm reboots. The word
* registers are 0x07 through 0x0c, so make sure the
* checks above don't access those registers. We
* don't want to do this check right up front though
* since this chip is somewhat hard to detect (which
* is why we check for every single fixed bit it has).
*/
name = "gl518sm";
} else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) &&
iicprobe(0x16) == 0x41 && ((iicprobe(0x17) & 0xf0) == 0x40)) {
name = "adm1026";
} else if (name == NULL &&
(addr & 0x78) == 0x48) { /* addr 0b1001xxx */
name = lm75probe();
}
#if 0
/*
* XXX This probe needs to be improved; the driver does some
* dangerous writes.
*/
if (name == NULL && (addr & 0x7c) == 0x48 && /* addr 0b1001xxx */
(iicprobew(0xaa) & 0x0007) == 0x0000 &&
(iicprobew(0xa1) & 0x0007) == 0x0000 &&
(iicprobew(0xa2) & 0x0007) == 0x0000 &&
(iicprobe(0xac) & 0x10) == 0x00) {
if ((iicprobe(0xac) & 0x7e) == 0x0a &&
iicprobe(0xab) == 0x00 && iicprobe(0xa8) == 0x00)
name = "ds1624";
else if ((iicprobe(0xac) & 0x7e) == 0x0c)
name = "ds1631"; /* terrible probe */
else if ((iicprobe(0xac) & 0x2e) == 0x2e)
name = "ds1721"; /* terrible probe */
}
#endif
if (name == NULL && (addr & 0xf8) == 0x28 && iicprobe(0x48) == addr &&
(iicprobe(0x00) & 0x90) == 0x10 && iicprobe(0x58) == 0x90) {
if (iicprobe(0x5b) == 0x12)
name = "it8712";
else if (iicprobe(0x5b) == 0x00)
name = "it8712f-a"; /* sis950 too */
}
if (name == NULL && iicprobe(0x48) == addr &&
(iicprobe(0x40) & 0x80) == 0x00 && iicprobe(0x58) == 0xac)
name = "mtp008";
if (name == NULL) {
name = adm1032cloneprobe(addr);
if (name)
skip_fc = 1;
}
#ifdef I2C_DEBUG
iic_dump(self, addr, name);
#endif /* I2C_DEBUG */
#if !defined(I2C_VERBOSE) && !defined(I2C_DEBUG)
if (name == NULL)
name = "unknown";
#endif
if (name) {
memset(&ia, 0, sizeof(ia));
ia.ia_tag = iba->iba_tag;
ia.ia_addr = addr;
ia.ia_size = 1;
ia.ia_name = name;
if (config_found(self, &ia, iic_print))
return;
}
#if defined(I2C_VERBOSE) && !defined(I2C_DEBUG)
iic_dump(self, addr, name);
#endif /* defined(I2C_VERBOSE) && !defined(I2C_DEBUG) */
}
void
iic_scan(struct device *self, struct i2cbus_attach_args *iba)
{
i2c_tag_t ic = iba->iba_tag;
u_int8_t cmd = 0, addr;
int i;
bzero(ignore_addrs, sizeof(ignore_addrs));
for (i = 0; i < sizeof(probe_addrs)/sizeof(probe_addrs[0]); i++) {
for (addr = probe_addrs[i].start; addr <= probe_addrs[i].end;
addr++) {
/* Perform RECEIVE BYTE command */
iic_acquire_bus(ic, 0);
if (iic_exec(ic, I2C_OP_READ_WITH_STOP, addr,
&cmd, 1, NULL, 0, 0) == 0) {
iic_release_bus(ic, 0);
/* Some device exists, so go scope it out */
iic_probe(self, iba, addr);
iic_acquire_bus(ic, 0);
}
iic_release_bus(ic, 0);
}
}
}