summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-11-13 10:14:52 +0000
committerpatrick <patrick@openbsd.org>2020-11-13 10:14:52 +0000
commitb7461f4bb2004ebed4660ebc3bf78b00583e21f9 (patch)
tree5d68e090b7312c5a2e083f0092d16ebc3e214414
parentscrub keyboard-interactive authentication prompts coming from the (diff)
downloadwireguard-openbsd-b7461f4bb2004ebed4660ebc3bf78b00583e21f9.tar.xz
wireguard-openbsd-b7461f4bb2004ebed4660ebc3bf78b00583e21f9.zip
Add support for the PCA9547 I2C mux to pcamux(4). In comparison to
the PCA954[68], this is a mux instead of a switch and can only have one active channel at a time. On the bright side, we treat switches like a mux, so only the bits have to be set a little bit differently. ok kettenis@
-rw-r--r--share/man/man4/iic.46
-rw-r--r--share/man/man4/pcamux.410
-rw-r--r--sys/dev/i2c/pca9548.c28
3 files changed, 29 insertions, 15 deletions
diff --git a/share/man/man4/iic.4 b/share/man/man4/iic.4
index e1318dca8e4..bcbbedb2d23 100644
--- a/share/man/man4/iic.4
+++ b/share/man/man4/iic.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: iic.4,v 1.114 2020/10/01 07:37:47 jmc Exp $
+.\" $OpenBSD: iic.4,v 1.115 2020/11/13 10:14:53 patrick Exp $
.\"
.\" Copyright (c) 2004, 2006 Alexander Yurchenko <grange@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 1 2020 $
+.Dd $Mdocdate: November 13 2020 $
.Dt IIC 4
.Os
.Sh NAME
@@ -220,7 +220,7 @@ Philips PCA955[4567] GPIO controller
.It Xr pcaled 4
Philips PCA9532/9552 GPIO LED dimmer
.It Xr pcamux 4
-Philips PCA954[68] I2C switch
+Philips PCA954[678] I2C switch/mux
.It Xr pcfadc 4
Philips PCF8591 temperature sensor
.It Xr pcfrtc 4
diff --git a/share/man/man4/pcamux.4 b/share/man/man4/pcamux.4
index 82eda7cc9f2..a03729fb0c3 100644
--- a/share/man/man4/pcamux.4
+++ b/share/man/man4/pcamux.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pcamux.4,v 1.3 2020/09/29 13:59:22 patrick Exp $
+.\" $OpenBSD: pcamux.4,v 1.4 2020/11/13 10:14:53 patrick Exp $
.\"
.\" Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
.\"
@@ -14,20 +14,20 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 29 2020 $
+.Dd $Mdocdate: November 13 2020 $
.Dt PCAMUX 4
.Os
.Sh NAME
.Nm pcamux
-.Nd Philips PCA954[68] I2C switch
+.Nd Philips PCA954[678] I2C switch/mux
.Sh SYNOPSIS
.Cd "pcamux* at iic?"
.Cd "iic* at pcamux?"
.Sh DESCRIPTION
The
.Nm
-driver provides support for the Philips PCA954[68] I2C switch,
-which is used with the
+driver provides support for the Philips PCA954[68] I2C switch
+and Philips PCA9547 I2C mux, which is used with the
.Xr iic 4
framework.
.Sh SEE ALSO
diff --git a/sys/dev/i2c/pca9548.c b/sys/dev/i2c/pca9548.c
index f4320a9f985..2709a05e79c 100644
--- a/sys/dev/i2c/pca9548.c
+++ b/sys/dev/i2c/pca9548.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pca9548.c,v 1.3 2020/09/29 13:59:22 patrick Exp $ */
+/* $OpenBSD: pca9548.c,v 1.4 2020/11/13 10:14:52 patrick Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis
@@ -28,8 +28,6 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_misc.h>
-#define PCA9546_NUM_CHANNELS 4
-#define PCA9548_NUM_CHANNELS 8
#define PCAMUX_MAX_CHANNELS 8
struct pcamux_bus {
@@ -44,12 +42,15 @@ struct pcamux_softc {
struct device sc_dev;
i2c_tag_t sc_tag;
i2c_addr_t sc_addr;
-
+
int sc_node;
int sc_channel;
int sc_nchannel;
struct pcamux_bus sc_bus[PCAMUX_MAX_CHANNELS];
struct rwlock sc_lock;
+
+ int sc_switch;
+ int sc_enable;
};
int pcamux_match(struct device *, void *, void *);
@@ -75,6 +76,7 @@ pcamux_match(struct device *parent, void *match, void *aux)
struct i2c_attach_args *ia = aux;
if (strcmp(ia->ia_name, "nxp,pca9546") == 0 ||
+ strcmp(ia->ia_name, "nxp,pca9547") == 0 ||
strcmp(ia->ia_name, "nxp,pca9548") == 0)
return (1);
return (0);
@@ -94,10 +96,16 @@ pcamux_attach(struct device *parent, struct device *self, void *aux)
sc->sc_channel = -1; /* unknown */
rw_init(&sc->sc_lock, sc->sc_dev.dv_xname);
- if (strcmp(ia->ia_name, "nxp,pca9546") == 0)
+ if (strcmp(ia->ia_name, "nxp,pca9546") == 0) {
+ sc->sc_switch = 1;
sc->sc_nchannel = 4;
- else if (strcmp(ia->ia_name, "nxp,pca9548") == 0)
+ } else if (strcmp(ia->ia_name, "nxp,pca9547") == 0) {
+ sc->sc_enable = 1 << 3;
+ sc->sc_nchannel = 8;
+ } else if (strcmp(ia->ia_name, "nxp,pca9548") == 0) {
+ sc->sc_switch = 1;
sc->sc_nchannel = 8;
+ }
printf("\n");
@@ -146,7 +154,13 @@ pcamux_set_channel(struct pcamux_softc *sc, int channel, int flags)
if (sc->sc_channel == channel)
return 0;
- data = (channel == -1) ? 0 : (1 << channel);
+ data = 0;
+ if (channel != -1) {
+ if (sc->sc_switch)
+ data = 1 << channel;
+ else
+ data = sc->sc_enable | channel;
+ }
error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
sc->sc_addr, NULL, 0, &data, sizeof data, flags);