summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2022-02-09 07:58:25 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2022-02-09 07:58:25 +0000
commitbadf3c55e7a1fd8f77fbfbe203f5ea736817b677 (patch)
treee3b600ddd4503f232ae79414998e2dc4da89fc8d /sys
parente5a9220c6217b9923c1448c7956d0a6016b5e48c (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.c25
-rw-r--r--sys/dev/i2c/i2cvar.h4
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_ */