From 7349a5e9843380e84de1d205db0a0e8096fd885c Mon Sep 17 00:00:00 2001 From: visa Date: Wed, 9 Feb 2022 07:58:24 +0000 Subject: [PATCH] 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@ --- share/man/man9/iic.9 | 18 +++++++++++++++--- sys/dev/i2c/i2c.c | 25 ++++++++++++++++++++++++- sys/dev/i2c/i2cvar.h | 4 +++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/share/man/man9/iic.9 b/share/man/man9/iic.9 index 7fd3855910a..ce3bb00657c 100644 --- a/share/man/man9/iic.9 +++ b/share/man/man9/iic.9 @@ -1,4 +1,4 @@ -.\" $OpenBSD: iic.9,v 1.9 2015/11/23 17:53:57 jmc Exp $ +.\" $OpenBSD: iic.9,v 1.10 2022/02/09 07:58:24 visa Exp $ .\" .\" Copyright (c) 2003 Wasabi Systems, Inc. .\" All rights reserved. @@ -33,7 +33,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 23 2015 $ +.Dd $Mdocdate: February 9 2022 $ .Dt IIC_ACQUIRE_BUS 9 .Os .Sh NAME @@ -42,7 +42,8 @@ .Nm iic_exec , .Nm iic_smbus_write_byte , .Nm iic_smbus_read_byte , -.Nm iic_smbus_receive_byte +.Nm iic_smbus_receive_byte , +.Nm iic_is_compatible .Nd Inter IC (I2C) bus .Sh SYNOPSIS .In dev/i2c/i2cvar.h @@ -90,6 +91,11 @@ .Fa "uint8_t *datap" .Fa "int flags" .Fc +.Ft int +.Fo iic_is_compatible +.Fa "const struct i2c_attach_args *ia" +.Fa "const char *name" +.Fc .Sh DESCRIPTION I2C is a two-wire bus developed by Philips used for connecting integrated circuits. @@ -137,8 +143,11 @@ 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 */ }; .Ed .El @@ -231,6 +240,9 @@ I2C_OP_READ_WITH_STOP with of 0 and .Fa len of 1. +.It Fn iic_is_compatible "ia" "name" +Test if the device is compatible with +.Fa name . .El .Sh CONTROLLER INTERFACE The I2C controller driver must fill in the function pointers of 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_ */ -- 2.20.1