tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

More i2c auto configuration improvements



I’ve gone through all of the i2c drivers I can find in the source tree and audited their auto configuration scheme.  Each of the drivers has been updated to return the “match quality” values introduced in the previous set of changes.  To review, those “match quality” values are:

— Address-only: “Yes, this is a valid address for this device”.  Used in indirect-config.

— Address-and-probe: “Yes, this is a valid address for this device, and I’ve looked at it and it seems to be what I expect”.  Used in indirect-config.

— Compatible-match: “One of the ‘compatible’ properties of the device matched one of my ‘compatible-with’ strings.”.  Used in direct-config.

— Specific-match: “A specific device driver was requested, and I’m it.”  Used in direct-config.

For a lot of drivers, the changes were purely mechanical, i.e. returning the correct I2C_MATCH_* constant.

I did introduce a new helper function to centralize the direct-config matching logic for drivers that support it:

bool iic_use_direct_match(const struct i2c_attach_args *ia, const cfdata_t cf, const char **compats, int *match_resultp);

This function checks to see if the attach_args indicate direct-config.  If they don’t, it returns false.  If they do, it returns true and places the match quality result into *match_resultp.  The match is first done against specific-driver, which compares ia->ia_name to the driver name retrieved via the passed-in cfdata_t (cf->cf_driver->cd_name).  Failing that, the passed-in compats array is checked as the old iic_compat_match() did.  If there is a match there, a match quality is computed and returned.  The match quality is computed by adding the reverse-index of the device’s matching compatible property to the base I2C_MATCH_DIRECT_COMPATIBLE value.  The reason for this is that a more-specific driver can match a device with a higher “compatible” match quality.  Take for example a device with the following “compatible” properties:

	foo,foo666-phy
	generic-phy

…and we have to drivers: “foo666phy” and “genericphy”, with compats arrays of  { “foo,foo666-phy”, NULL }, and { “generic-phy”, NULL } respectively.  The “genericphy” driver would of course work with the foo666 device, but may have reduced functionality.  By weighting the match in this way we guarantee that a driver that matches the more-specific compatible string is the one that’s selected to drive the device.  I adjusted some of the match quality base values to provide plenty of weighting-space between compatible and specific.

The general pattern that most drivers can use now is:

const char *foo_compats[] = { “foo,foo666phy”, NULL };

int
foo_match(device_t parent, cfdata_t cf, void *aux)
{
	struct i2c_attach_args *ia = aux;
	int match_result;

	if (iic_use_direct_match(ia, cf, foo_compats, &match_result))
		return (match_result);

	if (ia->ia_addr == FOO_ADDR1 || ia->ia_addr == FOO_ADDR2)
		return (I2C_MATCH_ADDRESS_ONLY);

	return (0);
}

I’ve made sure all of this at least compiles (well, I’m pretty sure I didn’t miss anything), including the machine-dependent drivers for sparc64, macppc, and various ARM and MIPS devices.  I still have some testing to do (I need to fake up some direct-config info for my particular RPI configuration to test out that logic thoroughly).  But I want to get some eyeballs on the changes and feedback early.

Index: arch/evbmips/loongson/dev/stvii.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbmips/loongson/dev/stvii.c,v
retrieving revision 1.5
diff -u -p -r1.5 stvii.c
--- arch/evbmips/loongson/dev/stvii.c	29 Feb 2016 18:24:31 -0000	1.5
+++ arch/evbmips/loongson/dev/stvii.c	14 Jun 2018 13:30:01 -0000
@@ -136,7 +136,7 @@ stvii_match(device_t parent, cfdata_t cf
 		DPRINTF("%02x\n", in);
 		iic_release_bus(args->ia_tag, 0);
 	}
-	return (ret >= 0);
+	return (ret >= 0) ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
 }
 
 static void
Index: arch/hpcarm/dev/nbppcon.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcarm/dev/nbppcon.c,v
retrieving revision 1.2
diff -u -p -r1.2 nbppcon.c
--- arch/hpcarm/dev/nbppcon.c	16 Jun 2012 05:58:03 -0000	1.2
+++ arch/hpcarm/dev/nbppcon.c	14 Jun 2018 13:30:01 -0000
@@ -78,7 +78,7 @@ nbppcon_match(device_t parent, cfdata_t 
 	    !platid_match(&platid, &platid_mask_MACH_PSIONTEKLOGIX_NETBOOK_PRO))
 		 return 0;
 
-	return 1;
+	return I2C_MATCH_ADDRESS_AND_PROBE;
 }
 
 /* ARGSUSED */
Index: arch/macppc/dev/deq.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/deq.c,v
retrieving revision 1.13
diff -u -p -r1.13 deq.c
--- arch/macppc/dev/deq.c	4 May 2018 17:15:23 -0000	1.13
+++ arch/macppc/dev/deq.c	14 Jun 2018 13:30:02 -0000
@@ -65,16 +65,14 @@ int
 deq_match(device_t parent, struct cfdata *cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
-	
-	if (ia->ia_name) {
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, deq_compats))
-				return 1;
-		}
-		if (strcmp(ia->ia_name, "deq") == 0)
-			return 1;
-	}
-	return 0;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, deq_compats, &match_result))
+		return (match_result);
+
+	/* This driver is direct-config only. */
+
+	return (0);
 }
 
 void
Index: arch/macppc/dev/smusat.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/smusat.c,v
retrieving revision 1.3
diff -u -p -r1.3 smusat.c
--- arch/macppc/dev/smusat.c	20 Apr 2018 18:22:50 -0000	1.3
+++ arch/macppc/dev/smusat.c	14 Jun 2018 13:30:02 -0000
@@ -115,15 +115,15 @@ static int
 smusat_match(device_t parent, struct cfdata *cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL) {
-		/* no ID registers on this chip */
-		if (ia->ia_addr == 0x58)
-			return 1;
-		return 0;
-	} else {
-		return iic_compat_match(ia, smusat_compats);
-	}
+	if (iic_use_direct_match(ia, cf, smusat_compats, &match_result))
+		return (match_result);
+
+	if (ia->ia_addr == 0x58)
+		return (I2C_MATCH_ADDRESS_ONLY);
+
+	return (0);
 }
 
 static void
Index: arch/macppc/dev/videopll.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/videopll.c,v
retrieving revision 1.2
diff -u -p -r1.2 videopll.c
--- arch/macppc/dev/videopll.c	22 Sep 2017 04:01:41 -0000	1.2
+++ arch/macppc/dev/videopll.c	14 Jun 2018 13:30:02 -0000
@@ -70,9 +70,12 @@ static int
 videopll_match(device_t parent, cfdata_t cfdata, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (strcmp(ia->ia_name, "videopll") == 0)
-		return 100;
+	if (iic_use_direct_match(ia, cfdata, NULL, &match_result))
+		return (match_result);
+	
+	/* This driver is direct-config only. */
 
 	return 0;
 }
Index: arch/sparc64/dev/pcf8591_envctrl.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/dev/pcf8591_envctrl.c,v
retrieving revision 1.6
diff -u -p -r1.6 pcf8591_envctrl.c
--- arch/sparc64/dev/pcf8591_envctrl.c	18 Mar 2012 05:26:58 -0000	1.6
+++ arch/sparc64/dev/pcf8591_envctrl.c	14 Jun 2018 13:30:02 -0000
@@ -78,9 +78,12 @@ static int
 ecadc_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (iic_compat_match(ia, ecadc_compats))
-		return 1;
+	if (iic_use_direct_match(ia, cf, ecadc_compats, &match_result))
+		return (match_result);
+
+	/* This driver is direct-config only. */
 
 	return 0;
 }
Index: arch/sparc64/dev/tda.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/dev/tda.c,v
retrieving revision 1.11
diff -u -p -r1.11 tda.c
--- arch/sparc64/dev/tda.c	7 Jul 2016 06:55:38 -0000	1.11
+++ arch/sparc64/dev/tda.c	14 Jun 2018 13:30:03 -0000
@@ -100,7 +100,9 @@ tda_match(device_t parent, cfdata_t matc
 	 */
 	if (ia->ia_name == NULL)
 		return(0);
-	return strcmp(ia->ia_name, "fan-control") == 0;
+
+	return strcmp(ia->ia_name, "fan-control") == 0 ?
+	    I2C_MATCH_DIRECT_SPECIFIC : 0;
 }
 
 void
Index: arch/zaurus/dev/ioexp.c
===================================================================
RCS file: /cvsroot/src/sys/arch/zaurus/dev/ioexp.c,v
retrieving revision 1.1
diff -u -p -r1.1 ioexp.c
--- arch/zaurus/dev/ioexp.c	19 Jun 2011 16:20:09 -0000	1.1
+++ arch/zaurus/dev/ioexp.c	14 Jun 2018 13:30:03 -0000
@@ -86,20 +86,19 @@ static int
 ioexp_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
 	/* only for SL-C1000 */
 	if (!ZAURUS_ISC1000)
 		return 0;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "ioexp") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == IOEXP_ADDRESS)
-			return 1;
-	}
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+	
+	/* indirect config - check typical address */
+	if (ia->ia_addr == IOEXP_ADDRESS)
+		return I2C_MATCH_ADDRESS_ONLY;
+
 	return 0;
 }
 
Index: arch/zaurus/dev/wm8731_zaudio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/zaurus/dev/wm8731_zaudio.c,v
retrieving revision 1.1
diff -u -p -r1.1 wm8731_zaudio.c
--- arch/zaurus/dev/wm8731_zaudio.c	23 Sep 2014 14:49:46 -0000	1.1
+++ arch/zaurus/dev/wm8731_zaudio.c	14 Jun 2018 13:30:03 -0000
@@ -211,19 +211,18 @@ wm8731_write(struct zaudio_softc *sc, in
 int
 wm8731_match(device_t parent, cfdata_t cf, struct i2c_attach_args *ia)
 {
+	int match_result;
 
 	if (ZAURUS_ISC1000 || ZAURUS_ISC3000)
 		return 0;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "zaudio") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == WM8731_ADDRESS)
-			return 1;
-	}
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+
+	/* indirect config - check typical address */
+	if (ia->ia_addr == WM8731_ADDRESS)
+		return I2C_MATCH_ADDRESS_ONLY;
+
 	return 0;
 }
 
Index: arch/zaurus/dev/wm8750_zaudio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/zaurus/dev/wm8750_zaudio.c,v
retrieving revision 1.1
diff -u -p -r1.1 wm8750_zaudio.c
--- arch/zaurus/dev/wm8750_zaudio.c	23 Sep 2014 14:49:46 -0000	1.1
+++ arch/zaurus/dev/wm8750_zaudio.c	14 Jun 2018 13:30:03 -0000
@@ -276,19 +276,18 @@ wm8750_write(struct zaudio_softc *sc, in
 int
 wm8750_match(device_t parent, cfdata_t cf, struct i2c_attach_args *ia)
 {
+	int match_result;
 
 	if (ZAURUS_ISC860)
 		return 0;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "zaudio") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == WM8750_ADDRESS)
-			return 1;
-	}
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+	
+	/* indirect config - check typical address */
+	if (ia->ia_addr == WM8750_ADDRESS)
+		return I2C_MATCH_ADDRESS_ONLY;
+
 	return 0;
 }
 
Index: dev/i2c/ac100.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/ac100.c,v
retrieving revision 1.1
diff -u -p -r1.1 ac100.c
--- dev/i2c/ac100.c	7 Dec 2014 14:24:11 -0000	1.1
+++ dev/i2c/ac100.c	14 Jun 2018 13:30:03 -0000
@@ -109,7 +109,7 @@ CFATTACH_DECL_NEW(ac100ic, sizeof(struct
 static int
 ac100_match(device_t parent, cfdata_t match, void *aux)
 {
-	return 1;
+	return (I2C_MATCH_ADDRESS_ONLY);	/* XXX */
 }
 
 static void
Index: dev/i2c/act8846.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/act8846.c,v
retrieving revision 1.4
diff -u -p -r1.4 act8846.c
--- dev/i2c/act8846.c	30 Apr 2018 20:26:09 -0000	1.4
+++ dev/i2c/act8846.c	14 Jun 2018 13:30:03 -0000
@@ -151,7 +151,7 @@ act8846_match(device_t parent, cfdata_t 
 	struct i2c_attach_args *ia = aux;
 
 	if (ia->ia_addr == 0x5a)
-		return 1;
+		return (I2C_MATCH_ADDRESS_ONLY);
 
 	return 0;
 }
Index: dev/i2c/adadc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/adadc.c,v
retrieving revision 1.3
diff -u -p -r1.3 adadc.c
--- dev/i2c/adadc.c	16 Mar 2018 22:10:31 -0000	1.3
+++ dev/i2c/adadc.c	14 Jun 2018 13:30:03 -0000
@@ -105,19 +105,20 @@ static int
 adadc_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL) {
-		/*
-		 * XXX
-		 * this driver is pretty much useless without OF, should
-		 * probably remove this
-		 */
-		if ((ia->ia_addr & 0x2b) == 0x2b)
-			return 1;
-		return 0;
-	} else {
-		return iic_compat_match(ia, dstemp_compats);
-	}
+	if (iic_use_direct_match(ia, match, dstemp_compats, &match_result))
+		return (match_result);
+
+	/*
+	 * XXX
+	 * this driver is pretty much useless without OF, should
+	 * probably remove this
+	 */
+	if ((ia->ia_addr & 0x2b) == 0x2b)
+		return I2C_MATCH_ADDRESS_ONLY;
+
+	return 0;
 }
 
 static void
Index: dev/i2c/adm1021.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/adm1021.c,v
retrieving revision 1.16
diff -u -p -r1.16 adm1021.c
--- dev/i2c/adm1021.c	29 Sep 2017 14:17:47 -0000	1.16
+++ dev/i2c/adm1021.c	14 Jun 2018 13:30:03 -0000
@@ -162,31 +162,21 @@ int
 admtemp_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL) {
-		/*
-		 * Indirect config - not much we can do!
-		 * Check typical addresses.
-		 */
-		if (((ia->ia_addr >= 0x18) && (ia->ia_addr <= 0x1a)) ||
-		    ((ia->ia_addr >= 0x29) && (ia->ia_addr <= 0x2b)) ||
-		    ((ia->ia_addr >= 0x48) && (ia->ia_addr <= 0x4e)))
-			return (1);
-	} else {
-		/*
-		 * Direct config - match via the list of compatible
-		 * hardware or simply match the device name.
-		 */
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, admtemp_compats))
-				return 1;
-		} else {
-			if (strcmp(ia->ia_name, "admtemp") == 0)
-				return 1;
-		}
-	}
+	if (iic_use_direct_match(ia, match, admtemp_compats, &match_result))
+		return (match_result);
+	
+	/*
+	 * Indirect config - not much we can do!
+	 * Check typical addresses.
+	 */
+	if (((ia->ia_addr >= 0x18) && (ia->ia_addr <= 0x1a)) ||
+	    ((ia->ia_addr >= 0x29) && (ia->ia_addr <= 0x2b)) ||
+	    ((ia->ia_addr >= 0x48) && (ia->ia_addr <= 0x4e)))
+		return (I2C_MATCH_ADDRESS_ONLY);
 
-	return 0;
+	return (0);
 }
 
 static int
Index: dev/i2c/adm1026.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/adm1026.c,v
retrieving revision 1.2
diff -u -p -r1.2 adm1026.c
--- dev/i2c/adm1026.c	11 Jan 2016 18:23:52 -0000	1.2
+++ dev/i2c/adm1026.c	14 Jun 2018 13:30:03 -0000
@@ -132,24 +132,20 @@ adm1026_match(device_t parent, cfdata_t 
 {
 	struct i2c_attach_args *ia = aux;
 	struct adm1026_softc sc;	/* For chip ident */
+	int match_result;
+
 	sc.sc_tag = ia->ia_tag;
 	sc.sc_address = ia->ia_addr;
 	sc.sc_iic_flags = 0;
 
-	/* Direct config - match compats */
-	if (ia->ia_name) {
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, adm1026_compats))
-				return 1;
-		}
-	/* Indirect config - check address and chip ID/rev. */
-	} else {
-		if ((ia->ia_addr & ADM1026_ADDRMASK) == ADM1026_ADDR &&
-		    adm1026_ident(&sc))
-			return 1;
-	}
+	if (iic_use_direct_match(ia, cf, adm1026_compats, &match_result))
+		return (match_result);
 
-	return 0;
+	if ((ia->ia_addr & ADM1026_ADDRMASK) == ADM1026_ADDR &&
+	    adm1026_ident(&sc))
+		return (I2C_MATCH_ADDRESS_AND_PROBE);
+
+	return (0);
 }
 
 static int
Index: dev/i2c/am2315.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/am2315.c,v
retrieving revision 1.2
diff -u -p -r1.2 am2315.c
--- dev/i2c/am2315.c	30 Dec 2017 03:18:26 -0000	1.2
+++ dev/i2c/am2315.c	14 Jun 2018 13:30:03 -0000
@@ -170,42 +170,19 @@ am2315_poke_m(i2c_tag_t tag, i2c_addr_t 
 static int
 am2315_match(device_t parent, cfdata_t match, void *aux)
 {
-	struct i2c_attach_args *ia;
+	struct i2c_attach_args *ia = aux;
 	int rv;
 	const bool matchdebug = false;
+	int match_result;
 
-	ia = aux;
-
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "am2315temp") != 0)
-			return 0;
-	} else {
-		/* indirect config - check for configured address */
-		if (ia->ia_addr != AM2315_TYPICAL_ADDR)
-			return 0;
-	}
-
-	/*
-	 * Check to see if something is really at this i2c address. This will
-	 * keep phantom devices from appearing
-	 */
-	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
-		if (matchdebug)
-			printf("in match acquire bus failed\n");
-		return 0;
-	}
+	if (iic_use_direct_match(ia, match, NULL, &match_result))
+		return (match_result);
 
-	if ((rv = am2315_poke_m(ia->ia_tag, ia->ia_addr, __func__, matchdebug))
-	    != 0) {
-		if (matchdebug)
-			printf("match rv poke %d\n", rv);
-		iic_release_bus(ia->ia_tag, 0);
-		return 0;
-	}
+	/* indirect config - check for standard address */
+	if (ia->ia_addr == AM2315_TYPICAL_ADDR)
+		return (I2C_MATCH_ADDRESS_ONLY);
 
-	iic_release_bus(ia->ia_tag, 0);
-	return 1;
+	return (0);
 }
 
 static void
Index: dev/i2c/as3722.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/as3722.c,v
retrieving revision 1.12
diff -u -p -r1.12 as3722.c
--- dev/i2c/as3722.c	28 May 2017 15:55:11 -0000	1.12
+++ dev/i2c/as3722.c	14 Jun 2018 13:30:03 -0000
@@ -51,6 +51,8 @@ __KERNEL_RCSID(0, "$NetBSD: as3722.c,v 1
 #include <dev/fdt/fdtvar.h>
 #endif
 
+#define	AS3722_I2C_ADDR			0x40
+
 #define AS3722_START_YEAR		2000
 
 #define AS3722_SD0_VOLTAGE_REG		0x00
@@ -230,22 +232,24 @@ as3722_match(device_t parent, cfdata_t m
 {
 	struct i2c_attach_args *ia = aux;
 	uint8_t reg, id1;
-	int error;
+	int error, match_result;
 
-	if (ia->ia_name == NULL) {
-		iic_acquire_bus(ia->ia_tag, I2C_F_POLL);
-		reg = AS3722_ASIC_ID1_REG;
-		error = iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
-		    &reg, 1, &id1, 1, I2C_F_POLL);
-		iic_release_bus(ia->ia_tag, I2C_F_POLL);
+	if (iic_use_direct_match(ia, match, as3722_compats, &match_result))
+		return (match_result);
+	
+	if (ia->ia_addr != AS3722_I2C_ADDR)
+		return (0);
+	
+	iic_acquire_bus(ia->ia_tag, I2C_F_POLL);
+	reg = AS3722_ASIC_ID1_REG;
+	error = iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
+	    &reg, 1, &id1, 1, I2C_F_POLL);
+	iic_release_bus(ia->ia_tag, I2C_F_POLL);
 
-		if (error == 0 && id1 == 0x0c)
-			return 1;
+	if (error == 0 && id1 == 0x0c)
+		return (I2C_MATCH_ADDRESS_AND_PROBE);
 
-		return 0;
-	} else {
-		return iic_compat_match(ia, as3722_compats);
-	}
+	return (0);
 }
 
 static void
Index: dev/i2c/at24cxx.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/at24cxx.c,v
retrieving revision 1.25
diff -u -p -r1.25 at24cxx.c
--- dev/i2c/at24cxx.c	28 Oct 2017 04:53:55 -0000	1.25
+++ dev/i2c/at24cxx.c	14 Jun 2018 13:30:03 -0000
@@ -131,19 +131,13 @@ static int
 seeprom_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name) {
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, seeprom_compats))
-				return (1);
-		} else {
-			if (strcmp(ia->ia_name, "seeprom") == 0)
-				return (1);
-		}
-	} else {
-		if ((ia->ia_addr & AT24CXX_ADDRMASK) == AT24CXX_ADDR)
-			return (1);
-	}
+	if (iic_use_direct_match(ia, cf, seeprom_compats, &match_result))
+		return (match_result);
+
+	if ((ia->ia_addr & AT24CXX_ADDRMASK) == AT24CXX_ADDR)
+		return (I2C_MATCH_ADDRESS_ONLY);
 
 	return (0);
 }
Index: dev/i2c/axp20x.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/axp20x.c,v
retrieving revision 1.10
diff -u -p -r1.10 axp20x.c
--- dev/i2c/axp20x.c	22 Oct 2017 11:00:28 -0000	1.10
+++ dev/i2c/axp20x.c	14 Jun 2018 13:30:03 -0000
@@ -47,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: axp20x.c,v 1
 #include <dev/fdt/fdtvar.h>
 #endif
 
+#define	AXP209_I2C_ADDR		0x34
+
 #define AXP_INPUT_STATUS	0x00
 #define AXP_INPUT_STATUS_AC_PRESENT	__BIT(7)
 #define AXP_INPUT_STATUS_AC_OK		__BIT(6)
@@ -221,11 +223,14 @@ static int
 axp20x_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args * const ia = aux;
+	int match_result;
+
+	if (iic_use_direct_match(ia, match, compatible, &match_result))
+		return (match_result);
 
-	if (ia->ia_name != NULL)
-		return iic_compat_match(ia, compatible);
+	/* This device is direct-config only. */
 
-	return 1;
+	return (0);
 }
 
 static void
Index: dev/i2c/axp22x.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/axp22x.c,v
retrieving revision 1.3
diff -u -p -r1.3 axp22x.c
--- dev/i2c/axp22x.c	7 Oct 2017 20:31:48 -0000	1.3
+++ dev/i2c/axp22x.c	14 Jun 2018 13:30:03 -0000
@@ -69,11 +69,14 @@ static int
 axp22x_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name != NULL)
-		return iic_compat_match(ia, compatible);
+	if (iic_use_direct_match(ia, match, compatible, &match_result))
+		return (match_result);
 
-	return 1;
+	/* This device is direct-config only. */
+
+	return (0);
 }
 
 static void
Index: dev/i2c/axp809.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/axp809.c,v
retrieving revision 1.1
diff -u -p -r1.1 axp809.c
--- dev/i2c/axp809.c	7 Dec 2014 00:33:26 -0000	1.1
+++ dev/i2c/axp809.c	14 Jun 2018 13:30:04 -0000
@@ -105,7 +105,15 @@ CFATTACH_DECL_NEW(axp809pm, sizeof(struc
 static int
 axp809_match(device_t parent, cfdata_t match, void *aux)
 {
-	return 1;
+	struct i2c_attach_args *ia = aux;
+	int match_result;
+
+	if (iic_use_direct_match(ia, match, NULL, &match_result))
+		return (match_result);
+	
+	/* This device is direct-config only. */
+
+	return 0;
 }
 
 static void
Index: dev/i2c/axppmic.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/axppmic.c,v
retrieving revision 1.10
diff -u -p -r1.10 axppmic.c
--- dev/i2c/axppmic.c	26 May 2018 14:39:20 -0000	1.10
+++ dev/i2c/axppmic.c	14 Jun 2018 13:30:04 -0000
@@ -679,14 +679,25 @@ axppmic_match(device_t parent, cfdata_t 
 {
 	struct i2c_attach_args *ia = aux;
 
+	/* XXXJRT Gross. */
 	if (ia->ia_name != NULL) {
-		if (ia->ia_cookie)
-			return of_match_compat_data(ia->ia_cookie, compat_data);
-		else
+		if (ia->ia_cookie) {
+			int match_result =
+			    of_match_compat_data(ia->ia_cookie, compat_data);
+			if (match_result) {
+				match_result = match_result - 1 +
+				    I2C_MATCH_DIRECT_COMPATIBLE;
+				match_result = MIN(match_result,
+				    I2C_MATCH_DIRECT_COMPATIBLE_MAX);
+			}
+			return (match_result);
+		} else
 			return 0;
 	}
 
-	return 1;
+	/* This device is direct-config only. */
+
+	return 0;
 }
 
 static void
Index: dev/i2c/dbcool.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/dbcool.c,v
retrieving revision 1.48
diff -u -p -r1.48 dbcool.c
--- dev/i2c/dbcool.c	6 Feb 2018 10:02:09 -0000	1.48
+++ dev/i2c/dbcool.c	14 Jun 2018 13:30:04 -0000
@@ -748,20 +748,16 @@ dbcool_match(device_t parent, cfdata_t c
 	dc.dc_chip = NULL;
 	dc.dc_readreg = dbcool_readreg;
 	dc.dc_writereg = dbcool_writereg;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, dbcool_compats, &match_result))
+		return (match_result);
+
+	if ((ia->ia_addr & DBCOOL_ADDRMASK) != DBCOOL_ADDR)
+		return 0;
+	if (dbcool_chip_ident(&dc) >= 0)
+		return I2C_MATCH_ADDRESS_AND_PROBE;
 
-	/* Direct config - match compats */
-	if (ia->ia_name) {
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, dbcool_compats))
-				return 1;
-		}
-	/* Indirect config - check address and chip ID */
-	} else {
-		if ((ia->ia_addr & DBCOOL_ADDRMASK) != DBCOOL_ADDR)
-			return 0;
-		if (dbcool_chip_ident(&dc) >= 0)
-			return 1;
-	}
 	return 0;
 }
 
Index: dev/i2c/ddc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/ddc.c,v
retrieving revision 1.6
diff -u -p -r1.6 ddc.c
--- dev/i2c/ddc.c	25 Jul 2015 15:20:49 -0000	1.6
+++ dev/i2c/ddc.c	14 Jun 2018 13:30:04 -0000
@@ -70,7 +70,7 @@ ddc_match(device_t parent, cfdata_t cf, 
 	struct i2c_attach_args *ia = aux;
 
 	if (ia->ia_addr == DDC_ADDR)
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 	return 0;
 }
 
Index: dev/i2c/ds1307.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/ds1307.c,v
retrieving revision 1.25
diff -u -p -r1.25 ds1307.c
--- dev/i2c/ds1307.c	28 Oct 2017 04:53:55 -0000	1.25
+++ dev/i2c/ds1307.c	14 Jun 2018 13:30:04 -0000
@@ -205,16 +205,23 @@ static int
 dsrtc_match(device_t parent, cfdata_t cf, void *arg)
 {
 	struct i2c_attach_args *ia = arg;
+	int match_result;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "dsrtc") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == DS1307_ADDR || ia->ia_addr == MCP7940_ADDR)
-			return dsrtc_model(cf->cf_flags & 0xffff) != NULL;
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+
+	/*
+	 * XXXJRT
+	 * This could be a little better.  Specifically, we could check
+	 * for the address that's correct for the specific device specified
+	 * in the config directive.
+	 */
+	
+	if (ia->ia_addr == DS1307_ADDR || ia->ia_addr == MCP7940_ADDR) {
+		if (dsrtc_model(cf->cf_flags & 0xffff) != NULL)
+			return (I2C_MATCH_ADDRESS_ONLY);
 	}
+
 	return 0;
 }
 
@@ -223,6 +230,7 @@ dsrtc_attach(device_t parent, device_t s
 {
 	struct dsrtc_softc *sc = device_private(self);
 	struct i2c_attach_args *ia = arg;
+	/* XXXJRT Should also allow for a device property to specify model. */
 	const struct dsrtc_model * const dm =
 	    dsrtc_model(device_cfdata(self)->cf_flags);
 
Index: dev/i2c/dstemp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/dstemp.c,v
retrieving revision 1.1
diff -u -p -r1.1 dstemp.c
--- dev/i2c/dstemp.c	1 Feb 2018 21:44:17 -0000	1.1
+++ dev/i2c/dstemp.c	14 Jun 2018 13:30:04 -0000
@@ -81,15 +81,15 @@ static int
 dstemp_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL) {
-		/* no ID registers on this chip */
-		if ((ia->ia_addr & 0xf8) == 0x48)
-			return 1;
-		return 0;
-	} else {
-		return iic_compat_match(ia, dstemp_compats);
-	}
+	if (iic_use_direct_match(ia, match, dstemp_compats, &match_result))
+		return (match_result);
+	
+	if ((ia->ia_addr & 0xf8) == 0x48)
+		return I2C_MATCH_ADDRESS_ONLY;
+
+	return 0;
 }
 
 static void
Index: dev/i2c/em3027.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/em3027.c,v
retrieving revision 1.1
diff -u -p -r1.1 em3027.c
--- dev/i2c/em3027.c	5 Jan 2018 03:07:15 -0000	1.1
+++ dev/i2c/em3027.c	14 Jun 2018 13:30:04 -0000
@@ -128,7 +128,7 @@ em3027rtc_match(device_t parent, cfdata_
 	if (error)
 		return 0;
 
-	return 1;
+	return I2C_MATCH_ADDRESS_AND_PROBE;
 }
 
 
Index: dev/i2c/fcu.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/fcu.c,v
retrieving revision 1.3
diff -u -p -r1.3 fcu.c
--- dev/i2c/fcu.c	21 Mar 2018 15:41:34 -0000	1.3
+++ dev/i2c/fcu.c	14 Jun 2018 13:30:04 -0000
@@ -124,15 +124,15 @@ static int
 fcu_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL) {
-		/* no ID registers on this chip */
-		if (ia->ia_addr == 0x2f)
-			return 1;
-		return 0;
-	} else {
-		return iic_compat_match(ia, fcu_compats);
-	}
+	if (iic_use_direct_match(ia, match, fcu_compats, &match_result))
+		return (match_result);
+	
+	if (ia->ia_addr == 0x2f)
+		return I2C_MATCH_ADDRESS_ONLY;
+	
+	return 0;
 }
 
 static void
Index: dev/i2c/g760a.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/g760a.c,v
retrieving revision 1.4
diff -u -p -r1.4 g760a.c
--- dev/i2c/g760a.c	29 Jul 2012 07:04:09 -0000	1.4
+++ dev/i2c/g760a.c	14 Jun 2018 13:30:04 -0000
@@ -79,7 +79,7 @@ g760a_match(device_t parent, struct cfda
 		/*
 		 * TODO: set up minimal speed? 
 		 */
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 	}
 
 	return 0;
Index: dev/i2c/hytp14.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/hytp14.c,v
retrieving revision 1.7
diff -u -p -r1.7 hytp14.c
--- dev/i2c/hytp14.c	3 Jul 2016 12:26:55 -0000	1.7
+++ dev/i2c/hytp14.c	14 Jun 2018 13:30:04 -0000
@@ -98,19 +98,25 @@ static struct hytp14_sensor hytp14_senso
 static int
 hytp14_match(device_t parent, cfdata_t match, void *aux)
 {
-	struct i2c_attach_args *ia;
+	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	ia = aux;
+	if (iic_use_direct_match(ia, match, NULL, &match_result))
+		return (match_result);
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "hythygtemp") == 0)
-			return 1;
-	} else {
-		/* indirect config - check for configured address */
-		if ((ia->ia_addr > 0) && (ia->ia_addr <= 0x7F))
-			return 1;
-	}
+	if (ia->ia_addr == 0x28)
+		return I2C_MATCH_ADDRESS_ONLY;
+	
+	/*
+	 * XXXJRT
+	 * This device is an odd-ball; the i2c address can be changed
+	 * at run-time using a command sequence documented in the
+	 * application note, but the timing is critical (within 10ms
+	 * after power-on of the device), and the device always starts
+	 * up at address 0x28.
+	 *
+	 * How should we handle this?
+	 */
 	return 0;
 }
 
Index: dev/i2c/i2c.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/i2c.c,v
retrieving revision 1.61
diff -u -p -r1.61 i2c.c
--- dev/i2c/i2c.c	7 Jun 2018 13:30:49 -0000	1.61
+++ dev/i2c/i2c.c	14 Jun 2018 13:30:04 -0000
@@ -680,18 +680,58 @@ iic_fill_compat(struct i2c_attach_args *
 	ia->ia_ncompat = count;
 }
 
-int
-iic_compat_match(struct i2c_attach_args *ia, const char ** compats)
+/*
+ * iic_compat_match --
+ *	Match a device's "compatible" property against the list
+ *	of compatible strings provided by the driver.  Note that
+ *	we weight the match to the reverse index of the device's
+ *	"compatible" property strings so that a driver that matches
+ *	an lower-indexed "compatible" property is given a higher
+ *	match priority than one that matches a higher-indexed
+ *	"compatible" property.
+ */
+static int
+iic_compat_match(const struct i2c_attach_args *ia, const char ** compats)
 {
-	int i;
+	int match_result = 0, i, ri;
+
+	if (ia->ia_ncompat == 0 || ia->ia_compat == NULL)
+		return (0);
 
 	for (; compats && *compats; compats++) {
-		for (i = 0; i < ia->ia_ncompat; i++) {
-			if (strcmp(*compats, ia->ia_compat[i]) == 0)
-				return 1;
+		for (i = 0, ri = ia->ia_ncompat - 1;
+		     i < ia->ia_ncompat;
+		     i++, ri--) {
+			if (strcmp(*compats, ia->ia_compat[i]) == 0) {
+				KASSERT(ri >= 0);
+				match_result =
+				    I2C_MATCH_DIRECT_COMPATIBLE + ri;
+			}
 		}
 	}
-	return 0;
+	match_result = MIN(match_result, I2C_MATCH_DIRECT_COMPATIBLE_MAX);
+	return (match_result);
+}
+
+bool
+iic_use_direct_match(const struct i2c_attach_args *ia, const cfdata_t cf,
+		     const char **compats, int *match_resultp)
+{
+
+	KASSERT(match_resultp != NULL);
+
+	if (ia->ia_name != NULL &&
+	    strcmp(ia->ia_name, cf->cf_name) == 0) {
+		*match_resultp = I2C_MATCH_DIRECT_SPECIFIC;
+		return (true);
+	}
+
+	if (ia->ia_ncompat > 0 && ia->ia_compat != NULL) {
+		*match_resultp = iic_compat_match(ia, compats);
+		return (true);
+	}
+
+	return (false);
 }
 
 static int
Index: dev/i2c/i2cvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/i2cvar.h,v
retrieving revision 1.13
diff -u -p -r1.13 i2cvar.h
--- dev/i2c/i2cvar.h	7 Jun 2018 13:30:49 -0000	1.13
+++ dev/i2c/i2cvar.h	14 Jun 2018 13:30:04 -0000
@@ -38,6 +38,7 @@
 #ifndef _DEV_I2C_I2CVAR_H_
 #define	_DEV_I2C_I2CVAR_H_
 
+#include <sys/device.h>
 #include <dev/i2c/i2c_io.h>
 #include <prop/proplib.h>
 
@@ -159,7 +160,12 @@ struct i2c_attach_args {
  * API presented to i2c controllers.
  */
 int	iicbus_print(void *, const char *);
-int	iic_compat_match(struct i2c_attach_args*, const char **);
+
+/*
+ * API presented to i2c devices.
+ */
+bool	iic_use_direct_match(const struct i2c_attach_args *,
+			     const cfdata_t, const char **, int *);
 
 /*
  * Constants to indicate the quality of a match made by a driver's
@@ -176,7 +182,8 @@ int	iic_compat_match(struct i2c_attach_a
 #define	I2C_MATCH_ADDRESS_ONLY		1
 #define	I2C_MATCH_ADDRESS_AND_PROBE	2
 #define	I2C_MATCH_DIRECT_COMPATIBLE	10
-#define	I2C_MATCH_DIRECT_SPECIFIC	50
+#define	I2C_MATCH_DIRECT_COMPATIBLE_MAX	99
+#define	I2C_MATCH_DIRECT_SPECIFIC	100
 
 #ifdef _I2C_PRIVATE
 /*
Index: dev/i2c/ibmhawk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/ibmhawk.c,v
retrieving revision 1.6
diff -u -p -r1.6 ibmhawk.c
--- dev/i2c/ibmhawk.c	6 Jun 2018 01:49:08 -0000	1.6
+++ dev/i2c/ibmhawk.c	14 Jun 2018 13:30:04 -0000
@@ -109,7 +109,8 @@ ibmhawk_match(device_t parent, cfdata_t 
 	sc.sc_addr = ia->ia_addr;
 	if (ibmhawk_request(&sc, IHR_EQUIP, &resp))
 		return 0;
-	return 1;
+
+	return I2C_MATCH_ADDRESS_AND_PROBE;
 }
 
 static void
Index: dev/i2c/ihidev.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/ihidev.c,v
retrieving revision 1.2
diff -u -p -r1.2 ihidev.c
--- dev/i2c/ihidev.c	20 Mar 2018 12:14:52 -0000	1.2
+++ dev/i2c/ihidev.c	14 Jun 2018 13:30:04 -0000
@@ -129,11 +129,11 @@ static int
 ihidev_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args * const ia = aux;
+	int match_result;
+
+	if (iic_use_direct_match(ia, match, ihidev_compats, &match_result))
+		return I2C_MATCH_DIRECT_COMPATIBLE;
 
-	if (ia->ia_ncompat > 0) {
-		if (iic_compat_match(ia, ihidev_compats))
-			return 1;
-	}
 	return 0;
 }
 
Index: dev/i2c/lm75.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/lm75.c,v
retrieving revision 1.30
diff -u -p -r1.30 lm75.c
--- dev/i2c/lm75.c	1 Oct 2017 05:12:18 -0000	1.30
+++ dev/i2c/lm75.c	14 Jun 2018 13:30:04 -0000
@@ -146,35 +146,23 @@ static int
 lmtemp_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
-	int i;
-
-	if (ia->ia_name == NULL) {
-		/*
-		 * Indirect config - not much we can do!
-		 */
-		for (i = 0; lmtemptbl[i].lmtemp_type != -1 ; i++)
-			if (lmtemptbl[i].lmtemp_type == cf->cf_flags)
-				break;
-		if (lmtemptbl[i].lmtemp_type == -1)
-			return 0;
+	int i, match_result;
 
-		if ((ia->ia_addr & lmtemptbl[i].lmtemp_addrmask) ==
-		    lmtemptbl[i].lmtemp_addr)
-			return 1;
-	} else {
-		/*
-		 * Direct config - match via the list of compatible
-		 * hardware or simply match the device name.
-		 */
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, lmtemp_compats))
-				return 1;
-		} else {
-			if (strcmp(ia->ia_name, "lmtemp") == 0)
-				return 1;
-		}
-	}
+	if (iic_use_direct_match(ia, cf, lmtemp_compats, &match_result))
+		return (match_result);
 
+	/*
+	 * Indirect config - not much we can do!
+	 */
+	for (i = 0; lmtemptbl[i].lmtemp_type != -1 ; i++)
+		if (lmtemptbl[i].lmtemp_type == cf->cf_flags)
+			break;
+	if (lmtemptbl[i].lmtemp_type == -1)
+		return 0;
+
+	if ((ia->ia_addr & lmtemptbl[i].lmtemp_addrmask) ==
+	    lmtemptbl[i].lmtemp_addr)
+		return I2C_MATCH_ADDRESS_ONLY;
 
 	return 0;
 }
Index: dev/i2c/lm87.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/lm87.c,v
retrieving revision 1.7
diff -u -p -r1.7 lm87.c
--- dev/i2c/lm87.c	10 Jan 2016 14:03:11 -0000	1.7
+++ dev/i2c/lm87.c	14 Jun 2018 13:30:04 -0000
@@ -149,41 +149,30 @@ lmenv_match(device_t parent, cfdata_t ma
 {
 	struct i2c_attach_args *ia = aux;
 	u_int8_t cmd, val;
-	int error, i;
+	int error, i, match_result;
 
-	if (ia->ia_name == NULL) {
-		/*
-		 * Indirect config - not much we can do!
-		 * Check typical addresses and read the Company ID register
-		 */
-		if ((ia->ia_addr < 0x2c) || (ia->ia_addr > 0x2f))
-			return 0;
-
-		cmd = LM87_COMPANY_ID;
-		iic_acquire_bus(ia->ia_tag, 0);
-		error = iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
-		    &cmd, 1, &val, 1, I2C_F_POLL);
-		iic_release_bus(ia->ia_tag, 0);
-
-		if (error)
-			return 0;
-
-		for (i = 0; lmenv_ids[i].id != 0; i++)
-			if (lmenv_ids[i].id == val)
-				return 1;
-	} else {
-		/*
-		 * Direct config - match via the list of compatible
-		 * hardware or simply match the device name.
-		 */
-		if (ia->ia_ncompat > 0) {
-			if (iic_compat_match(ia, lmenv_compats))
-				return 1;
-		} else {
-			if (strcmp(ia->ia_name, "lmenv") == 0)
-				return 1;
-		}
-	}
+	if (iic_use_direct_match(ia, match, lmenv_compats, &match_result))
+		return (match_result);
+	
+	/*
+	 * Indirect config - not much we can do!
+	 * Check typical addresses and read the Company ID register
+	 */
+	if ((ia->ia_addr < 0x2c) || (ia->ia_addr > 0x2f))
+		return 0;
+
+	cmd = LM87_COMPANY_ID;
+	iic_acquire_bus(ia->ia_tag, 0);
+	error = iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
+	    &cmd, 1, &val, 1, I2C_F_POLL);
+	iic_release_bus(ia->ia_tag, 0);
+
+	if (error)
+		return 0;
+
+	for (i = 0; lmenv_ids[i].id != 0; i++)
+		if (lmenv_ids[i].id == val)
+			return I2C_MATCH_ADDRESS_AND_PROBE;
 
 	return 0;
 }
Index: dev/i2c/lm_i2c.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/lm_i2c.c,v
retrieving revision 1.4
diff -u -p -r1.4 lm_i2c.c
--- dev/i2c/lm_i2c.c	18 Aug 2017 04:07:51 -0000	1.4
+++ dev/i2c/lm_i2c.c	14 Jun 2018 13:30:04 -0000
@@ -71,6 +71,8 @@ lm_i2c_match(device_t parent, cfdata_t m
 	if (ia->ia_addr < 1)
 		return 0;
 
+	/* XXXJRT filter addresses //at all// please? */
+
 	/* Bus independent probe */
 	sc.sc_lmsc.lm_writereg = lm_i2c_writereg;
 	sc.sc_lmsc.lm_readreg = lm_i2c_readreg;
@@ -78,7 +80,7 @@ lm_i2c_match(device_t parent, cfdata_t m
 	sc.sc_addr = ia->ia_addr;
 	rv = lm_match(&sc.sc_lmsc);
 
-	return rv;
+	return rv ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
 }
 
 
Index: dev/i2c/m41st84.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/m41st84.c,v
retrieving revision 1.23
diff -u -p -r1.23 m41st84.c
--- dev/i2c/m41st84.c	28 Oct 2017 04:53:55 -0000	1.23
+++ dev/i2c/m41st84.c	14 Jun 2018 13:30:04 -0000
@@ -102,16 +102,15 @@ static int
 strtc_match(device_t parent, cfdata_t cf, void *arg)
 {
 	struct i2c_attach_args *ia = arg;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+
+	/* indirect config - check typical address */
+	if (ia->ia_addr == M41ST84_ADDR)
+		return I2C_MATCH_ADDRESS_ONLY;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "strtc") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == M41ST84_ADDR)
-			return 1;
-	}
 	return 0;
 }
 
Index: dev/i2c/m41t00.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/m41t00.c,v
retrieving revision 1.20
diff -u -p -r1.20 m41t00.c
--- dev/i2c/m41t00.c	28 Oct 2017 04:53:55 -0000	1.20
+++ dev/i2c/m41t00.c	14 Jun 2018 13:30:04 -0000
@@ -102,7 +102,7 @@ m41t00_match(device_t parent, cfdata_t c
 	struct i2c_attach_args *ia = aux;
 
 	if (ia->ia_addr == M41T00_ADDR) {
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 	}
 
 	return 0;
Index: dev/i2c/max6900.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/max6900.c,v
retrieving revision 1.15
diff -u -p -r1.15 max6900.c
--- dev/i2c/max6900.c	20 Nov 2014 16:34:26 -0000	1.15
+++ dev/i2c/max6900.c	14 Jun 2018 13:30:04 -0000
@@ -98,7 +98,7 @@ maxrtc_match(device_t parent, cfdata_t c
 	struct i2c_attach_args *ia = aux;
 
 	if ((ia->ia_addr & MAX6900_ADDRMASK) == MAX6900_ADDR)
-		return (1);
+		return (I2C_MATCH_ADDRESS_ONLY);
 
 	return (0);
 }
Index: dev/i2c/max77620.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/max77620.c,v
retrieving revision 1.2
diff -u -p -r1.2 max77620.c
--- dev/i2c/max77620.c	28 Sep 2017 13:08:00 -0000	1.2
+++ dev/i2c/max77620.c	14 Jun 2018 13:30:04 -0000
@@ -258,11 +258,12 @@ static int
 max77620_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL)
-		return 0;
+	if (iic_use_direct_match(ia, match, max77620_compats, match_result))
+		return (match_result);
 
-	return iic_compat_match(ia, max77620_compats);
+	return 0;
 }
 
 static void
Index: dev/i2c/mcp980x.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/mcp980x.c,v
retrieving revision 1.5
diff -u -p -r1.5 mcp980x.c
--- dev/i2c/mcp980x.c	28 Oct 2013 11:24:08 -0000	1.5
+++ dev/i2c/mcp980x.c	14 Jun 2018 13:30:04 -0000
@@ -106,12 +106,12 @@ CFATTACH_DECL_NEW(mcp980x, sizeof (struc
 static int
 mcp980x_match(device_t parent, cfdata_t cf, void *aux)
 {
-	/*
-	 * No sane way to probe? Perhaps at least try to match constant part
-	 * of the I2Caddress.
-	 */
 
-	return 1;
+	if (ia->ia_addr >= MCP980X_ADDR_CONST &&
+	    ia->ia_addr <= (MCP980X_ADDR_CONST + MCP980X_ADDR_VAR))
+		return I2C_MATCH_ADDRESS_ONLY;
+
+	return 0;
 }
 
 static void
Index: dev/i2c/mpl115a.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/mpl115a.c,v
retrieving revision 1.1
diff -u -p -r1.1 mpl115a.c
--- dev/i2c/mpl115a.c	8 Sep 2013 14:59:42 -0000	1.1
+++ dev/i2c/mpl115a.c	14 Jun 2018 13:30:04 -0000
@@ -97,7 +97,7 @@ mpl115a_match(device_t parent, cfdata_t 
 	struct i2c_attach_args *ia = aux;
 
 	if (ia->ia_addr == MPL115A_ADDR) 
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 	return 0;
 }
 
Index: dev/i2c/pcf8563.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/pcf8563.c,v
retrieving revision 1.8
diff -u -p -r1.8 pcf8563.c
--- dev/i2c/pcf8563.c	7 Oct 2017 20:18:16 -0000	1.8
+++ dev/i2c/pcf8563.c	14 Jun 2018 13:30:04 -0000
@@ -76,15 +76,15 @@ static int
 pcf8563rtc_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, compatible, &match_result))
+		return (match_result);
+
+	/* indirect config - check typical address */
+	if (ia->ia_addr == PCF8563_ADDR)
+		return I2C_MATCH_ADDRESS_ONLY;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		return iic_compat_match(ia, compatible);
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == PCF8563_ADDR)
-			return 1;
-	}
 	return 0;
 }
 
Index: dev/i2c/pcf8583.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/pcf8583.c,v
retrieving revision 1.17
diff -u -p -r1.17 pcf8583.c
--- dev/i2c/pcf8583.c	28 Oct 2017 04:53:55 -0000	1.17
+++ dev/i2c/pcf8583.c	14 Jun 2018 13:30:04 -0000
@@ -109,7 +109,7 @@ pcfrtc_match(device_t parent, cfdata_t c
 	struct i2c_attach_args *ia = aux;
 
 	if ((ia->ia_addr & PCF8583_ADDRMASK) == PCF8583_ADDR)
-		return (1);
+		return (I2C_MATCH_ADDRESS_ONLY);
 
 	return (0);
 }
Index: dev/i2c/r2025.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/r2025.c,v
retrieving revision 1.7
diff -u -p -r1.7 r2025.c
--- dev/i2c/r2025.c	20 Nov 2014 16:34:26 -0000	1.7
+++ dev/i2c/r2025.c	14 Jun 2018 13:30:04 -0000
@@ -76,7 +76,7 @@ r2025rtc_match(device_t parent, cfdata_t
 
 	/* match only R2025 RTC devices */
 	if (ia->ia_addr == R2025_ADDR)
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 
 	return 0;
 }
Index: dev/i2c/rs5c372.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/rs5c372.c,v
retrieving revision 1.14
diff -u -p -r1.14 rs5c372.c
--- dev/i2c/rs5c372.c	20 Nov 2014 16:34:26 -0000	1.14
+++ dev/i2c/rs5c372.c	14 Jun 2018 13:30:04 -0000
@@ -65,16 +65,15 @@ static int
 rs5c372rtc_match(device_t parent, cfdata_t cf, void *arg)
 {
 	struct i2c_attach_args *ia = arg;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+
+	/* indirect config - check typical address */
+	if (ia->ia_addr == RS5C372_ADDR)
+		return I2C_MATCH_ADDRESS_ONLY;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "rs5c372rtc") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == RS5C372_ADDR)
-			return 1;
-	}
 	return 0;
 }
 
Index: dev/i2c/s390.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/s390.c,v
retrieving revision 1.3
diff -u -p -r1.3 s390.c
--- dev/i2c/s390.c	20 Nov 2014 16:34:26 -0000	1.3
+++ dev/i2c/s390.c	14 Jun 2018 13:30:04 -0000
@@ -66,16 +66,15 @@ static int
 s390rtc_match(device_t parent, cfdata_t cf, void *arg)
 {
 	struct i2c_attach_args *ia = arg;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, NULL, &match_result))
+		return (match_result);
+	
+	/* indirect config - check typical address */
+	if (ia->ia_addr == S390_ADDR)
+		return I2C_MATCH_ADDRESS_ONLY;
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "s390rtc") == 0)
-			return 1;
-	} else {
-		/* indirect config - check typical address */
-		if (ia->ia_addr == S390_ADDR)
-			return 1;
-	}
 	return 0;
 }
 
Index: dev/i2c/sdtemp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/sdtemp.c,v
retrieving revision 1.33
diff -u -p -r1.33 sdtemp.c
--- dev/i2c/sdtemp.c	22 Feb 2018 10:09:12 -0000	1.33
+++ dev/i2c/sdtemp.c	14 Jun 2018 13:30:04 -0000
@@ -240,7 +240,7 @@ sdtemp_match(device_t parent, cfdata_t c
 	if ((cap & SDTEMP_CAP_HAS_ALARM) == 0)
 		return 0;
 
-	return 1;
+	return I2C_MATCH_ADDRESS_AND_PROBE;
 }
 
 static void
Index: dev/i2c/sgsmix.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/sgsmix.c,v
retrieving revision 1.8
diff -u -p -r1.8 sgsmix.c
--- dev/i2c/sgsmix.c	22 Sep 2017 04:07:34 -0000	1.8
+++ dev/i2c/sgsmix.c	14 Jun 2018 13:30:04 -0000
@@ -81,21 +81,21 @@ sgsmix_match(device_t parent, cfdata_t c
 	struct i2c_attach_args *args = aux;
 	int ret = -1;
 	uint8_t out[2] = {1, 0x20};
+	int match_result;
 
-	if (args->ia_name) {
-		if (strcmp(args->ia_name, "sgsmix") == 0)
-			return 1;
-	} else {
-		/* see if we can talk to something at address 0x8a */
-		if (args->ia_addr == 0x8a) {
-			iic_acquire_bus(args->ia_tag, 0);
-			ret = iic_exec(args->ia_tag, I2C_OP_WRITE, args->ia_addr,
-			    out, 2, NULL, 0, 0);
-			iic_release_bus(args->ia_tag, 0);
-		}
-		return (ret >= 0);
-	}
-	return 0;
+	if (iic_use_direct_match(args, cf, NULL, &match_result))
+		return (match_result);
+
+	/* see if we can talk to something at address 0x8a */
+	if (args->ia_addr != 0x8a)
+		return (0);
+
+	iic_acquire_bus(args->ia_tag, 0);
+	ret = iic_exec(args->ia_tag, I2C_OP_WRITE, args->ia_addr,
+	    out, 2, NULL, 0, 0);
+	iic_release_bus(args->ia_tag, 0);
+
+	return (ret >= 0) ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
 }
 
 static void
Index: dev/i2c/si70xx.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/si70xx.c,v
retrieving revision 1.3
diff -u -p -r1.3 si70xx.c
--- dev/i2c/si70xx.c	30 Dec 2017 03:18:26 -0000	1.3
+++ dev/i2c/si70xx.c	14 Jun 2018 13:30:04 -0000
@@ -563,21 +563,16 @@ si70xx_sysctl_init(struct si70xx_sc *sc)
 static int
 si70xx_match(device_t parent, cfdata_t match, void *aux)
 {
-	struct i2c_attach_args *ia;
-	int error;
+	struct i2c_attach_args *ia = aux;
+	int error, match_result;
 	const bool matchdebug = false;
 
-	ia = aux;
+	if (iic_use_direct_match(ia, match, NULL, &match_result))
+		return (match_result);
 
-	if (ia->ia_name) {
-		/* direct config - check name */
-		if (strcmp(ia->ia_name, "si70xxtemp") != 0)
-			return 0;
-	} else {
-		/* indirect config - check for configured address */
-		if (ia->ia_addr != SI70XX_TYPICAL_ADDR)
-			return 0;
-	}
+	/* indirect config - check for configured address */
+	if (ia->ia_addr != SI70XX_TYPICAL_ADDR)
+		return 0;
 
 	/*
 	 * Check to see if something is really at this i2c address. This will
@@ -592,7 +587,7 @@ si70xx_match(device_t parent, cfdata_t m
 	error = si70xx_poke(ia->ia_tag, ia->ia_addr, matchdebug);
 	iic_release_bus(ia->ia_tag, 0);
 
-	return error == 0;
+	return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
 }
 
 static void
Index: dev/i2c/smscmon.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/smscmon.c,v
retrieving revision 1.2
diff -u -p -r1.2 smscmon.c
--- dev/i2c/smscmon.c	20 Jun 2011 20:16:19 -0000	1.2
+++ dev/i2c/smscmon.c	14 Jun 2018 13:30:04 -0000
@@ -183,7 +183,7 @@ smscmon_match(device_t parent, cfdata_t 
 	}
 
 	iic_release_bus(ia->ia_tag, 0);
-	return 1;
+	return I2C_MATCH_ADDRESS_AND_PROBE;
 }
 
 static void
Index: dev/i2c/spdmem_i2c.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/spdmem_i2c.c,v
retrieving revision 1.14
diff -u -p -r1.14 spdmem_i2c.c
--- dev/i2c/spdmem_i2c.c	1 Mar 2018 05:47:22 -0000	1.14
+++ dev/i2c/spdmem_i2c.c	14 Jun 2018 13:30:04 -0000
@@ -178,6 +178,15 @@ spdmem_i2c_match(device_t parent, cfdata
 	struct i2c_attach_args *ia = aux;
 	struct spdmem_i2c_softc sc;
 
+	/*
+	 * XXXJRT
+	 * Should do this with "compatible" strings.  There are also
+	 * other problems with this "match" routine.  Specifically, if
+	 * we are doing direct-config, we know the device is already
+	 * there aren't do need to probe.  I'll leave the logic for
+	 * now and let someone who knows better clean it later.
+	 */
+
 	if (ia->ia_name) {
 		/* add other names as we find more firmware variations */
 		if (strcmp(ia->ia_name, "dimm-spd") &&
@@ -201,7 +210,11 @@ spdmem_i2c_match(device_t parent, cfdata
 	if (spdmem_reset_page(&sc) != 0)
 		return 0;
 
-	return spdmem_common_probe(&sc.sc_base);
+	if (spdmem_common_probe(&sc.sc_base)) {
+		return ia->ia_name ? I2C_MATCH_DIRECT_SPECIFIC
+				   : I2C_MATCH_ADDRESS_AND_PROBE;
+	}
+	return 0;
 }
 
 static void
Index: dev/i2c/sy8106a.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/sy8106a.c,v
retrieving revision 1.1
diff -u -p -r1.1 sy8106a.c
--- dev/i2c/sy8106a.c	2 Oct 2017 22:48:02 -0000	1.1
+++ dev/i2c/sy8106a.c	14 Jun 2018 13:30:04 -0000
@@ -185,11 +185,12 @@ static int
 sy8106a_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL)
-		return 0;
-
-	return iic_compat_match(ia, compatible);
+	if (iic_use_direct_match(ia, match, compatible, &match_result))
+		return (match_result);
+	
+	return 0;
 }
 
 static void
Index: dev/i2c/tcagpio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/tcagpio.c,v
retrieving revision 1.1
diff -u -p -r1.1 tcagpio.c
--- dev/i2c/tcagpio.c	22 Sep 2017 18:12:31 -0000	1.1
+++ dev/i2c/tcagpio.c	14 Jun 2018 13:30:04 -0000
@@ -246,11 +246,12 @@ static int
 tcagpio_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL)
-		return 0;
+	if (iic_use_direct_match(ia, match, compatible, &match_result))
+		return (match_result);
 
-	return iic_compat_match(ia, compatible);
+	return 0;
 }
 
 static void
Index: dev/i2c/tcakp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/tcakp.c,v
retrieving revision 1.6
diff -u -p -r1.6 tcakp.c
--- dev/i2c/tcakp.c	30 Apr 2018 20:33:09 -0000	1.6
+++ dev/i2c/tcakp.c	14 Jun 2018 13:30:04 -0000
@@ -316,13 +316,15 @@ static int
 tcakp_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
 
-	if (ia->ia_name == NULL) {
-		if (ia->ia_addr == 0x34)
-			return 1;
-		return 0;
-	} else
-		return iic_compat_match(ia, tcakp_compats);
+	if (iic_use_direct_match(ia, match, tcakp_compats, &match_result))
+		return (match_result);
+
+	if (ia->ia_addr == 0x34)
+		return I2C_MATCH_ADDRESS_ONLY;
+	
+	return 0;
 }
 
 static void
Index: dev/i2c/titemp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/titemp.c,v
retrieving revision 1.4
diff -u -p -r1.4 titemp.c
--- dev/i2c/titemp.c	30 Apr 2018 20:37:01 -0000	1.4
+++ dev/i2c/titemp.c	14 Jun 2018 13:30:04 -0000
@@ -94,25 +94,24 @@ titemp_match(device_t parent, cfdata_t m
 {
 	struct i2c_attach_args *ia = aux;
 	uint8_t mfid;
-	int error;
+	int error, match_result;
 
-	if (ia->ia_name == NULL) {
-		if (ia->ia_addr != 0x4c)
-			return 0;
-
-		if (iic_acquire_bus(ia->ia_tag, I2C_F_POLL) != 0)
-			return 0;
-		error = iic_smbus_read_byte(ia->ia_tag, ia->ia_addr,
-		    TITEMP_MFID_REG, &mfid, I2C_F_POLL);
-		iic_release_bus(ia->ia_tag, I2C_F_POLL);
+	if (iic_use_direct_match(ia, match, titemp_compats, &match_result))
+		return (match_result);
+	
+	if (ia->ia_addr != 0x4c)
+		return 0;
+
+	if (iic_acquire_bus(ia->ia_tag, I2C_F_POLL) != 0)
+		return 0;
+	error = iic_smbus_read_byte(ia->ia_tag, ia->ia_addr,
+	    TITEMP_MFID_REG, &mfid, I2C_F_POLL);
+	iic_release_bus(ia->ia_tag, I2C_F_POLL);
 
-		if (error || mfid != TITEMP_MFID_TMP451)
-			return 0;
+	if (error || mfid != TITEMP_MFID_TMP451)
+		return 0;
 
-		return 1;
-	} else {
-		return iic_compat_match(ia, titemp_compats);
-	}
+	return I2C_MATCH_ADDRESS_AND_PROBE;
 }
 
 static void
Index: dev/i2c/tps65217pmic.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/tps65217pmic.c,v
retrieving revision 1.11
diff -u -p -r1.11 tps65217pmic.c
--- dev/i2c/tps65217pmic.c	15 Oct 2016 14:40:41 -0000	1.11
+++ dev/i2c/tps65217pmic.c	14 Jun 2018 13:30:04 -0000
@@ -280,10 +280,8 @@ tps65217pmic_match(device_t parent, cfda
 		/* we can only have one */
 		if (matched)
 			return 0;
-		else
-			matched = true;
 
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 	}
 	return 0;
 }
@@ -296,6 +294,9 @@ tps65217pmic_attach(device_t parent, dev
 	prop_dictionary_t dict;
 	int isel, fdim, brightness;
 
+	/* XXXJRT But what if you have multiple i2c busses? */
+	matched = true;
+
 	sc->sc_dev = self;
 	sc->sc_addr = ia->ia_addr;
 	sc->sc_tag = ia->ia_tag;
Index: dev/i2c/tps65950.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/tps65950.c,v
retrieving revision 1.5
diff -u -p -r1.5 tps65950.c
--- dev/i2c/tps65950.c	20 Nov 2014 16:34:26 -0000	1.5
+++ dev/i2c/tps65950.c	14 Jun 2018 13:30:04 -0000
@@ -131,7 +131,7 @@ tps65950_match(device_t parent, cfdata_t
 	case TPS65950_ADDR_ID3:
 	case TPS65950_ADDR_ID4:
 	case TPS65950_ADDR_ID5:
-		return 1;
+		return I2C_MATCH_ADDRESS_ONLY;
 	default:
 		return 0;
 	}
Index: dev/i2c/tsl256x.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/tsl256x.c,v
retrieving revision 1.3
diff -u -p -r1.3 tsl256x.c
--- dev/i2c/tsl256x.c	7 Jun 2018 05:54:23 -0000	1.3
+++ dev/i2c/tsl256x.c	14 Jun 2018 13:30:04 -0000
@@ -110,38 +110,35 @@ tsllux_match(device_t parent, cfdata_t m
 {
 	struct i2c_attach_args *ia = aux;
 	uint8_t id_reg;
-	int error;
+	int error, match_result;
 
-	if (ia->ia_name == NULL) {
-		switch (ia->ia_addr) {
-		case TSL256x_SLAVEADDR_GND:
-		case TSL256x_SLAVEADDR_FLOAT:
-		case TSL256x_SLAVEADDR_VDD:
-			break;
+	if (iic_use_direct_match(ia, match, tsllux_compats, &match_result))
+		return (match_result);
 
-		default:
-			return (0);
-		}
+	switch (ia->ia_addr) {
+	case TSL256x_SLAVEADDR_GND:
+	case TSL256x_SLAVEADDR_FLOAT:
+	case TSL256x_SLAVEADDR_VDD:
+		break;
 
-		if (iic_acquire_bus(ia->ia_tag, I2C_F_POLL) != 0)
-			return (0);
-		error = iic_smbus_read_byte(ia->ia_tag, ia->ia_addr,
-		    TSL256x_REG_ID | COMMAND_CMD, &id_reg, I2C_F_POLL);
-		iic_release_bus(ia->ia_tag, I2C_F_POLL);
+	default:
+		return (0);
+	}
 
-		if (error)
-			return (0);
+	if (iic_acquire_bus(ia->ia_tag, I2C_F_POLL) != 0)
+		return (0);
+	error = iic_smbus_read_byte(ia->ia_tag, ia->ia_addr,
+	    TSL256x_REG_ID | COMMAND_CMD, &id_reg, I2C_F_POLL);
+	iic_release_bus(ia->ia_tag, I2C_F_POLL);
 
-		/*
-		 * XXX This loses if we have a 2560 rev. 0.
-		 */
-		if (id_reg == 0)
-			return (0);
+	if (error)
+		return (0);
 
-		return (1);
-	} else {
-		return iic_compat_match(ia, tsllux_compats);
-	}
+	/* XXX This loses if we have a 2560 rev. 0. */
+	if (id_reg == 0)
+		return (I2C_MATCH_ADDRESS_ONLY);
+
+	return (I2C_MATCH_ADDRESS_AND_PROBE);
 }
 
 static void
@@ -517,7 +514,7 @@ static int
 tsllux_write2(struct tsllux_softc *sc, uint8_t reg, uint16_t val)
 {
 	reg = (reg & REGMASK) | COMMAND_CMD | COMMAND_WORD;
-	return (iic_smbus_write_byte(sc->sc_i2c, sc->sc_addr, reg, val,
+	return (iic_smbus_write_word(sc->sc_i2c, sc->sc_addr, reg, val,
 				     sc->sc_i2c_flags));
 }
 #endif
Index: dev/i2c/w83795g.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/w83795g.c,v
retrieving revision 1.2
diff -u -p -r1.2 w83795g.c
--- dev/i2c/w83795g.c	13 Apr 2014 12:42:47 -0000	1.2
+++ dev/i2c/w83795g.c	14 Jun 2018 13:30:04 -0000
@@ -155,7 +155,7 @@ w83795g_match(device_t parent, cfdata_t 
 	if ((bank & BANKSEL_HBACS && vend == VENDOR_NUVOTON_ID_HI) ||
 	   (~bank & BANKSEL_HBACS && vend == VENDOR_NUVOTON_ID_LO))
 		if (chip == CHIP_W83795G && deva == DEVICEA_A)
-			return 1;
+			return I2C_MATCH_ADDRESS_AND_PROBE;
 
 	return 0;
 }
Index: dev/i2c/x1226.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/x1226.c,v
retrieving revision 1.20
diff -u -p -r1.20 x1226.c
--- dev/i2c/x1226.c	28 Oct 2017 04:53:55 -0000	1.20
+++ dev/i2c/x1226.c	14 Jun 2018 13:30:04 -0000
@@ -103,7 +103,7 @@ xrtc_match(device_t parent, cfdata_t cf,
 
 	/* match only this RTC devices */
 	if (ia->ia_addr == X1226_ADDR)
-		return (1);
+		return (I2C_MATCH_ADDRESS_ONLY);
 
 	return (0);
 }

Thx.

-- thorpej



Home | Main Index | Thread Index | Old Index