[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211214095021.572799-2-patrick.rudolph@9elements.com>
Date: Tue, 14 Dec 2021 10:50:19 +0100
From: Patrick Rudolph <patrick.rudolph@...ements.com>
To: Peter Rosin <peda@...ntia.se>
Cc: Patrick Rudolph <patrick.rudolph@...ements.com>,
linux-i2c@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 2/4] drivers/i2c/mux: Add MAX735x support to PCA954x
Add support for MAX7356, MAX7357 and MAX7358 using the existing driver.
All added Maxim chips behave like the PCA9848, where a single SMBUS byte
write selects up to 8 channels to be bridged to the primary bus.
The MAX7357 exposes 6 additional registers at Power-On-Reset and is
configured to enable additional features:
- Disabled interrupts on bus locked up detection
- Enable bus locked-up clearing
- Disconnect only locked bus instead of all channels
The MAX7357/MAX7358 IRQs aren't supported and must not be enabled.
Signed-off-by: Patrick Rudolph <patrick.rudolph@...ements.com>
---
drivers/i2c/muxes/Kconfig | 4 +-
drivers/i2c/muxes/i2c-mux-pca954x.c | 63 +++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 1708b1a82da2..621c8a5314f6 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -65,11 +65,11 @@ config I2C_MUX_PCA9541
will be called i2c-mux-pca9541.
config I2C_MUX_PCA954x
- tristate "NXP PCA954x and PCA984x I2C Mux/switches"
+ tristate "NXP PCA954x and PCA984x and Maxim MAX735x I2C Mux/switches"
depends on GPIOLIB || COMPILE_TEST
help
If you say yes here you get support for the NXP PCA954x
- and PCA984x I2C mux/switch devices.
+ and PCA984x and Maxim MAX735x I2C mux/switch devices.
This driver can also be built as a module. If so, the module
will be called i2c-mux-pca954x.
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 4ad665757dd8..23e0f24bab04 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -11,6 +11,12 @@
* PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547,
* PCA9548, PCA9846, PCA9847, PCA9848 and PCA9849.
*
+ * It's also compatible to Maxims MAX735x I2C switch chips, which is controlled
+ * as the NXP PCA9548.
+ *
+ * This includes the:
+ * MAX7356, MAX7357 and MAX7358.
+ *
* These chips are all controlled via the I2C bus itself, and all have a
* single 8-bit register. The upstream "parent" bus fans out to two,
* four, or eight downstream busses or channels; which of these
@@ -50,7 +56,12 @@
#define PCA954X_IRQ_OFFSET 4
+#define MAX7357_REG_CONFIG_DEFAULTS 0x16
+
enum pca_type {
+ max_7356,
+ max_7357,
+ max_7358,
pca_9540,
pca_9542,
pca_9543,
@@ -69,6 +80,8 @@ struct chip_desc {
u8 nchans;
u8 enable; /* used for muxes only */
u8 has_irq;
+ u8 max7357;
+ u8 max735x;
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi
@@ -90,8 +103,27 @@ struct pca954x {
raw_spinlock_t lock;
};
-/* Provide specs for the PCA954x types we know about */
+/* Provide specs for the PCA954x and MAX735x types we know about */
static const struct chip_desc chips[] = {
+ [max_7356] = {
+ .nchans = 8,
+ .muxtype = pca954x_isswi,
+ .max735x = 1,
+ .id = { .manufacturer_id = I2C_DEVICE_ID_NONE },
+ },
+ [max_7357] = {
+ .nchans = 8,
+ .muxtype = pca954x_isswi,
+ .max735x = 1,
+ .max7357 = 1,
+ .id = { .manufacturer_id = I2C_DEVICE_ID_NONE },
+ },
+ [max_7358] = {
+ .nchans = 8,
+ .muxtype = pca954x_isswi,
+ .max735x = 1,
+ .id = { .manufacturer_id = I2C_DEVICE_ID_NONE },
+ },
[pca_9540] = {
.nchans = 2,
.enable = 0x4,
@@ -177,6 +209,9 @@ static const struct chip_desc chips[] = {
};
static const struct i2c_device_id pca954x_id[] = {
+ { "max7356", max_7356 },
+ { "max7357", max_7357 },
+ { "max7358", max_7358 },
{ "pca9540", pca_9540 },
{ "pca9542", pca_9542 },
{ "pca9543", pca_9543 },
@@ -194,6 +229,9 @@ static const struct i2c_device_id pca954x_id[] = {
MODULE_DEVICE_TABLE(i2c, pca954x_id);
static const struct of_device_id pca954x_of_match[] = {
+ { .compatible = "maxim,max7356", .data = &chips[max_7356] },
+ { .compatible = "maxim,max7357", .data = &chips[max_7357] },
+ { .compatible = "maxim,max7358", .data = &chips[max_7358] },
{ .compatible = "nxp,pca9540", .data = &chips[pca_9540] },
{ .compatible = "nxp,pca9542", .data = &chips[pca_9542] },
{ .compatible = "nxp,pca9543", .data = &chips[pca_9543] },
@@ -355,6 +393,11 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc)
if (!data->chip->has_irq || client->irq <= 0)
return 0;
+ if (data->chip->max735x) {
+ dev_err(&client->dev, "IRQs not supported for MAX735x\n");
+ return -EOPNOTSUPP;
+ }
+
raw_spin_lock_init(&data->lock);
data->irq = irq_domain_add_linear(client->dev.of_node,
@@ -401,9 +444,21 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data)
else
data->last_chan = 0; /* Disconnect multiplexer */
- ret = i2c_smbus_write_byte(client, data->last_chan);
- if (ret < 0)
- data->last_chan = 0;
+ /*
+ * MAX7357 exposes 7 register on POR which allows to configure additional
+ * features. Disable interrupts, enable bus locked-up clearing,
+ * disconnect only locked bus instead of all channels.
+ */
+ if (data->chip->max7357) {
+ ret = i2c_smbus_write_byte_data(client, data->last_chan,
+ MAX7357_REG_CONFIG_DEFAULTS);
+ if (ret < 0)
+ data->last_chan = 0;
+ } else {
+ ret = i2c_smbus_write_byte(client, data->last_chan);
+ if (ret < 0)
+ data->last_chan = 0;
+ }
return ret;
}
--
2.33.1
Powered by blists - more mailing lists