Skip to contentSkip to conversation

Add support for Maxim MAX735x/MAX736x variants

PATCH Superseded Patrick Rudolph 3 participants 9 messages Jan 8, 2022 – Jan 20, 2022

Subsystems (3)

v2 of 16 Superseded Latest is v16 →

lore
Share & tools
lore
#0 lore raw

v2 cover Add support for Maxim MAX735x/MAX736x variants

v2:
- Move dt-bindings to separate file
- Added support for MAX736x as they are very similar
- Fixed an issue found by kernel test robot
- Dropped max735x property and custom IRQ check
- Added MAX7357 config register defines instead of magic values
- Renamed vcc-supply to vdd-supply

Patrick Rudolph (4):
dt-bindings: i2c: Add Maxim MAX735x/MAX736x variants
i2c: muxes: pca954x: Add MAX735x/MAX736x support
dt-bindings: i2c: Add regulator to pca954x and max735x
i2c: muxes: pca954x: Add regulator support

 .../bindings/i2c/i2c-mux-max735x.yaml         | 106 +++++++++++++++
 .../bindings/i2c/i2c-mux-pca954x.yaml         |   5 +
 drivers/i2c/muxes/Kconfig                     |   4 +-
 drivers/i2c/muxes/i2c-mux-pca954x.c           | 124 ++++++++++++++++--
 4 files changed, 228 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml
Signature · 1 line
2.33.1
#1 lore raw

PATCH v2 1/4 dt-bindings: i2c: Add Maxim MAX735x/MAX736x variants

Add the Maxim MAX735x/MAX736x as supported chip and give an example how to use it. The functionality will be provided by the exisintg pca954x driver.

---
 .../bindings/i2c/i2c-mux-max735x.yaml         | 101 ++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml
Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml new file +101 -0
new file mode 100644
index 000000000000..dc924ec934ca
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/i2c-mux-max735x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX735x/MAX736x I2C bus switch
+
+maintainers:
+  - Laurent Pinchart <[email protected]>
+
+description:
+  The binding supports Maxim MAX735x and MAX736x I2C mux/switch devices.
+
+allOf:
+  - $ref: /schemas/i2c/i2c-mux.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - maxim,max7367
+              - maxim,max7369
+    then:
+      properties:
+        interrupts: true
+
+        "#interrupt-cells":
+          const: 2
+
+        interrupt-controller: true
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - maxim,max7356
+          - maxim,max7357
+          - maxim,max7358
+          - maxim,max7367
+          - maxim,max7368
+          - maxim,max7369
+
+  reg:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  i2c-mux-idle-disconnect:
+    type: boolean
+    description: Forces mux to disconnect all children in idle state. This is
+      necessary for example, if there are several multiplexers on the bus and
+      the devices behind them use same I2C addresses.
+
+  idle-state:
+    description: if present, overrides i2c-mux-idle-disconnect
+    $ref: /schemas/mux/mux-controller.yaml#/properties/idle-state
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        i2c-mux@74 {
+            compatible = "maxim,max7357";
+            #address-cells = <1>;
+            #size-cells = <0>;
+            reg = <0x74>;
+
+            i2c@1 {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                reg = <1>;
+
+                eeprom@54 {
+                    compatible = "atmel,24c08";
+                    reg = <0x54>;
+                };
+            };
+
+            i2c@7 {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                reg = <7>;
+
+                rtc@51 {
+                    compatible = "nxp,pcf8563";
+                    reg = <0x51>;
+                };
+            };
+        };
+    };
+...
Signature · 1 line
2.33.1
#2 lore raw

Re: [PATCH v2 1/4] dt-bindings: i2c: Add Maxim MAX735x/MAX736x variants

Hi Patrick,

Thank you for the patch.

Quoted 3 lines · Patrick Rudolph

Add the Maxim MAX735x/MAX736x as supported chip and give an example how to use it. The functionality will be provided by the exisintg pca954x driver.

While DT bindings and drivers are decoupled, the fact that the same driver provides support for the MAX735x/MAX736x indicates there's some similarity between those and the PCA954x chips. Would they be similar enough to have a single DT binding schema file ? This file looks very similar to Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml.

Quoted 113 lines
---
 .../bindings/i2c/i2c-mux-max735x.yaml         | 101 ++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml
Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml new file +101 -0
new file mode 100644
index 000000000000..dc924ec934ca
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/i2c-mux-max735x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX735x/MAX736x I2C bus switch
+
+maintainers:
+  - Laurent Pinchart <[email protected]>
+
+description:
+  The binding supports Maxim MAX735x and MAX736x I2C mux/switch devices.
+
+allOf:
+  - $ref: /schemas/i2c/i2c-mux.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - maxim,max7367
+              - maxim,max7369
+    then:
+      properties:
+        interrupts: true
+
+        "#interrupt-cells":
+          const: 2
+
+        interrupt-controller: true
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - maxim,max7356
+          - maxim,max7357
+          - maxim,max7358
+          - maxim,max7367
+          - maxim,max7368
+          - maxim,max7369
+
+  reg:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  i2c-mux-idle-disconnect:
+    type: boolean
+    description: Forces mux to disconnect all children in idle state. This is
+      necessary for example, if there are several multiplexers on the bus and
+      the devices behind them use same I2C addresses.
+
+  idle-state:
+    description: if present, overrides i2c-mux-idle-disconnect
+    $ref: /schemas/mux/mux-controller.yaml#/properties/idle-state
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        i2c-mux@74 {
+            compatible = "maxim,max7357";
+            #address-cells = <1>;
+            #size-cells = <0>;
+            reg = <0x74>;
+
+            i2c@1 {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                reg = <1>;
+
+                eeprom@54 {
+                    compatible = "atmel,24c08";
+                    reg = <0x54>;
+                };
+            };
+
+            i2c@7 {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                reg = <7>;
+
+                rtc@51 {
+                    compatible = "nxp,pcf8563";
+                    reg = <0x51>;
+                };
+            };
+        };
+    };
+...
Signature · 3 lines
Regards,

Laurent Pinchart
#3 lore raw

PATCH v2 2/4 i2c: muxes: pca954x: Add MAX735x/MAX736x support

In reply to Patrick Rudolph

Add support for the following Maxim chips using the existing PCA954x driver:
- MAX7356
- MAX7357
- MAX7358
- MAX7367
- MAX7368
- MAX7369

All added Maxim chips behave like the PCA954x, 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:
- Disabled interrupts on bus locked up detection
- Enable bus locked-up clearing
- Disconnect only locked bus instead of all channels

While the MAX7357/MAX7358 have interrupt support, they don't act as interrupt controller like the PCA9545 does. Thus don't enable IRQ support and handle them like the PCA9548.

Tested using the MAX7357 and verified that the stalled bus is disconnected while the other channels remain operational.

---
 drivers/i2c/muxes/Kconfig           |  4 +-
 drivers/i2c/muxes/i2c-mux-pca954x.c | 92 +++++++++++++++++++++++++++--
 2 files changed, 90 insertions(+), 6 deletions(-)
drivers/i2c/muxes/Kconfig +2 -2
index 1708b1a82da2..2ac99d044199 100644
@@ -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/PCA984x and Maxim MAX735x/MAX736x 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/MAX736x I2C mux/switch devices.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-mux-pca954x.
drivers/i2c/muxes/i2c-mux-pca954x.c +88 -4

142 lines not on this page · raw message

Signature · 1 line
2.33.1
#4 lore raw

PATCH v2 3/4 dt-bindings: i2c: Add regulator to pca954x and max735x

In reply to Patrick Rudolph

Add a regulator called vdd also present in datasheets of PCA954x and MAX735x and update the examples.

---
 Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml | 5 +++++
 Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml | 5 +++++
 2 files changed, 10 insertions(+)
Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml +5 -0
index dc924ec934ca..93eda07718e8 100644
@@ -57,6 +57,9 @@ properties:
     description: if present, overrides i2c-mux-idle-disconnect
     $ref: /schemas/mux/mux-controller.yaml#/properties/idle-state
 
+  vdd-supply:
+    description: A voltage regulator supplying power to the chip.
+
 required:
   - compatible
   - reg
@@ -75,6 +78,8 @@ examples:
             #size-cells = <0>;
             reg = <0x74>;
 
+            vdd-supply = <&p3v3>;
+
             i2c@1 {
                 #address-cells = <1>;
                 #size-cells = <0>;
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml +5 -0
index 9f1726d0356b..b28d05dc956d 100644
@@ -59,6 +59,9 @@ properties:
     description: if present, overrides i2c-mux-idle-disconnect
     $ref: /schemas/mux/mux-controller.yaml#/properties/idle-state
 
+  vdd-supply:
+    description: A voltage regulator supplying power to the chip.
+
 required:
   - compatible
   - reg
@@ -79,6 +82,8 @@ examples:
             #size-cells = <0>;
             reg = <0x74>;
 
+            vdd-supply = <&p3v3>;
+
             interrupt-parent = <&ipic>;
             interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
             interrupt-controller;
Signature · 1 line
2.33.1
Reviewed-by on v2 3/4
#5 lore raw

Re: [PATCH v2 3/4] dt-bindings: i2c: Add regulator to pca954x and max735x

Hi Patrick,

Thank you for the patch.

Quoted 24 lines · Patrick Rudolph

Add a regulator called vdd also present in datasheets of PCA954x and MAX735x and update the examples.

---
 Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml | 5 +++++
 Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml | 5 +++++
 2 files changed, 10 insertions(+)
Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml +3 -0
index dc924ec934ca..93eda07718e8 100644
@@ -57,6 +57,9 @@ properties:
     description: if present, overrides i2c-mux-idle-disconnect
     $ref: /schemas/mux/mux-controller.yaml#/properties/idle-state
 
+  vdd-supply:
+    description: A voltage regulator supplying power to the chip.
+
 required:
   - compatible
   - reg

Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml examples: · line 85

Quoted 8 lines
Documentation/devicetree/bindings/i2c/i2c-mux-max735x.yaml +2 -0
@@ -75,6 +78,8 @@ examples:
             #size-cells = <0>;
             reg = <0x74>;
 
+            vdd-supply = <&p3v3>;
+
             i2c@1 {
                 #address-cells = <1>;
                 #size-cells = <0>;

This should be part of patch 1/4 (or better in my opinion, the two binding files should be merged into a single one).

Quoted 15 lines
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml +3 -0
index 9f1726d0356b..b28d05dc956d 100644
@@ -59,6 +59,9 @@ properties:
     description: if present, overrides i2c-mux-idle-disconnect
     $ref: /schemas/mux/mux-controller.yaml#/properties/idle-state
 
+  vdd-supply:
+    description: A voltage regulator supplying power to the chip.
+
 required:
   - compatible
   - reg

Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml examples: · line 89

Quoted 8 lines
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml +2 -0
@@ -79,6 +82,8 @@ examples:
             #size-cells = <0>;
             reg = <0x74>;
 
+            vdd-supply = <&p3v3>;
+
             interrupt-parent = <&ipic>;
             interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
             interrupt-controller;

For this part,

Signature · 3 lines
Regards,

Laurent Pinchart
#6 lore raw

PATCH v2 4/4 i2c: muxes: pca954x: Add regulator support

In reply to Patrick Rudolph

Add an optional vdd regulator and enable it when found for devices that are powered off by default.

---
 drivers/i2c/muxes/i2c-mux-pca954x.c | 32 ++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)
drivers/i2c/muxes/i2c-mux-pca954x.c +27 -5
index 33b9a6a1fffa..086647193ea9 100644
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/property.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <dt-bindings/mux/mux.h>
@@ -119,6 +120,7 @@ struct pca954x {
 	struct irq_domain *irq;
 	unsigned int irq_mask;
 	raw_spinlock_t lock;
+	struct regulator *supply;
 };
 
 /* Provide specs for the PCA954x and MAX735x types we know about */
@@ -459,6 +461,9 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc)
 	struct pca954x *data = i2c_mux_priv(muxc);
 	int c, irq;
 
+	if (!IS_ERR_OR_NULL(data->supply))
+		regulator_disable(data->supply);
+
 	if (data->irq) {
 		for (c = 0; c < data->chip->nchans; c++) {
 			irq = irq_find_mapping(data->irq, c);
@@ -513,15 +518,30 @@ static int pca954x_probe(struct i2c_client *client,
 			     pca954x_select_chan, pca954x_deselect_mux);
 	if (!muxc)
 		return -ENOMEM;
+
 	data = i2c_mux_priv(muxc);
 
 	i2c_set_clientdata(client, muxc);
 	data->client = client;
 
+	data->supply = devm_regulator_get_optional(dev, "vdd");
+	if (IS_ERR(data->supply)) {
+		if ((PTR_ERR(data->supply) == -EPROBE_DEFER))
+			return -EPROBE_DEFER;
+	} else {
+		ret = regulator_enable(data->supply);
+		if (ret) {
+			dev_err(dev, "Failed to enable regulator vdd: %d\n", ret);
+			return ret;
+		}
+	}
+
 	/* Reset the mux if a reset GPIO is specified. */
 	gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-	if (IS_ERR(gpio))
-		return PTR_ERR(gpio);
+	if (IS_ERR(gpio)) {
+		ret = PTR_ERR(gpio);
+		goto fail_cleanup;
+	}
 	if (gpio) {
 		udelay(1);
 		gpiod_set_value_cansleep(gpio, 0);
@@ -538,7 +558,7 @@ static int pca954x_probe(struct i2c_client *client,
 
 		ret = i2c_get_device_id(client, &id);
 		if (ret && ret != -EOPNOTSUPP)
-			return ret;
+			goto fail_cleanup;
 
 		if (!ret &&
 		    (id.manufacturer_id != data->chip->id.manufacturer_id ||
@@ -546,7 +566,8 @@ static int pca954x_probe(struct i2c_client *client,
 			dev_warn(dev, "unexpected device id %03x-%03x-%x\n",
 				 id.manufacturer_id, id.part_id,
 				 id.die_revision);
-			return -ENODEV;
+			ret = -ENODEV;
+			goto fail_cleanup;
 		}
 	}
 
@@ -565,7 +586,8 @@ static int pca954x_probe(struct i2c_client *client,
 	ret = pca954x_init(client, data);
 	if (ret < 0) {
 		dev_warn(dev, "probe failed\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto fail_cleanup;
 	}
 
 	ret = pca954x_irq_setup(muxc);
Signature · 1 line
2.33.1
#7 lore raw

Re: [PATCH v2 4/4] i2c: muxes: pca954x: Add regulator support

Quoted 4 lines · Patrick Rudolph

Add an optional vdd regulator and enable it when found for devices that are powered off by default.

regulator support was recently added to the I2C core but had to be reverted because of side effects [1]. I think you could make use of it if it gets readded?

[1] a19f75de73c2 ("Revert "i2c: core: support bus regulator controlling in adapter"")

#8 lore raw

Re: [PATCH v2 4/4] i2c: muxes: pca954x: Add regulator support

Hi Wolfram,
I don't think that it's possible to use the generic vbus-supply. In my case the complete chip, not only the bus, is powered by a regulator. In addition it looks like this works only for platform drivers where you can set the bus_regulator
before the i2c core probe function is invoked.

Regards,
Patrick Rudolph

Quoted 13 lines · Wolfram Sang
Quoted 4 lines · Patrick Rudolph

Add an optional vdd regulator and enable it when found for devices that are powered off by default.

regulator support was recently added to the I2C core but had to be reverted because of side effects [1]. I think you could make use of it if it gets readded?

[1] a19f75de73c2 ("Revert "i2c: core: support bus regulator controlling in adapter"")