diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2022-02-09 07:58:25 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2022-02-09 07:58:25 +0000 |
commit | badf3c55e7a1fd8f77fbfbe203f5ea736817b677 (patch) | |
tree | e3b600ddd4503f232ae79414998e2dc4da89fc8d /sys | |
parent | e5a9220c6217b9923c1448c7956d0a6016b5e48c (diff) |
Add iic_is_compatible() for matching I2C devices
When using device trees, the ia_name field of struct i2c_attach_args
points to the first string of the device node's "compatible" array.
However, in many cases it would be preferable to use the last, most
general "compatible" entry as a device matching criterion.
Enable more flexible device matching by permitting ia_name to point to
the raw "compatible" data which is a concatenation of NUL-terminated
strings. I2C bus code will supply the data and set ia_name and
ia_namelen. I2C device drivers will use iic_is_compatible() to check
matches. This method is also backwards compatible with the old, direct
use of ia_name.
Prompted by a related patch from kettenis@.
OK kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/i2c/i2c.c | 25 | ||||
-rw-r--r-- | sys/dev/i2c/i2cvar.h | 4 |
2 files changed, 27 insertions, 2 deletions
diff --git a/sys/dev/i2c/i2c.c b/sys/dev/i2c/i2c.c index 4b44892cf3c..48e0ec96a76 100644 --- a/sys/dev/i2c/i2c.c +++ b/sys/dev/i2c/i2c.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i2c.c,v 1.17 2021/10/26 16:29:49 deraadt Exp $ */ +/* $OpenBSD: i2c.c,v 1.18 2022/02/09 07:58:24 visa Exp $ */ /* $NetBSD: i2c.c,v 1.1 2003/09/30 00:35:31 thorpej Exp $ */ /* @@ -143,3 +143,26 @@ iic_attach(struct device *parent, struct device *self, void *aux) else iic_scan(self, aux); } + +int +iic_is_compatible(const struct i2c_attach_args *ia, const char *name) +{ + const char *end, *entry; + + if (ia->ia_namelen > 0) { + /* ia_name points to a concatenation of strings. */ + entry = ia->ia_name; + end = entry + ia->ia_namelen; + while (entry < end) { + if (strcmp(entry, name) == 0) + return (1); + entry += strlen(entry) + 1; + } + } else { + /* ia_name points to a string. */ + if (strcmp(ia->ia_name, name) == 0) + return (1); + } + + return (0); +} diff --git a/sys/dev/i2c/i2cvar.h b/sys/dev/i2c/i2cvar.h index aaba3294055..72469227e8b 100644 --- a/sys/dev/i2c/i2cvar.h +++ b/sys/dev/i2c/i2cvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i2cvar.h,v 1.17 2019/07/22 14:37:06 jcs Exp $ */ +/* $OpenBSD: i2cvar.h,v 1.18 2022/02/09 07:58:24 visa Exp $ */ /* $NetBSD: i2cvar.h,v 1.1 2003/09/30 00:35:31 thorpej Exp $ */ /* @@ -111,6 +111,7 @@ struct i2c_attach_args { i2c_addr_t ia_addr; /* address of device */ int ia_size; /* size (for EEPROMs) */ char *ia_name; /* chip name */ + size_t ia_namelen; /* length of name concatenation */ void *ia_cookie; /* pass extra info from bus to dev */ void *ia_intr; /* interrupt info */ int ia_poll; /* to force polling */ @@ -164,5 +165,6 @@ int iic_smbus_receive_byte(i2c_tag_t, i2c_addr_t, uint8_t *, int); (*(ic)->ic_intr_string)((ic)->ic_cookie, (ih)) void iic_ignore_addr(u_int8_t addr); +int iic_is_compatible(const struct i2c_attach_args *, const char *); #endif /* _DEV_I2C_I2CVAR_H_ */ |