Thu Jun 7 13:30:49 2018 UTC ()
Changes / enhancements to i2c indirect device auto-configuration:

— iic_search() chooses a “probe strategy” based on the
  "i2c-indirect-probe-strategy” property on the “iic” instance.
  Valid values are "smbus-quick-write”, "smbus-receive-byte”, and
  “none”.  If no value is specified, the default is "smbus-quick-write”.

— If the "i2c-indirect-device-whitelist” exists on the “iic” instance,
  iic_search() will first check the driver name in the cfdata_t against
  this list, and only allow the match/probe to move forward if the
  cfdata_t driver name is in the list.  This is primarily to accommodate
  the Intel integrated memory controller neutered-i2c-thing.

— If the cfdata_t specifies a wildcard address, each address of the i2c
  bus will be consulted.  If the cfdata_t contains a nailed-down address,
  then we limit the bus scan to that specific address.

— We explicitly skip reserved / special i2c addresses, such as the
  General-Call address, etc.

— We introduce the notion of a “match quality” for i2c drivers.  From
  lowest-quality to highest-quality: matched by plausible address only,
  matched by plausible address and poking at the bus to see if the
  device looks reasonable, matched by direct-config “compatible” string,
  matched by direct-config “driver name” string.

— If the “match quality” is merely “plausible address only”, then
  iic_search() will use the probe strategy selected above to see if
  a device responds to that address.


(thorpej)
diff -r1.60 -r1.61 src/sys/dev/i2c/i2c.c
diff -r1.12 -r1.13 src/sys/dev/i2c/i2cvar.h

cvs diff -r1.60 -r1.61 src/sys/dev/i2c/i2c.c (expand / switch to unified diff)

--- src/sys/dev/i2c/i2c.c 2018/06/07 05:56:18 1.60
+++ src/sys/dev/i2c/i2c.c 2018/06/07 13:30:49 1.61
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: i2c.c,v 1.60 2018/06/07 05:56:18 thorpej Exp $ */ 1/* $NetBSD: i2c.c,v 1.61 2018/06/07 13:30:49 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Wasabi Systems, Inc. 4 * Copyright (c) 2003 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -30,53 +30,54 @@ @@ -30,53 +30,54 @@
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE. 35 * POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38#ifdef _KERNEL_OPT 38#ifdef _KERNEL_OPT
39#include "opt_i2c.h" 39#include "opt_i2c.h"
40#endif 40#endif
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.60 2018/06/07 05:56:18 thorpej Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.61 2018/06/07 13:30:49 thorpej Exp $");
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/event.h> 48#include <sys/event.h>
49#include <sys/conf.h> 49#include <sys/conf.h>
50#include <sys/malloc.h> 50#include <sys/malloc.h>
51#include <sys/kmem.h> 51#include <sys/kmem.h>
52#include <sys/kthread.h> 52#include <sys/kthread.h>
53#include <sys/proc.h> 53#include <sys/proc.h>
54#include <sys/kernel.h> 54#include <sys/kernel.h>
55#include <sys/fcntl.h> 55#include <sys/fcntl.h>
56#include <sys/module.h> 56#include <sys/module.h>
57#include <sys/once.h> 57#include <sys/once.h>
58#include <sys/mutex.h> 58#include <sys/mutex.h>
59 59
60#include <dev/i2c/i2cvar.h> 60#include <dev/i2c/i2cvar.h>
61 61
62#include "ioconf.h" 62#include "ioconf.h"
63#include "locators.h" 63#include "locators.h"
64 64
65#ifndef I2C_MAX_ADDR 65#ifndef I2C_MAX_ADDR
66#define I2C_MAX_ADDR 0x3ff /* 10-bit address, max */ 66#define I2C_MAX_ADDR 0x3ff /* 10-bit address, max */
67#endif 67#endif
68 68
69struct iic_softc { 69struct iic_softc {
 70 device_t sc_dev;
70 i2c_tag_t sc_tag; 71 i2c_tag_t sc_tag;
71 int sc_type; 72 int sc_type;
72 device_t sc_devices[I2C_MAX_ADDR + 1]; 73 device_t sc_devices[I2C_MAX_ADDR + 1];
73}; 74};
74 75
75static dev_type_open(iic_open); 76static dev_type_open(iic_open);
76static dev_type_close(iic_close); 77static dev_type_close(iic_close);
77static dev_type_ioctl(iic_ioctl); 78static dev_type_ioctl(iic_ioctl);
78 79
79int iic_init(void); 80int iic_init(void);
80 81
81kmutex_t iic_mtx; 82kmutex_t iic_mtx;
82int iic_refcnt; 83int iic_refcnt;
@@ -117,61 +118,258 @@ iic_print_direct(void *aux, const char * @@ -117,61 +118,258 @@ iic_print_direct(void *aux, const char *
117} 118}
118 119
119static int 120static int
120iic_print(void *aux, const char *pnp) 121iic_print(void *aux, const char *pnp)
121{ 122{
122 struct i2c_attach_args *ia = aux; 123 struct i2c_attach_args *ia = aux;
123 124
124 if (ia->ia_addr != (i2c_addr_t)IICCF_ADDR_DEFAULT) 125 if (ia->ia_addr != (i2c_addr_t)IICCF_ADDR_DEFAULT)
125 aprint_normal(" addr 0x%x", ia->ia_addr); 126 aprint_normal(" addr 0x%x", ia->ia_addr);
126 127
127 return UNCONF; 128 return UNCONF;
128} 129}
129 130
 131static bool
 132iic_is_special_address(i2c_addr_t addr)
 133{
 134
 135 /*
 136 * See: https://www.i2c-bus.org/addressing/
 137 */
 138
 139 /* General Call (read) / Start Byte (write) */
 140 if (addr == 0x00)
 141 return (true);
 142
 143 /* CBUS Addresses */
 144 if (addr == 0x01)
 145 return (true);
 146
 147 /* Reserved for Different Bus Formats */
 148 if (addr == 0x02)
 149 return (true);
 150
 151 /* Reserved for future purposes */
 152 if (addr == 0x03)
 153 return (true);
 154
 155 /* High Speed Master Code */
 156 if ((addr & 0x7c) == 0x04)
 157 return (true);
 158
 159 /* 10-bit Slave Addressing prefix */
 160 if ((addr & 0x7c) == 0x78)
 161 return (true);
 162
 163 /* Reserved for future purposes */
 164 if ((addr & 0x7c) == 0x7c)
 165 return (true);
 166
 167 return (false);
 168}
 169
 170static int
 171iic_probe_none(struct iic_softc *sc,
 172 const struct i2c_attach_args *ia, int flags)
 173{
 174
 175 return (0);
 176}
 177
 178static int
 179iic_probe_smbus_quick_write(struct iic_softc *sc,
 180 const struct i2c_attach_args *ia, int flags)
 181{
 182 int error;
 183
 184 if ((error = iic_acquire_bus(ia->ia_tag, flags)) == 0) {
 185 error = iic_smbus_quick_write(ia->ia_tag, ia->ia_addr, flags);
 186 }
 187 (void) iic_release_bus(ia->ia_tag, flags);
 188
 189 return (error);
 190}
 191
 192static int
 193iic_probe_smbus_receive_byte(struct iic_softc *sc,
 194 const struct i2c_attach_args *ia, int flags)
 195{
 196 int error;
 197
 198 if ((error = iic_acquire_bus(ia->ia_tag, flags)) == 0) {
 199 uint8_t dummy;
 200
 201 error = iic_smbus_receive_byte(ia->ia_tag, ia->ia_addr,
 202 &dummy, flags);
 203 }
 204 (void) iic_release_bus(ia->ia_tag, flags);
 205
 206 return (error);
 207}
 208
 209static bool
 210iic_indirect_driver_is_whitelisted(struct iic_softc *sc, cfdata_t cf)
 211{
 212 prop_object_iterator_t iter;
 213 prop_array_t whitelist;
 214 prop_string_t pstr;
 215 prop_type_t ptype;
 216 bool rv = false;
 217
 218 whitelist = prop_dictionary_get(device_properties(sc->sc_dev),
 219 I2C_PROP_INDIRECT_DEVICE_WHITELIST);
 220 if (whitelist == NULL) {
 221 /* No whitelist -> everything allowed */
 222 return (true);
 223 }
 224
 225 if ((ptype = prop_object_type(whitelist)) != PROP_TYPE_ARRAY) {
 226 aprint_error_dev(sc->sc_dev,
 227 "invalid property type (%d) for '%s'; must be array (%d)\n",
 228 ptype, I2C_PROP_INDIRECT_DEVICE_WHITELIST, PROP_TYPE_ARRAY);
 229 return (false);
 230 }
 231
 232 iter = prop_array_iterator(whitelist);
 233 while ((pstr = prop_object_iterator_next(iter)) != NULL) {
 234 if (prop_string_equals_cstring(pstr, cf->cf_name)) {
 235 rv = true;
 236 break;
 237 }
 238 }
 239 prop_object_iterator_release(iter);
 240
 241 return (rv);
 242}
 243
130static int 244static int
131iic_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 245iic_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
132{ 246{
133 struct iic_softc *sc = device_private(parent); 247 struct iic_softc *sc = device_private(parent);
134 struct i2c_attach_args ia; 248 struct i2c_attach_args ia;
 249 int (*probe_func)(struct iic_softc *,
 250 const struct i2c_attach_args *, int);
 251 prop_string_t pstr;
 252 i2c_addr_t first_addr, last_addr;
135 253
136 /* 254 /*
137 * I2C doesn't have any regular probing capability. If we 255 * Before we do any more work, consult the allowed-driver
138 * encounter a cfdata with a wild-carded address or a wild- 256 * white-list for this bus (if any).
139 * carded parent spec, we skip them because they can only 
140 * be used for direct-coniguration. 
141 */ 257 */
142 if (cf->cf_loc[IICCF_ADDR] == IICCF_ADDR_DEFAULT || 258 if (iic_indirect_driver_is_whitelisted(sc, cf) == false)
143 cf->cf_pspec->cfp_unit == DVUNIT_ANY) 259 return (0);
144 return 0; 260
 261 /* default to "quick write". */
 262 probe_func = iic_probe_smbus_quick_write;
 263
 264 pstr = prop_dictionary_get(device_properties(sc->sc_dev),
 265 I2C_PROP_INDIRECT_PROBE_STRATEGY);
 266 if (pstr == NULL) {
 267 /* Use the default. */
 268 } else if (prop_string_equals_cstring(pstr,
 269 I2C_PROBE_STRATEGY_QUICK_WRITE)) {
 270 probe_func = iic_probe_smbus_quick_write;
 271 } else if (prop_string_equals_cstring(pstr,
 272 I2C_PROBE_STRATEGY_RECEIVE_BYTE)) {
 273 probe_func = iic_probe_smbus_receive_byte;
 274 } else if (prop_string_equals_cstring(pstr,
 275 I2C_PROBE_STRATEGY_NONE)) {
 276 probe_func = iic_probe_none;
 277 } else {
 278 aprint_error_dev(sc->sc_dev,
 279 "unknown probe strategy '%s'; defaulting to '%s'\n",
 280 prop_string_cstring_nocopy(pstr),
 281 I2C_PROBE_STRATEGY_QUICK_WRITE);
 282
 283 /* Use the default. */
 284 }
145 285
146 ia.ia_tag = sc->sc_tag; 286 ia.ia_tag = sc->sc_tag;
147 ia.ia_size = cf->cf_loc[IICCF_SIZE]; 287 ia.ia_size = cf->cf_loc[IICCF_SIZE];
148 ia.ia_type = sc->sc_type; 288 ia.ia_type = sc->sc_type;
149 289
150 ia.ia_name = NULL; 290 ia.ia_name = NULL;
151 ia.ia_ncompat = 0; 291 ia.ia_ncompat = 0;
152 ia.ia_compat = NULL; 292 ia.ia_compat = NULL;
153 ia.ia_prop = NULL; 293 ia.ia_prop = NULL;
154 294
155 for (ia.ia_addr = 0; ia.ia_addr <= I2C_MAX_ADDR; ia.ia_addr++) { 295 if (cf->cf_loc[IICCF_ADDR] == IICCF_ADDR_DEFAULT) {
 296 /*
 297 * This particular config directive has
 298 * wildcarded the address, so we will
 299 * scan the entire bus for it.
 300 */
 301 first_addr = 0;
 302 last_addr = I2C_MAX_ADDR;
 303 } else {
 304 /*
 305 * This config directive hard-wires the i2c
 306 * bus address for the device, so there is
 307 * no need to go poking around at any other
 308 * addresses.
 309 */
 310 if (cf->cf_loc[IICCF_ADDR] < 0 ||
 311 cf->cf_loc[IICCF_ADDR] > I2C_MAX_ADDR) {
 312 /* Invalid config directive! */
 313 return (0);
 314 }
 315 first_addr = last_addr = cf->cf_loc[IICCF_ADDR];
 316 }
 317
 318 for (ia.ia_addr = first_addr; ia.ia_addr <= last_addr; ia.ia_addr++) {
 319 int error, match_result;
 320
 321 /*
 322 * Skip I2C addresses that are reserved for
 323 * special purposes.
 324 */
 325 if (iic_is_special_address(ia.ia_addr))
 326 continue;
 327
 328 /*
 329 * Skip addresses where a device is already attached.
 330 */
156 if (sc->sc_devices[ia.ia_addr] != NULL) 331 if (sc->sc_devices[ia.ia_addr] != NULL)
157 continue; 332 continue;
158 333
159 if (cf->cf_loc[IICCF_ADDR] != ia.ia_addr) 334 /*
 335 * Call the "match" routine for the device. If that
 336 * returns success, then call the probe strategy
 337 * function.
 338 *
 339 * We do it in this order because i2c devices tend
 340 * to be found at a small number of possible addresses
 341 * (e.g. read-time clocks that are only ever found at
 342 * 0x68). This gives the driver a chance to skip any
 343 * address that are not valid for the device, saving
 344 * us from having to poke at the bus to see if anything
 345 * is there.
 346 */
 347 match_result = config_match(parent, cf, &ia);
 348 if (match_result <= 0)
 349 continue;
 350
 351 /*
 352 * If the quality of the match by the driver was low
 353 * (i.e. matched on being a valid address only, didn't
 354 * perform any hardware probe), invoke our probe routine
 355 * to see if it looks like something is really there.
 356 */
 357 if (match_result == I2C_MATCH_ADDRESS_ONLY &&
 358 (error = (*probe_func)(sc, &ia, I2C_F_POLL)) != 0)
160 continue; 359 continue;
161 360
162 if (config_match(parent, cf, &ia) > 0) 361 sc->sc_devices[ia.ia_addr] =
163 sc->sc_devices[ia.ia_addr] = 362 config_attach(parent, cf, &ia, iic_print);
164 config_attach(parent, cf, &ia, iic_print); 
165 } 363 }
166 364
167 return 0; 365 return 0;
168} 366}
169 367
170static void 368static void
171iic_child_detach(device_t parent, device_t child) 369iic_child_detach(device_t parent, device_t child)
172{ 370{
173 struct iic_softc *sc = device_private(parent); 371 struct iic_softc *sc = device_private(parent);
174 int i; 372 int i;
175 373
176 for (i = 0; i <= I2C_MAX_ADDR; i++) 374 for (i = 0; i <= I2C_MAX_ADDR; i++)
177 if (sc->sc_devices[i] == child) { 375 if (sc->sc_devices[i] == child) {
@@ -199,26 +397,27 @@ iic_attach(device_t parent, device_t sel @@ -199,26 +397,27 @@ iic_attach(device_t parent, device_t sel
199{ 397{
200 struct iic_softc *sc = device_private(self); 398 struct iic_softc *sc = device_private(self);
201 struct i2cbus_attach_args *iba = aux; 399 struct i2cbus_attach_args *iba = aux;
202 prop_array_t child_devices; 400 prop_array_t child_devices;
203 prop_dictionary_t props; 401 prop_dictionary_t props;
204 char *buf; 402 char *buf;
205 i2c_tag_t ic; 403 i2c_tag_t ic;
206 int rv; 404 int rv;
207 bool indirect_config; 405 bool indirect_config;
208 406
209 aprint_naive("\n"); 407 aprint_naive("\n");
210 aprint_normal(": I2C bus\n"); 408 aprint_normal(": I2C bus\n");
211 409
 410 sc->sc_dev = self;
212 sc->sc_tag = iba->iba_tag; 411 sc->sc_tag = iba->iba_tag;
213 sc->sc_type = iba->iba_type; 412 sc->sc_type = iba->iba_type;
214 ic = sc->sc_tag; 413 ic = sc->sc_tag;
215 ic->ic_devname = device_xname(self); 414 ic->ic_devname = device_xname(self);
216 415
217 LIST_INIT(&(sc->sc_tag->ic_list)); 416 LIST_INIT(&(sc->sc_tag->ic_list));
218 LIST_INIT(&(sc->sc_tag->ic_proc_list)); 417 LIST_INIT(&(sc->sc_tag->ic_proc_list));
219 418
220 rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL, 419 rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL,
221 iic_smbus_intr_thread, ic, &ic->ic_intr_thread, 420 iic_smbus_intr_thread, ic, &ic->ic_intr_thread,
222 "%s", ic->ic_devname); 421 "%s", ic->ic_devname);
223 if (rv) 422 if (rv)
224 aprint_error_dev(self, "unable to create intr thread\n"); 423 aprint_error_dev(self, "unable to create intr thread\n");

cvs diff -r1.12 -r1.13 src/sys/dev/i2c/i2cvar.h (expand / switch to unified diff)

--- src/sys/dev/i2c/i2cvar.h 2018/06/07 05:56:18 1.12
+++ src/sys/dev/i2c/i2cvar.h 2018/06/07 13:30:49 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: i2cvar.h,v 1.12 2018/06/07 05:56:18 thorpej Exp $ */ 1/* $NetBSD: i2cvar.h,v 1.13 2018/06/07 13:30:49 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Wasabi Systems, Inc. 4 * Copyright (c) 2003 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Steve C. Woodford and Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Steve C. Woodford and Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -39,26 +39,40 @@ @@ -39,26 +39,40 @@
39#define _DEV_I2C_I2CVAR_H_ 39#define _DEV_I2C_I2CVAR_H_
40 40
41#include <dev/i2c/i2c_io.h> 41#include <dev/i2c/i2c_io.h>
42#include <prop/proplib.h> 42#include <prop/proplib.h>
43 43
44/* Flags passed to i2c routines. */ 44/* Flags passed to i2c routines. */
45#define I2C_F_WRITE 0x00 /* new transfer is a write */ 45#define I2C_F_WRITE 0x00 /* new transfer is a write */
46#define I2C_F_READ 0x01 /* new transfer is a read */ 46#define I2C_F_READ 0x01 /* new transfer is a read */
47#define I2C_F_LAST 0x02 /* last byte of read */ 47#define I2C_F_LAST 0x02 /* last byte of read */
48#define I2C_F_STOP 0x04 /* send stop after byte */ 48#define I2C_F_STOP 0x04 /* send stop after byte */
49#define I2C_F_POLL 0x08 /* poll, don't sleep */ 49#define I2C_F_POLL 0x08 /* poll, don't sleep */
50#define I2C_F_PEC 0x10 /* smbus packet error checking */ 50#define I2C_F_PEC 0x10 /* smbus packet error checking */
51 51
 52/* i2c bus instance properties */
 53#define I2C_PROP_INDIRECT_PROBE_STRATEGY \
 54 "i2c-indirect-probe-strategy"
 55#define I2C_PROBE_STRATEGY_QUICK_WRITE \
 56 "smbus-quick-write"
 57#define I2C_PROBE_STRATEGY_RECEIVE_BYTE \
 58 "smbus-receive-byte"
 59#define I2C_PROBE_STRATEGY_NONE \
 60 "none"
 61
 62#define I2C_PROP_INDIRECT_DEVICE_WHITELIST \
 63 "i2c-indirect-device-whitelist"
 64 /* value is a prop_array of prop_strings */
 65
52struct ic_intr_list { 66struct ic_intr_list {
53 LIST_ENTRY(ic_intr_list) il_next; 67 LIST_ENTRY(ic_intr_list) il_next;
54 int (*il_intr)(void *); 68 int (*il_intr)(void *);
55 void *il_intrarg; 69 void *il_intrarg;
56}; 70};
57 71
58/* 72/*
59 * This structure provides the interface between the i2c framework 73 * This structure provides the interface between the i2c framework
60 * and the underlying i2c controller. 74 * and the underlying i2c controller.
61 * 75 *
62 * Note that this structure is designed specifically to allow us 76 * Note that this structure is designed specifically to allow us
63 * to either use the autoconfiguration framework or not. This 77 * to either use the autoconfiguration framework or not. This
64 * allows a driver for a board with a private i2c bus use generic 78 * allows a driver for a board with a private i2c bus use generic
@@ -137,26 +151,43 @@ struct i2c_attach_args { @@ -137,26 +151,43 @@ struct i2c_attach_args {
137 * down to MD drivers through the MI i2c bus otherwise. 151 * down to MD drivers through the MI i2c bus otherwise.
138 *  152 *
139 * On ACPI platforms this is the ACPI_HANDLE of the device. 153 * On ACPI platforms this is the ACPI_HANDLE of the device.
140 */ 154 */
141 uintptr_t ia_cookie; /* OF node in openfirmware machines */ 155 uintptr_t ia_cookie; /* OF node in openfirmware machines */
142}; 156};
143 157
144/* 158/*
145 * API presented to i2c controllers. 159 * API presented to i2c controllers.
146 */ 160 */
147int iicbus_print(void *, const char *); 161int iicbus_print(void *, const char *);
148int iic_compat_match(struct i2c_attach_args*, const char **); 162int iic_compat_match(struct i2c_attach_args*, const char **);
149 163
 164/*
 165 * Constants to indicate the quality of a match made by a driver's
 166 * match routine, from lowest to higest:
 167 *
 168 * -- Address only; no other checks were made.
 169 *
 170 * -- Address + device probed and recognized.
 171 *
 172 * -- Direct-config match by "compatible" string.
 173 *
 174 * -- Direct-config match by specific driver name.
 175 */
 176#define I2C_MATCH_ADDRESS_ONLY 1
 177#define I2C_MATCH_ADDRESS_AND_PROBE 2
 178#define I2C_MATCH_DIRECT_COMPATIBLE 10
 179#define I2C_MATCH_DIRECT_SPECIFIC 50
 180
150#ifdef _I2C_PRIVATE 181#ifdef _I2C_PRIVATE
151/* 182/*
152 * Macros used internally by the i2c framework. 183 * Macros used internally by the i2c framework.
153 */ 184 */
154#define iic_send_start(ic, flags) \ 185#define iic_send_start(ic, flags) \
155 (*(ic)->ic_send_start)((ic)->ic_cookie, (flags)) 186 (*(ic)->ic_send_start)((ic)->ic_cookie, (flags))
156#define iic_send_stop(ic, flags) \ 187#define iic_send_stop(ic, flags) \
157 (*(ic)->ic_send_stop)((ic)->ic_cookie, (flags)) 188 (*(ic)->ic_send_stop)((ic)->ic_cookie, (flags))
158#define iic_initiate_xfer(ic, addr, flags) \ 189#define iic_initiate_xfer(ic, addr, flags) \
159 (*(ic)->ic_initiate_xfer)((ic)->ic_cookie, (addr), (flags)) 190 (*(ic)->ic_initiate_xfer)((ic)->ic_cookie, (addr), (flags))
160 191
161#define iic_read_byte(ic, bytep, flags) \ 192#define iic_read_byte(ic, bytep, flags) \
162 (*(ic)->ic_read_byte)((ic)->ic_cookie, (bytep), (flags)) 193 (*(ic)->ic_read_byte)((ic)->ic_cookie, (bytep), (flags))