public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] mfd: max597x: Add support for max597x
@ 2022-07-07 13:41 Naresh Solanki
  2022-07-07 13:41 ` [PATCH v2 1/5] dt-bindings: mfd: Add bindings for MAX5970 and MAX5978 Naresh Solanki
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Naresh Solanki @ 2022-07-07 13:41 UTC (permalink / raw)
  To: linux-kernel; +Cc: Naresh Solanki

max597x is multifunction device with hot swap controller, fault
protection & upto four indication leds.

max5978 has single hot swap controller whereas max5970 has two hot swap
controllers.

Changes in V2:
- Update depends in Kconfig.

Marcello Sylvester Bauer (1):
  dt-bindings: mfd: Add bindings for MAX5970 and MAX5978

Patrick Rudolph (4):
  mfd: max597x: Add support for MAX5970 and MAX5978
  regulator: max597x: Add support for max597x regulator
  iio: max597x: Add support for max597x
  leds: max597x: Add support for max597x

 .../devicetree/bindings/mfd/max5970.yaml      | 164 ++++++
 drivers/iio/adc/Kconfig                       |   9 +
 drivers/iio/adc/Makefile                      |   1 +
 drivers/iio/adc/max597x-iio.c                 | 156 ++++++
 drivers/leds/Kconfig                          |  10 +
 drivers/leds/Makefile                         |   1 +
 drivers/leds/leds-max597x.c                   | 130 +++++
 drivers/mfd/Kconfig                           |  12 +
 drivers/mfd/Makefile                          |   2 +
 drivers/mfd/max597x.c                         | 109 ++++
 drivers/regulator/Kconfig                     |  10 +
 drivers/regulator/Makefile                    |   1 +
 drivers/regulator/max597x-regulator.c         | 506 ++++++++++++++++++
 include/linux/mfd/max597x.h                   | 100 ++++
 14 files changed, 1211 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/max5970.yaml
 create mode 100644 drivers/iio/adc/max597x-iio.c
 create mode 100644 drivers/leds/leds-max597x.c
 create mode 100644 drivers/mfd/max597x.c
 create mode 100644 drivers/regulator/max597x-regulator.c
 create mode 100644 include/linux/mfd/max597x.h


base-commit: 9f09069cde34dcd86f5ecf3a3139fd752020812f
-- 
2.35.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/5] dt-bindings: mfd: Add bindings for MAX5970 and MAX5978
  2022-07-07 13:41 [PATCH v2 0/5] mfd: max597x: Add support for max597x Naresh Solanki
@ 2022-07-07 13:41 ` Naresh Solanki
  2022-07-07 13:41 ` [PATCH v2 2/5] mfd: max597x: Add support " Naresh Solanki
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Naresh Solanki @ 2022-07-07 13:41 UTC (permalink / raw)
  To: linux-kernel, Lee Jones, Patrick Rudolph
  Cc: Marcello Sylvester Bauer, Naresh Solanki

From: Marcello Sylvester Bauer <sylv@sylv.io>

The MAX597x is a hot swap controller with configurable fault protection.
It also has 10bit ADC for current & voltage measurements.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com>
---
 .../devicetree/bindings/mfd/max5970.yaml      | 164 ++++++++++++++++++
 1 file changed, 164 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/max5970.yaml

diff --git a/Documentation/devicetree/bindings/mfd/max5970.yaml b/Documentation/devicetree/bindings/mfd/max5970.yaml
new file mode 100644
index 000000000000..a0cc6a7543b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/max5970.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/max5970.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Regulator driver for MAX5970 smart switch from Maxim Integrated.
+
+maintainers:
+  - Patrick Rudolph <patrick.rudolph@9elements.com>
+
+description: |
+  The smart switch provides no output regulation, but independent fault protection
+  and voltage and current sensing.
+  Programming is done through I2C bus.
+
+  Datasheets:
+    https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf
+    https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf
+
+properties:
+  compatible:
+    enum:
+      - maxim,max5970
+      - maxim,max5978
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  leds:
+    type: object
+    description:
+      Properties for single channel.
+
+    patternProperties:
+      "^led@[0-3]$":
+        $ref: /schemas/leds/common.yaml#
+        type: object
+
+    additionalProperties: true
+
+  vss1-supply:
+    description: Supply of the first channel.
+
+  "#io-channel-cells":
+    const: 1
+
+  regulators:
+    type: object
+    description:
+      Properties for single channel.
+
+    patternProperties:
+      "^(sw[0-1])$":
+        $ref: /schemas/regulator/regulator.yaml#
+        type: object
+
+      shunt-resistor-micro-ohms:
+        description: |
+          The value of curent sense resistor in microohms.
+          Must be specified for each channel.
+
+    additionalProperties: true
+
+required:
+  - compatible
+  - reg
+  - regulators
+  - vss1-supply
+
+allOf:
+  - $ref: /schemas/regulator/regulator.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - maxim,max5970
+    then:
+      properties:
+        vss2-supply:
+          description: Supply of the second channel.
+
+        io-channels:
+          items:
+            - description: voltage first channel
+            - description: current first channel
+            - description: voltage second channel
+            - description: current second channel
+          description: |
+            Voltage and current for first and second channel.
+      required:
+        - vss2-supply
+
+    else:
+      properties:
+        io-channels:
+          items:
+            - description: voltage first channel
+            - description: current first channel
+          description: |
+            Voltage and current for first channel.
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            leds {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                led@0 {
+                        reg = <0>;
+                        label = "led0";
+                        default-state = "on";
+                };
+                led@1 {
+                        reg = <1>;
+                        label = "led1";
+                        default-state = "on";
+                };
+            };
+            regulator@3a {
+                    reg = <0x3a>;
+                    vss1-supply = <&p3v3>;
+                    compatible = "maxim,max5978";
+
+                    regulators {
+                            sw0_ref_0: SW0 {
+                                   regulator-compatible = "SW0";
+                                   shunt-resistor-micro-ohms = <12000>;
+                            };
+                    };
+            };
+    };
+
+  - |
+    i2c {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            regulator@3a {
+                    reg = <0x3a>;
+                    vss1-supply = <&p3v3>;
+                    vss2-supply = <&p5v>;
+                    compatible = "maxim,max5970";
+
+                    regulators {
+                            sw0_ref_1: SW0 {
+                                   regulator-compatible = "SW0";
+                                   shunt-resistor-micro-ohms = <12000>;
+                            };
+                            sw1_ref_1: SW1 {
+                                   regulator-compatible = "SW1";
+                                   shunt-resistor-micro-ohms = <10000>;
+                            };
+                    };
+            };
+    };
+...
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/5] mfd: max597x: Add support for MAX5970 and MAX5978
  2022-07-07 13:41 [PATCH v2 0/5] mfd: max597x: Add support for max597x Naresh Solanki
  2022-07-07 13:41 ` [PATCH v2 1/5] dt-bindings: mfd: Add bindings for MAX5970 and MAX5978 Naresh Solanki
@ 2022-07-07 13:41 ` Naresh Solanki
  2022-08-08 13:55   ` Lee Jones
  2022-07-07 13:41 ` [PATCH v2 3/5] regulator: max597x: Add support for max597x regulator Naresh Solanki
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Naresh Solanki @ 2022-07-07 13:41 UTC (permalink / raw)
  To: linux-kernel, Lee Jones
  Cc: Patrick Rudolph, Marcello Sylvester Bauer, Naresh Solanki

From: Patrick Rudolph <patrick.rudolph@9elements.com>

Implement a regulator driver with IRQ support for fault management.
Written against documentation [1] and [2] and tested on real hardware.

Every channel has it's own regulator supply nammed 'vss1-supply' and
'vss2-supply'. The regulator supply is used to determine the output
voltage, as the smart switch provides no output regulation.
The driver requires the 'shunt-resistor-micro-ohms' to be present in
the devicetree to properly calculate current related values.

You must specify compatible devictree layout:

regulator@3a {
        reg = <0x3a>;
        vss1-supply = <&p3v3>;
        compatible = "maxim,max5978";

        ...

        regulators {
                sw0_ref: SW0 {
                        regulator-compatible = "SW0";
                        shunt-resistor-micro-ohms = <12000>;
                        ...
                }
        }
}

1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf
2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com>
---
 drivers/mfd/Kconfig         |  12 ++++
 drivers/mfd/Makefile        |   2 +
 drivers/mfd/max597x.c       | 109 ++++++++++++++++++++++++++++++++++++
 include/linux/mfd/max597x.h | 100 +++++++++++++++++++++++++++++++++
 4 files changed, 223 insertions(+)
 create mode 100644 drivers/mfd/max597x.c
 create mode 100644 include/linux/mfd/max597x.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3b59456f5545..2422ae155118 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -253,6 +253,18 @@ config MFD_MADERA_SPI
 	  Support for the Cirrus Logic Madera platform audio SoC
 	  core functionality controlled via SPI.
 
+config MFD_MAX597X
+	tristate "Maxim 597x power switch and monitor"
+	depends on I2C
+	depends on OF
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  This driver controls a Maxim 5970/5978 switch via I2C bus.
+	  The MAX5970/5978 is a smart switch with no output regulation, but
+	  fault protection and voltage and current monitoring capabilities.
+	  Also it supports upto 4 indication leds.
+
 config MFD_CS47L15
 	bool "Cirrus Logic CS47L15"
 	select PINCTRL_CS47L15
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 858cacf659d6..f5f46b86401f 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -95,6 +95,8 @@ obj-$(CONFIG_MFD_MADERA)	+= madera.o
 obj-$(CONFIG_MFD_MADERA_I2C)	+= madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)	+= madera-spi.o
 
+obj-$(CONFIG_MFD_MAX597X) += max597x.o
+
 obj-$(CONFIG_TPS6105X)		+= tps6105x.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
diff --git a/drivers/mfd/max597x.c b/drivers/mfd/max597x.c
new file mode 100644
index 000000000000..b2450e64d3eb
--- /dev/null
+++ b/drivers/mfd/max597x.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device driver for regulators in MAX5970 and MAX5978 IC
+ *
+ * Copyright (c) 2022 9elements GmbH
+ *
+ * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/version.h>
+#include <linux/mfd/max597x.h>
+
+static const struct regmap_config max597x_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = MAX_REGISTERS,
+};
+
+static const struct mfd_cell max597x_devs[] = {
+	{
+	 .name = "max597x-regulator",
+	 },
+	{
+	 .name = "max597x-iio",
+	 },
+	{
+	 .name = "max597x-led",
+	 },
+};
+
+static int max597x_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+	struct max597x_data *max597x;
+	struct regmap *regmap;
+	enum max597x_chip_type chip = id->driver_data;
+
+	max597x =
+	    devm_kzalloc(&i2c->dev, sizeof(struct max597x_data), GFP_KERNEL);
+	switch (chip) {
+	case MAX597x_TYPE_MAX5970:
+		max597x->num_switches = 2;
+		break;
+	case MAX597x_TYPE_MAX5978:
+		max597x->num_switches = 1;
+		break;
+	}
+
+	regmap = devm_regmap_init_i2c(i2c, &max597x_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&i2c->dev, "No regmap\n");
+		return -EINVAL;
+	}
+	max597x->regmap = regmap;
+	max597x->irq = i2c->irq;
+	max597x->dev = &i2c->dev;
+	i2c_set_clientdata(i2c, max597x);
+
+	return devm_mfd_add_devices(max597x->dev, PLATFORM_DEVID_AUTO,
+				    max597x_devs, ARRAY_SIZE(max597x_devs),
+				    NULL, 0, NULL);
+}
+
+static const struct i2c_device_id max597x_table[] = {
+	{.name = "max5970", MAX597x_TYPE_MAX5970},
+	{.name = "max5978", MAX597x_TYPE_MAX5978},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, max597x_table);
+
+static const struct of_device_id max597x_of_match[] = {
+	{	.compatible = "maxim,max5970",
+		.data = (void *)MAX597x_TYPE_MAX5970
+	},
+	{	.compatible = "maxim,max5978",
+		.data = (void *)MAX597x_TYPE_MAX5978
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, max597x_of_match);
+
+static struct i2c_driver max597x_driver = {
+	.id_table = max597x_table,
+	.driver = {
+		   .name = "max597x",
+		   .of_match_table = of_match_ptr(max597x_of_match),
+		   },
+	.probe = max597x_probe,
+};
+
+module_i2c_driver(max597x_driver);
+
+MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
+MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/max597x.h b/include/linux/mfd/max597x.h
new file mode 100644
index 000000000000..ac7e9c84d06c
--- /dev/null
+++ b/include/linux/mfd/max597x.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Device driver for regulators in MAX5970 and MAX5978 IC
+ *
+ * Copyright (c) 2022 9elements GmbH
+ *
+ * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
+ */
+
+#ifndef _MAX597X_H
+#define _MAX597X_H
+
+#include <linux/regmap.h>
+
+#define MAX5970_NUM_SWITCHES 2
+#define MAX5978_NUM_SWITCHES 1
+#define MAX597X_NUM_LEDS     4
+
+struct max597x_data {
+	struct device *dev;
+	int irq;
+	int num_switches;
+	struct regmap *regmap;
+	u32 irng[MAX5970_NUM_SWITCHES];
+	u32 mon_rng[MAX5970_NUM_SWITCHES];
+	u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES];
+};
+
+enum max597x_chip_type {
+	MAX597x_TYPE_MAX5978 = 1,
+	MAX597x_TYPE_MAX5970,
+};
+
+#define MAX5970_REG_CURRENT_L(ch)		(0x01 + (ch) * 4)
+#define MAX5970_REG_CURRENT_H(ch)		(0x00 + (ch) * 4)
+#define MAX5970_REG_VOLTAGE_L(ch)		(0x03 + (ch) * 4)
+#define MAX5970_REG_VOLTAGE_H(ch)		(0x02 + (ch) * 4)
+#define MAX5970_REG_MON_RANGE			0x18
+#define  MAX5970_MON_MASK			0x3
+#define  MAX5970_MON(reg, ch) \
+	(((reg) >> ((ch) * 2)) & MAX5970_MON_MASK)
+#define  MAX5970_MON_MAX_RANGE_UV		16000000
+
+#define MAX5970_REG_CH_UV_WARN_H(ch)		(0x1A + (ch) * 10)
+#define MAX5970_REG_CH_UV_WARN_L(ch)		(0x1B + (ch) * 10)
+#define MAX5970_REG_CH_UV_CRIT_H(ch)		(0x1C + (ch) * 10)
+#define MAX5970_REG_CH_UV_CRIT_L(ch)		(0x1D + (ch) * 10)
+#define MAX5970_REG_CH_OV_WARN_H(ch)		(0x1E + (ch) * 10)
+#define MAX5970_REG_CH_OV_WARN_L(ch)		(0x1F + (ch) * 10)
+#define MAX5970_REG_CH_OV_CRIT_H(ch)		(0x20 + (ch) * 10)
+#define MAX5970_REG_CH_OV_CRIT_L(ch)		(0x21 + (ch) * 10)
+
+#define  MAX5970_VAL2REG_H(x)		(((x) >> 2) & 0xFF)
+#define  MAX5970_VAL2REG_L(x)		((x) & 0x3)
+
+#define MAX5970_REG_DAC_FAST(ch)	(0x2E + (ch))
+
+#define MAX5970_FAST2SLOW_RATIO		200
+
+#define MAX5970_REG_STATUS0		0x31
+#define  MAX5970_CB_IFAULTF(ch)		(1 << (ch))
+#define  MAX5970_CB_IFAULTS(ch)		(1 << ((ch) + 4))
+
+#define MAX5970_REG_STATUS1		0x32
+#define  STATUS1_PROT_MASK		0x3
+#define  STATUS1_PROT(reg) \
+	(((reg) >> 6) & STATUS1_PROT_MASK)
+#define  STATUS1_PROT_SHUTDOWN		0
+#define  STATUS1_PROT_CLEAR_PG		1
+#define  STATUS1_PROT_ALERT_ONLY	2
+
+#define MAX5970_REG_STATUS2		0x33
+#define  MAX5970_IRNG_MASK		0x3
+#define  MAX5970_IRNG(reg, ch) \
+	(((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK)
+
+#define MAX5970_REG_STATUS3		0x34
+#define  MAX5970_STATUS3_ALERT		BIT(4)
+#define  MAX5970_STATUS3_PG(ch)		BIT(ch)
+
+#define MAX5970_REG_FAULT0		0x35
+#define  UV_STATUS_WARN(ch)		(1 << (ch))
+#define  UV_STATUS_CRIT(ch)		(1 << ((ch) + 4))
+
+#define MAX5970_REG_FAULT1		0x36
+#define  OV_STATUS_WARN(ch)		(1 << (ch))
+#define  OV_STATUS_CRIT(ch)		(1 << ((ch) + 4))
+
+#define MAX5970_REG_FAULT2		0x37
+#define  OC_STATUS_WARN(ch)		(1 << (ch))
+
+#define MAX5970_REG_CHXEN		0x3b
+#define  CHXEN(ch)			(3 << ((ch) * 2))
+
+#define MAX5970_REG_LED_FLASH		0x43
+
+#define MAX_REGISTERS			0x49
+#define ADC_MASK			0x3FF
+
+#endif				/* _MAX597X_H */
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/5] regulator: max597x: Add support for max597x regulator
  2022-07-07 13:41 [PATCH v2 0/5] mfd: max597x: Add support for max597x Naresh Solanki
  2022-07-07 13:41 ` [PATCH v2 1/5] dt-bindings: mfd: Add bindings for MAX5970 and MAX5978 Naresh Solanki
  2022-07-07 13:41 ` [PATCH v2 2/5] mfd: max597x: Add support " Naresh Solanki
@ 2022-07-07 13:41 ` Naresh Solanki
  2022-07-07 13:43   ` Mark Brown
  2022-07-07 13:41 ` [PATCH v2 4/5] iio: max597x: Add support for max597x Naresh Solanki
  2022-07-07 13:41 ` [PATCH v2 5/5] leds: " Naresh Solanki
  4 siblings, 1 reply; 9+ messages in thread
From: Naresh Solanki @ 2022-07-07 13:41 UTC (permalink / raw)
  To: linux-kernel, Liam Girdwood, Mark Brown
  Cc: Patrick Rudolph, Marcello Sylvester Bauer, Naresh Solanki

From: Patrick Rudolph <patrick.rudolph@9elements.com>

max597x is hot swap controller.
This regulator driver controls the same & also configures fault
protection features supported by the chip.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com>
---
 drivers/regulator/Kconfig             |  10 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/max597x-regulator.c | 506 ++++++++++++++++++++++++++
 3 files changed, 517 insertions(+)
 create mode 100644 drivers/regulator/max597x-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index cbe0f96ca342..e26ad891bb03 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -546,6 +546,16 @@ config REGULATOR_MAX1586
 	  regulator via I2C bus. The provided regulator is suitable
 	  for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
 
+config REGULATOR_MAX597X
+	tristate "Maxim 597x power switch and monitor"
+	depends on I2C
+	depends on OF
+	depends MFD_MAX597X
+	help
+	  This driver controls a Maxim 5970/5978 switch via I2C bus.
+	  The MAX5970/5978 is a smart switch with no output regulation, but
+	  fault protection and voltage and current monitoring capabilities.
+
 config REGULATOR_MAX77620
 	tristate "Maxim 77620/MAX20024 voltage regulator"
 	depends on MFD_MAX77620 || COMPILE_TEST
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 8d3ee8b6d41d..4a8a42998561 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
 obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
 obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
+obj-$(CONFIG_REGULATOR_MAX597X) += max597x-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
 obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o
 obj-$(CONFIG_REGULATOR_MAX8649)	+= max8649.o
diff --git a/drivers/regulator/max597x-regulator.c b/drivers/regulator/max597x-regulator.c
new file mode 100644
index 000000000000..f95acd1c5e3a
--- /dev/null
+++ b/drivers/regulator/max597x-regulator.c
@@ -0,0 +1,506 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device driver for regulators in MAX5970 and MAX5978 IC
+ *
+ * Copyright (c) 2022 9elements GmbH
+ *
+ * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/max597x.h>
+
+struct max597x_regulator {
+	int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA;
+	struct regmap *regmap;
+};
+
+enum max597x_regulator_id {
+	MAX597X_SW0,
+	MAX597X_SW1,
+};
+
+static int max597x_uvp_ovp_check_mode(struct regulator_dev *rdev, int severity)
+{
+	int ret, reg;
+
+	/* Status1 register contains the soft strap values sampled at POR */
+	ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS1, &reg);
+	if (ret)
+		return ret;
+
+	/* Check soft straps match requested mode */
+	if (severity == REGULATOR_SEVERITY_PROT) {
+		if (STATUS1_PROT(reg) != STATUS1_PROT_SHUTDOWN)
+			return -EOPNOTSUPP;
+
+		return 0;
+	}
+	if (STATUS1_PROT(reg) == STATUS1_PROT_SHUTDOWN)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity,
+			  bool enable, bool overvoltage)
+{
+	int off_h, off_l, reg, ret;
+	struct max597x_regulator *data = rdev_get_drvdata(rdev);
+	int channel = rdev_get_id(rdev);
+
+	if (overvoltage) {
+		if (severity == REGULATOR_SEVERITY_WARN) {
+			off_h = MAX5970_REG_CH_OV_WARN_H(channel);
+			off_l = MAX5970_REG_CH_OV_WARN_L(channel);
+		} else {
+			off_h = MAX5970_REG_CH_OV_CRIT_H(channel);
+			off_l = MAX5970_REG_CH_OV_CRIT_L(channel);
+		}
+	} else {
+		if (severity == REGULATOR_SEVERITY_WARN) {
+			off_h = MAX5970_REG_CH_UV_WARN_H(channel);
+			off_l = MAX5970_REG_CH_UV_WARN_L(channel);
+		} else {
+			off_h = MAX5970_REG_CH_UV_CRIT_H(channel);
+			off_l = MAX5970_REG_CH_UV_CRIT_L(channel);
+		}
+	}
+
+	if (enable)
+		/* reg = ADC_MASK * (lim_uV / 1000000) / (data->mon_rng / 1000000) */
+		reg = ADC_MASK * lim_uV / data->mon_rng;
+	else
+		reg = 0;
+
+	ret = regmap_write(rdev->regmap, off_h, MAX5970_VAL2REG_H(reg));
+	if (ret)
+		return ret;
+
+	ret = regmap_write(rdev->regmap, off_l, MAX5970_VAL2REG_L(reg));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int max597x_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity,
+			   bool enable)
+{
+	int ret;
+
+	/*
+	 * MAX5970 has enable control as a special value in limit reg. Can't
+	 * set limit but keep feature disabled or enable W/O given limit.
+	 */
+	if ((lim_uV && !enable) || (!lim_uV && enable))
+		return -EINVAL;
+
+	ret = max597x_uvp_ovp_check_mode(rdev, severity);
+	if (ret)
+		return ret;
+
+	return max597x_set_vp(rdev, lim_uV, severity, enable, false);
+}
+
+static int max597x_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity,
+			   bool enable)
+{
+	int ret;
+
+	/*
+	 * MAX5970 has enable control as a special value in limit reg. Can't
+	 * set limit but keep feature disabled or enable W/O given limit.
+	 */
+	if ((lim_uV && !enable) || (!lim_uV && enable))
+		return -EINVAL;
+
+	ret = max597x_uvp_ovp_check_mode(rdev, severity);
+	if (ret)
+		return ret;
+
+	return max597x_set_vp(rdev, lim_uV, severity, enable, true);
+}
+
+static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA,
+			   int severity, bool enable)
+{
+	int ret, val, reg;
+	unsigned int vthst, vthfst;
+
+	struct max597x_regulator *data = rdev_get_drvdata(rdev);
+	int rdev_id = rdev_get_id(rdev);
+	/*
+	 * MAX5970 doesn't has enable control for ocp.
+	 * If limit is specified but enable is not set then hold the value in
+	 * variable & later use it when ocp needs to be enabled.
+	 */
+	if (lim_uA != 0 && lim_uA != data->lim_uA)
+		data->lim_uA = lim_uA;
+
+	if (severity != REGULATOR_SEVERITY_PROT)
+		return -EINVAL;
+
+	if (enable) {
+
+		/* Calc Vtrip threshold in uV. */
+		vthst =
+		    div_u64(mul_u32_u32(data->shunt_micro_ohms, data->lim_uA),
+			    1000000);
+
+		/*
+		 * As recommended in datasheed, add 20% margin to avoid
+		 * spurious event & passive component tolerance.
+		 */
+		vthst = div_u64(mul_u32_u32(vthst, 120), 100);
+
+		/* Calc fast Vtrip threshold in uV */
+		vthfst = vthst * (MAX5970_FAST2SLOW_RATIO / 100);
+
+		if (vthfst > data->irng) {
+			dev_err(&rdev->dev, "Current limit out of range\n");
+			return -EINVAL;
+		}
+		/* Fast trip threshold to be programmed */
+		val = div_u64(mul_u32_u32(0xFF, vthfst), data->irng);
+	} else
+		/*
+		 * Since there is no option to disable ocp, set limit to max
+		 * value
+		 */
+		val = 0xFF;
+
+	reg = MAX5970_REG_DAC_FAST(rdev_id);
+	ret = regmap_write(rdev->regmap, reg, val);
+
+	return ret;
+}
+
+static int max597x_get_status(struct regulator_dev *rdev)
+{
+	int val, ret;
+
+	ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS3, &val);
+	if (ret)
+		return REGULATOR_FAILED_RETRY;
+
+	if (val & MAX5970_STATUS3_ALERT)
+		return REGULATOR_STATUS_ERROR;
+
+	ret = regulator_is_enabled_regmap(rdev);
+	if (ret < 0)
+		return ret;
+
+	if (ret)
+		return REGULATOR_STATUS_ON;
+
+	return REGULATOR_STATUS_OFF;
+}
+
+static const struct regulator_ops max597x_switch_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.get_status = max597x_get_status,
+	.set_over_voltage_protection = max597x_set_ovp,
+	.set_under_voltage_protection = max597x_set_uvp,
+	.set_over_current_protection = max597x_set_ocp,
+};
+
+static int max597x_dt_parse(struct device_node *np,
+			    const struct regulator_desc *desc,
+			    struct regulator_config *cfg)
+{
+	struct max597x_regulator *data = cfg->driver_data;
+	int ret = 0;
+
+	ret =
+	    of_property_read_u32(np, "shunt-resistor-micro-ohms",
+				 &data->shunt_micro_ohms);
+	if (ret < 0)
+		dev_err(cfg->dev,
+			"property 'shunt-resistor-micro-ohms' not found, err %d\n",
+			ret);
+	return ret;
+
+}
+
+#define MAX597X_SWITCH(_ID, _ereg, _chan, _supply) {     \
+	.name            = #_ID,                         \
+	.of_match        = of_match_ptr(#_ID),           \
+	.ops             = &max597x_switch_ops,          \
+	.regulators_node = of_match_ptr("regulators"),   \
+	.type            = REGULATOR_VOLTAGE,            \
+	.id              = MAX597X_##_ID,                \
+	.owner           = THIS_MODULE,                  \
+	.supply_name     = _supply,                      \
+	.enable_reg      = _ereg,                        \
+	.enable_mask     = CHXEN((_chan)),               \
+	.of_parse_cb	 = max597x_dt_parse,		 \
+}
+
+static const struct regulator_desc regulators[] = {
+	MAX597X_SWITCH(SW0, MAX5970_REG_CHXEN, 0, "vss1"),
+	MAX597X_SWITCH(SW1, MAX5970_REG_CHXEN, 1, "vss2"),
+};
+
+static int max597x_regmap_read_clear(struct regmap *map, unsigned int reg,
+				     unsigned int *val)
+{
+	int ret;
+
+	ret = regmap_read(map, reg, val);
+	if (ret)
+		return ret;
+
+	if (*val)
+		return regmap_write(map, reg, *val);
+
+	return 0;
+}
+
+static int max597x_irq_handler(int irq, struct regulator_irq_data *rid,
+			       unsigned long *dev_mask)
+{
+	struct regulator_err_state *stat;
+	struct max597x_regulator *d = (struct max597x_regulator *)rid->data;
+	int val, ret, i;
+
+	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val);
+	if (ret)
+		return REGULATOR_FAILED_RETRY;
+
+	*dev_mask = 0;
+	for (i = 0; i < d->num_switches; i++) {
+		stat = &rid->states[i];
+		stat->notifs = 0;
+		stat->errors = 0;
+	}
+
+	for (i = 0; i < d->num_switches; i++) {
+		stat = &rid->states[i];
+
+		if (val & UV_STATUS_CRIT(i)) {
+			*dev_mask |= 1 << i;
+			stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE;
+			stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE;
+		} else if (val & UV_STATUS_WARN(i)) {
+			*dev_mask |= 1 << i;
+			stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE_WARN;
+			stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE_WARN;
+		}
+	}
+
+	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT1, &val);
+	if (ret)
+		return REGULATOR_FAILED_RETRY;
+
+	for (i = 0; i < d->num_switches; i++) {
+		stat = &rid->states[i];
+
+		if (val & OV_STATUS_CRIT(i)) {
+			*dev_mask |= 1 << i;
+			stat->notifs |= REGULATOR_EVENT_REGULATION_OUT;
+			stat->errors |= REGULATOR_ERROR_REGULATION_OUT;
+		} else if (val & OV_STATUS_WARN(i)) {
+			*dev_mask |= 1 << i;
+			stat->notifs |= REGULATOR_EVENT_OVER_VOLTAGE_WARN;
+			stat->errors |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;
+		}
+	}
+
+	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT2, &val);
+	if (ret)
+		return REGULATOR_FAILED_RETRY;
+
+	for (i = 0; i < d->num_switches; i++) {
+		stat = &rid->states[i];
+
+		if (val & OC_STATUS_WARN(i)) {
+			*dev_mask |= 1 << i;
+			stat->notifs |= REGULATOR_EVENT_OVER_CURRENT_WARN;
+			stat->errors |= REGULATOR_ERROR_OVER_CURRENT_WARN;
+		}
+	}
+
+	ret = regmap_read(d->regmap, MAX5970_REG_STATUS0, &val);
+	if (ret)
+		return REGULATOR_FAILED_RETRY;
+
+	for (i = 0; i < d->num_switches; i++) {
+		stat = &rid->states[i];
+
+		if ((val & MAX5970_CB_IFAULTF(i))
+		    || (val & MAX5970_CB_IFAULTS(i))) {
+			*dev_mask |= 1 << i;
+			stat->notifs |=
+			    REGULATOR_EVENT_OVER_CURRENT |
+			    REGULATOR_EVENT_DISABLE;
+			stat->errors |=
+			    REGULATOR_ERROR_OVER_CURRENT | REGULATOR_ERROR_FAIL;
+
+			/* Clear the sub-IRQ status */
+			regulator_disable_regmap(stat->rdev);
+		}
+	}
+	return 0;
+}
+
+static const struct regmap_config max597x_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = MAX_REGISTERS,
+};
+
+static int max597x_adc_range(struct regmap *regmap, const int ch,
+			     u32 *irng, u32 *mon_rng)
+{
+	unsigned int reg;
+	int ret;
+
+	/* Decode current ADC range */
+	ret = regmap_read(regmap, MAX5970_REG_STATUS2, &reg);
+	if (ret)
+		return ret;
+	switch (MAX5970_IRNG(reg, ch)) {
+	case 0:
+		*irng = 100000;	/* 100 mV */
+		break;
+	case 1:
+		*irng = 50000;	/* 50 mV */
+		break;
+	case 2:
+		*irng = 25000;	/* 25 mV */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Decode current voltage monitor range */
+	ret = regmap_read(regmap, MAX5970_REG_MON_RANGE, &reg);
+	if (ret)
+		return ret;
+
+	*mon_rng = MAX5970_MON_MAX_RANGE_UV >> MAX5970_MON(reg, ch);
+
+	return 0;
+}
+
+static int max597x_setup_irq(struct device *dev,
+			     int irq,
+			     struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES],
+			     int num_switches, struct max597x_regulator *data)
+{
+	struct regulator_irq_desc max597x_notif = {
+		.name = "max597x-irq",
+		.map_event = max597x_irq_handler,
+		.data = data,
+	};
+	int errs = REGULATOR_ERROR_UNDER_VOLTAGE |
+	    REGULATOR_ERROR_UNDER_VOLTAGE_WARN |
+	    REGULATOR_ERROR_OVER_VOLTAGE_WARN |
+	    REGULATOR_ERROR_REGULATION_OUT |
+	    REGULATOR_ERROR_OVER_CURRENT |
+	    REGULATOR_ERROR_OVER_CURRENT_WARN | REGULATOR_ERROR_FAIL;
+	void *irq_helper;
+
+	/* Register notifiers - can fail if IRQ is not given */
+	irq_helper = devm_regulator_irq_helper(dev, &max597x_notif,
+					       irq, 0, errs, NULL,
+					       &rdevs[0], num_switches);
+	if (IS_ERR(irq_helper)) {
+		if (PTR_ERR(irq_helper) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+
+		dev_warn(dev, "IRQ disabled %pe\n", irq_helper);
+	}
+
+	return 0;
+}
+
+static int max597x_regulator_probe(struct platform_device *pdev)
+{
+
+
+	struct max597x_data *max597x = dev_get_drvdata(pdev->dev.parent);
+	struct max597x_regulator *data;
+
+	struct regulator_config config = { };
+	struct regulator_dev *rdev;
+	struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES];
+	int num_switches = max597x->num_switches;
+	int ret, i;
+
+	for (i = 0; i < num_switches; i++) {
+		data =
+		    devm_kzalloc(max597x->dev, sizeof(struct max597x_regulator),
+				 GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+
+		data->num_switches = num_switches;
+		data->regmap = max597x->regmap;
+
+		if (ret < 0)
+			return ret;
+
+		ret = max597x_adc_range(data->regmap, i, &max597x->irng[i], &max597x->mon_rng[i]);
+		if (ret < 0)
+			return ret;
+
+		data->irng = max597x->irng[i];
+		data->mon_rng = max597x->mon_rng[i];
+
+		config.dev = max597x->dev;
+		config.driver_data = (void *)data;
+		config.regmap = data->regmap;
+		rdev = devm_regulator_register(max597x->dev,
+					       &regulators[i], &config);
+		if (IS_ERR(rdev)) {
+			dev_err(max597x->dev, "failed to register regulator %s\n",
+				regulators[i].name);
+			return PTR_ERR(rdev);
+		}
+		rdevs[i] = rdev;
+		max597x->shunt_micro_ohms[i] = data->shunt_micro_ohms;
+	}
+
+	if (max597x->irq) {
+		ret =
+		    max597x_setup_irq(max597x->dev, max597x->irq, rdevs, num_switches,
+				      data);
+		if (ret) {
+			dev_err(max597x->dev, "IRQ setup failed");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static struct platform_driver max597x_regulator_driver = {
+	.driver = {
+		.name = "max597x-regulator",
+	},
+	.probe = max597x_regulator_probe,
+};
+
+module_platform_driver(max597x_regulator_driver);
+
+
+MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
+MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/5] iio: max597x: Add support for max597x
  2022-07-07 13:41 [PATCH v2 0/5] mfd: max597x: Add support for max597x Naresh Solanki
                   ` (2 preceding siblings ...)
  2022-07-07 13:41 ` [PATCH v2 3/5] regulator: max597x: Add support for max597x regulator Naresh Solanki
@ 2022-07-07 13:41 ` Naresh Solanki
  2022-07-07 14:38   ` kernel test robot
  2022-07-07 13:41 ` [PATCH v2 5/5] leds: " Naresh Solanki
  4 siblings, 1 reply; 9+ messages in thread
From: Naresh Solanki @ 2022-07-07 13:41 UTC (permalink / raw)
  To: linux-kernel; +Cc: Patrick Rudolph, Naresh Solanki

From: Patrick Rudolph <patrick.rudolph@9elements.com>

max597x has 10bit ADC for voltage & current monitoring.
Use iio framework to expose the same in sysfs.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com>
---
 drivers/iio/adc/Kconfig       |   9 ++
 drivers/iio/adc/Makefile      |   1 +
 drivers/iio/adc/max597x-iio.c | 156 ++++++++++++++++++++++++++++++++++
 3 files changed, 166 insertions(+)
 create mode 100644 drivers/iio/adc/max597x-iio.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 48ace7412874..8d23c81d4105 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -683,6 +683,15 @@ config MAX1363
 	  To compile this driver as a module, choose M here: the module will be
 	  called max1363.
 
+config MAX597X_IIO
+	tristate "Maxim 597x power switch and monitor"
+	depends on I2C
+	depends on OF
+	depends MFD_MAX597X
+	help
+	  This driver exposes Maxim 5970/5978 voltage/current monitoring
+	  interface using iio framework.
+
 config MAX9611
 	tristate "Maxim max9611/max9612 ADC driver"
 	depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 39d806f6d457..f8cb5a30a946 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_MAX11100) += max11100.o
 obj-$(CONFIG_MAX1118) += max1118.o
 obj-$(CONFIG_MAX1241) += max1241.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MAX597X_IIO) += max597x-iio.o
 obj-$(CONFIG_MAX9611) += max9611.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_MCP3422) += mcp3422.o
diff --git a/drivers/iio/adc/max597x-iio.c b/drivers/iio/adc/max597x-iio.c
new file mode 100644
index 000000000000..de0ea762c5c8
--- /dev/null
+++ b/drivers/iio/adc/max597x-iio.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device driver for regulators in MAX5970 and MAX5978 IC
+ *
+ * Copyright (c) 2022 9elements GmbH
+ *
+ * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/iio/iio.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <linux/mfd/max597x.h>
+#include <linux/regmap.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+
+struct max597x_iio {
+	struct regmap *regmap;
+	int shunt_micro_ohms[MAX5970_NUM_SWITCHES];
+	unsigned int irng[MAX5970_NUM_SWITCHES];
+	unsigned int mon_rng[MAX5970_NUM_SWITCHES];
+};
+
+#define MAX597X_ADC_CHANNEL(_idx, _type) {			\
+	.type = IIO_ ## _type,					\
+	.indexed = 1,						\
+	.channel = (_idx),					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
+			      BIT(IIO_CHAN_INFO_SCALE),		\
+	.address = MAX5970_REG_ ## _type ## _L(_idx),		\
+}
+
+static const struct iio_chan_spec max5978_adc_iio_channels[] = {
+	MAX597X_ADC_CHANNEL(0, VOLTAGE),
+	MAX597X_ADC_CHANNEL(0, CURRENT),
+};
+
+static const struct iio_chan_spec max5970_adc_iio_channels[] = {
+	MAX597X_ADC_CHANNEL(0, VOLTAGE),
+	MAX597X_ADC_CHANNEL(0, CURRENT),
+	MAX597X_ADC_CHANNEL(1, VOLTAGE),
+	MAX597X_ADC_CHANNEL(1, CURRENT),
+};
+
+static int max597x_iio_read_raw(struct iio_dev *iio_dev,
+				struct iio_chan_spec const *chan,
+				int *val, int *val2, long info)
+{
+	int ret;
+	struct max597x_iio *data = iio_priv(iio_dev);
+	unsigned int reg_l, reg_h;
+
+	switch (info) {
+	case IIO_CHAN_INFO_RAW:
+		ret = regmap_read(data->regmap, chan->address, &reg_l);
+		if (ret < 0)
+			return ret;
+		ret = regmap_read(data->regmap, chan->address - 1, &reg_h);
+		if (ret < 0)
+			return ret;
+		*val = (reg_h << 2) | (reg_l & 3);
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+
+		switch (chan->address) {
+		case MAX5970_REG_CURRENT_L(0):
+			fallthrough;
+		case MAX5970_REG_CURRENT_L(1):
+			/* in A, convert to mA */
+			*val = data->irng[chan->channel] * 1000;
+			*val2 =
+			    data->shunt_micro_ohms[chan->channel] * ADC_MASK;
+			return IIO_VAL_FRACTIONAL;
+
+		case MAX5970_REG_VOLTAGE_L(0):
+			fallthrough;
+		case MAX5970_REG_VOLTAGE_L(1):
+			/* in uV, convert to mV */
+			*val = data->mon_rng[chan->channel];
+			*val2 = ADC_MASK * 1000;
+			return IIO_VAL_FRACTIONAL;
+		}
+
+		break;
+	}
+	return -EINVAL;
+}
+
+static const struct iio_info max597x_adc_iio_info = {
+	.read_raw = &max597x_iio_read_raw,
+};
+
+static int max597x_iio_probe(struct platform_device *pdev)
+{
+	struct max597x_data *max597x = dev_get_drvdata(pdev->dev.parent);
+	struct iio_dev *indio_dev;
+	struct max597x_iio *priv;
+	int ret, i;
+
+	/* registering iio */
+	indio_dev = devm_iio_device_alloc(max597x->dev, sizeof(*priv));
+	if (!indio_dev) {
+		dev_err(max597x->dev, "failed allocating iio device\n");
+		return -ENOMEM;
+	}
+	indio_dev->name = dev_name(max597x->dev);
+	indio_dev->info = &max597x_adc_iio_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	switch (max597x->num_switches) {
+	case MAX597x_TYPE_MAX5970:
+		indio_dev->channels = max5970_adc_iio_channels;
+		indio_dev->num_channels = ARRAY_SIZE(max5970_adc_iio_channels);
+		break;
+	case MAX597x_TYPE_MAX5978:
+		indio_dev->channels = max5978_adc_iio_channels;
+		indio_dev->num_channels = ARRAY_SIZE(max5978_adc_iio_channels);
+		break;
+	}
+
+	priv = iio_priv(indio_dev);
+	priv->regmap = max597x->regmap;
+	for (i = 0; i < indio_dev->num_channels; i++) {
+		priv->irng[i] = max597x->irng[i];
+		priv->mon_rng[i] = max597x->mon_rng[i];
+		priv->shunt_micro_ohms[i] = max597x->shunt_micro_ohms[i];
+	}
+
+	ret = devm_iio_device_register(max597x->dev, indio_dev);
+	if (ret)
+		dev_err(max597x->dev, "could not register iio device");
+
+	return ret;
+
+}
+
+static struct platform_driver max597x_iio_driver = {
+	.driver = {
+		.name = "max597x-iio",
+	},
+	.probe = max597x_iio_probe,
+};
+
+module_platform_driver(max597x_iio_driver);
+
+
+MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
+MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 5/5] leds: max597x: Add support for max597x
  2022-07-07 13:41 [PATCH v2 0/5] mfd: max597x: Add support for max597x Naresh Solanki
                   ` (3 preceding siblings ...)
  2022-07-07 13:41 ` [PATCH v2 4/5] iio: max597x: Add support for max597x Naresh Solanki
@ 2022-07-07 13:41 ` Naresh Solanki
  4 siblings, 0 replies; 9+ messages in thread
From: Naresh Solanki @ 2022-07-07 13:41 UTC (permalink / raw)
  To: linux-kernel, Pavel Machek; +Cc: Patrick Rudolph, Naresh Solanki

From: Patrick Rudolph <patrick.rudolph@9elements.com>

max597x is hot swap controller with indication led support.
This driver uses DT property to configure led during boot time &
also provide the led control in sysfs.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com>
---
 drivers/leds/Kconfig        |  10 +++
 drivers/leds/Makefile       |   1 +
 drivers/leds/leds-max597x.c | 130 ++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+)
 create mode 100644 drivers/leds/leds-max597x.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index a49979f41eee..64070cadac31 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -598,6 +598,16 @@ config LEDS_ADP5520
 	  To compile this driver as a module, choose M here: the module will
 	  be called leds-adp5520.
 
+config LEDS_MAX597X
+	tristate "Maxim 597x leds"
+	depends on I2C
+	depends on OF
+	depends on LEDS_CLASS
+	depends MFD_MAX597X
+	help
+	  This driver controls a Maxim 5970/5978 indication led via I2C bus.
+	  The MAX5970/5978 is a smart switch with 4 indication leds
+
 config LEDS_MC13783
 	tristate "LED Support for MC13XXX PMIC"
 	depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 4fd2f92cd198..c44b0e9559ab 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_LEDS_LP8501)		+= leds-lp8501.o
 obj-$(CONFIG_LEDS_LP8788)		+= leds-lp8788.o
 obj-$(CONFIG_LEDS_LP8860)		+= leds-lp8860.o
 obj-$(CONFIG_LEDS_LT3593)		+= leds-lt3593.o
+obj-$(CONFIG_LEDS_MAX597X)		+= leds-max597x.o
 obj-$(CONFIG_LEDS_MAX77650)		+= leds-max77650.o
 obj-$(CONFIG_LEDS_MAX8997)		+= leds-max8997.o
 obj-$(CONFIG_LEDS_MC13783)		+= leds-mc13783.o
diff --git a/drivers/leds/leds-max597x.c b/drivers/leds/leds-max597x.c
new file mode 100644
index 000000000000..645d6cdcfa34
--- /dev/null
+++ b/drivers/leds/leds-max597x.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device driver for regulators in MAX5970 and MAX5978 IC
+ *
+ * Copyright (c) 2022 9elements GmbH
+ *
+ * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+#include <linux/mfd/max597x.h>
+#include <linux/regmap.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+
+struct max597x_led {
+	struct regmap *regmap;
+	struct led_classdev led;
+	unsigned int index;
+};
+
+static int max597x_led_set_brightness(struct led_classdev *cdev,
+				      enum led_brightness brightness)
+{
+	struct max597x_led *led = cdev->driver_data;
+	int ret;
+
+	if (!led || !led->regmap)
+		return -1;
+
+	ret = regmap_update_bits(led->regmap, MAX5970_REG_LED_FLASH,
+				 1 << led->index, ~brightness << led->index);
+	if (ret < 0)
+		dev_err(cdev->dev, "failed to set brightness %d\n", ret);
+	return ret;
+}
+
+static int max597x_led(struct max597x_data *max597x, struct device_node *nc, u32 reg)
+{
+	struct max597x_led *led;
+	const char *state;
+	int ret = 0;
+
+	led = devm_kzalloc(max597x->dev, sizeof(struct max597x_led),
+				   GFP_KERNEL);
+	if (!led)
+		return -ENOMEM;
+
+	if (of_property_read_string(nc, "label", &led->led.name))
+		led->led.name = nc->name;
+
+	led->led.max_brightness = 1;
+	led->led.brightness_set_blocking = max597x_led_set_brightness;
+	led->led.default_trigger = "none";
+	led->index = reg;
+	led->regmap = max597x->regmap;
+	ret = led_classdev_register(max597x->dev, &led->led);
+	if (ret) {
+		dev_err(max597x->dev, "Error in initializing led %s", led->led.name);
+		devm_kfree(max597x->dev, led);
+		return ret;
+	}
+	led->led.driver_data = led;
+	led->led.dev = max597x->dev;
+	if (!of_property_read_string(nc, "default-state", &state)) {
+		if (!strcmp(state, "on")) {
+			led->led.brightness = 1;
+			led_set_brightness(&led->led, led->led.brightness);
+		}
+	}
+	return 0;
+}
+
+static int max597x_led_probe(struct platform_device *pdev)
+{
+
+
+	struct max597x_data *max597x = dev_get_drvdata(pdev->dev.parent);
+	struct device_node *np = dev_of_node(pdev->dev.parent);
+	struct device_node *led_node;
+	struct device_node *child;
+	int ret = 0;
+
+
+	led_node = of_get_child_by_name(np, "leds");
+	if (!led_node)
+		return -ENODEV;
+
+	for_each_available_child_of_node(led_node, child) {
+		u32 reg;
+
+		if (of_property_read_u32(child, "reg", &reg))
+			continue;
+
+		if (reg >= MAX597X_NUM_LEDS) {
+			dev_err(max597x->dev, "invalid LED (%u >= %d)\n", reg,
+				MAX597X_NUM_LEDS);
+			continue;
+		}
+
+		ret = max597x_led(max597x, child, reg);
+		if (ret < 0) {
+			of_node_put(child);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static struct platform_driver max597x_led_driver = {
+	.driver = {
+		.name = "max597x-led",
+	},
+	.probe = max597x_led_probe,
+};
+
+module_platform_driver(max597x_led_driver);
+
+
+MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
+MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/5] regulator: max597x: Add support for max597x regulator
  2022-07-07 13:41 ` [PATCH v2 3/5] regulator: max597x: Add support for max597x regulator Naresh Solanki
@ 2022-07-07 13:43   ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2022-07-07 13:43 UTC (permalink / raw)
  To: Naresh Solanki
  Cc: linux-kernel, Liam Girdwood, Patrick Rudolph,
	Marcello Sylvester Bauer

[-- Attachment #1: Type: text/plain, Size: 576 bytes --]

On Thu, Jul 07, 2022 at 03:41:39PM +0200, Naresh Solanki wrote:
> From: Patrick Rudolph <patrick.rudolph@9elements.com>
> 
> max597x is hot swap controller.
> This regulator driver controls the same & also configures fault
> protection features supported by the chip.

Please do not submit new versions of already applied patches, please
submit incremental updates to the existing code.  Modifying existing
commits creates problems for other users building on top of those
commits so it's best practice to only change pubished git commits if
absolutely essential.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/5] iio: max597x: Add support for max597x
  2022-07-07 13:41 ` [PATCH v2 4/5] iio: max597x: Add support for max597x Naresh Solanki
@ 2022-07-07 14:38   ` kernel test robot
  0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2022-07-07 14:38 UTC (permalink / raw)
  To: Naresh Solanki, linux-kernel; +Cc: kbuild-all, Patrick Rudolph, Naresh Solanki

Hi Naresh,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on 9f09069cde34dcd86f5ecf3a3139fd752020812f]

url:    https://github.com/intel-lab-lkp/linux/commits/Naresh-Solanki/mfd-max597x-Add-support-for-max597x/20220707-214501
base:   9f09069cde34dcd86f5ecf3a3139fd752020812f
config: um-i386_defconfig
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/22ea6b6b3fde4f8c03be1f1d0345f3d1fcc295e8
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Naresh-Solanki/mfd-max597x-Add-support-for-max597x/20220707-214501
        git checkout 22ea6b6b3fde4f8c03be1f1d0345f3d1fcc295e8
        make W=1 ARCH=um SUBARCH=i386 defconfig
        make W=1 ARCH=um SUBARCH=i386

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/regulator/Kconfig:554: syntax error
   drivers/regulator/Kconfig:553: invalid statement
   drivers/regulator/Kconfig:554: invalid statement
   drivers/regulator/Kconfig:555:warning: ignoring unsupported character '/'
   drivers/regulator/Kconfig:555:warning: ignoring unsupported character '.'
   drivers/regulator/Kconfig:555: unknown statement "This"
   drivers/regulator/Kconfig:556:warning: ignoring unsupported character '/'
   drivers/regulator/Kconfig:556:warning: ignoring unsupported character ','
   drivers/regulator/Kconfig:556: unknown statement "The"
   drivers/regulator/Kconfig:557:warning: ignoring unsupported character '.'
   drivers/regulator/Kconfig:557: unknown statement "fault"
>> drivers/iio/adc/Kconfig:691: syntax error
   drivers/iio/adc/Kconfig:690: invalid statement
   drivers/iio/adc/Kconfig:691: invalid statement
   drivers/iio/adc/Kconfig:692:warning: ignoring unsupported character '/'
   drivers/iio/adc/Kconfig:692:warning: ignoring unsupported character '/'
   drivers/iio/adc/Kconfig:692: unknown statement "This"
   drivers/iio/adc/Kconfig:693:warning: ignoring unsupported character '.'
   drivers/iio/adc/Kconfig:693: unknown statement "interface"
   make[2]: *** [scripts/kconfig/Makefile:87: defconfig] Error 1
   make[1]: *** [Makefile:629: defconfig] Error 2
   make: *** [Makefile:219: __sub-make] Error 2
   make: Target 'defconfig' not remade because of errors.
--
   drivers/regulator/Kconfig:554: syntax error
   drivers/regulator/Kconfig:553: invalid statement
   drivers/regulator/Kconfig:554: invalid statement
   drivers/regulator/Kconfig:555:warning: ignoring unsupported character '/'
   drivers/regulator/Kconfig:555:warning: ignoring unsupported character '.'
   drivers/regulator/Kconfig:555: unknown statement "This"
   drivers/regulator/Kconfig:556:warning: ignoring unsupported character '/'
   drivers/regulator/Kconfig:556:warning: ignoring unsupported character ','
   drivers/regulator/Kconfig:556: unknown statement "The"
   drivers/regulator/Kconfig:557:warning: ignoring unsupported character '.'
   drivers/regulator/Kconfig:557: unknown statement "fault"
>> drivers/iio/adc/Kconfig:691: syntax error
   drivers/iio/adc/Kconfig:690: invalid statement
   drivers/iio/adc/Kconfig:691: invalid statement
   drivers/iio/adc/Kconfig:692:warning: ignoring unsupported character '/'
   drivers/iio/adc/Kconfig:692:warning: ignoring unsupported character '/'
   drivers/iio/adc/Kconfig:692: unknown statement "This"
   drivers/iio/adc/Kconfig:693:warning: ignoring unsupported character '.'
   drivers/iio/adc/Kconfig:693: unknown statement "interface"
   make[2]: *** [scripts/kconfig/Makefile:77: oldconfig] Error 1
   make[1]: *** [Makefile:629: oldconfig] Error 2
   make: *** [Makefile:219: __sub-make] Error 2
   make: Target 'oldconfig' not remade because of errors.
--
   drivers/regulator/Kconfig:554: syntax error
   drivers/regulator/Kconfig:553: invalid statement
   drivers/regulator/Kconfig:554: invalid statement
   drivers/regulator/Kconfig:555:warning: ignoring unsupported character '/'
   drivers/regulator/Kconfig:555:warning: ignoring unsupported character '.'
   drivers/regulator/Kconfig:555: unknown statement "This"
   drivers/regulator/Kconfig:556:warning: ignoring unsupported character '/'
   drivers/regulator/Kconfig:556:warning: ignoring unsupported character ','
   drivers/regulator/Kconfig:556: unknown statement "The"
   drivers/regulator/Kconfig:557:warning: ignoring unsupported character '.'
   drivers/regulator/Kconfig:557: unknown statement "fault"
>> drivers/iio/adc/Kconfig:691: syntax error
   drivers/iio/adc/Kconfig:690: invalid statement
   drivers/iio/adc/Kconfig:691: invalid statement
   drivers/iio/adc/Kconfig:692:warning: ignoring unsupported character '/'
   drivers/iio/adc/Kconfig:692:warning: ignoring unsupported character '/'
   drivers/iio/adc/Kconfig:692: unknown statement "This"
   drivers/iio/adc/Kconfig:693:warning: ignoring unsupported character '.'
   drivers/iio/adc/Kconfig:693: unknown statement "interface"
   make[2]: *** [scripts/kconfig/Makefile:77: olddefconfig] Error 1
   make[1]: *** [Makefile:629: olddefconfig] Error 2
   make: *** [Makefile:219: __sub-make] Error 2
   make: Target 'olddefconfig' not remade because of errors.


vim +691 drivers/iio/adc/Kconfig

     8	
     9	config AB8500_GPADC
    10		bool "ST-Ericsson AB8500 GPADC driver"
    11		depends on AB8500_CORE && REGULATOR_AB8500
    12		default y
    13		help
    14		  AB8500 Analog Baseband, mixed signal integrated circuit GPADC
    15		  (General Purpose Analog to Digital Converter) driver used to monitor
    16		  internal voltages, convert accessory and battery, AC (charger, mains)
    17		  and USB voltages integral to the U8500 platform.
    18	
    19	config AD_SIGMA_DELTA
    20		tristate
    21		select IIO_BUFFER
    22		select IIO_TRIGGERED_BUFFER
    23	
    24	config AD7091R5
    25		tristate "Analog Devices AD7091R5 ADC Driver"
    26		depends on I2C
    27		select REGMAP_I2C
    28		help
    29		  Say yes here to build support for Analog Devices AD7091R-5 ADC.
    30	
    31	config AD7124
    32		tristate "Analog Devices AD7124 and similar sigma-delta ADCs driver"
    33		depends on SPI_MASTER
    34		select AD_SIGMA_DELTA
    35		help
    36		  Say yes here to build support for Analog Devices AD7124-4 and AD7124-8
    37		  SPI analog to digital converters (ADC).
    38	
    39		  To compile this driver as a module, choose M here: the module will be
    40		  called ad7124.
    41	
    42	config AD7192
    43		tristate "Analog Devices AD7190 AD7192 AD7193 AD7195 ADC driver"
    44		depends on SPI
    45		select AD_SIGMA_DELTA
    46		help
    47		  Say yes here to build support for Analog Devices AD7190,
    48		  AD7192, AD7193 or AD7195 SPI analog to digital converters (ADC).
    49		  If unsure, say N (but it's safe to say "Y").
    50	
    51		  To compile this driver as a module, choose M here: the
    52		  module will be called ad7192.
    53	
    54	config AD7266
    55		tristate "Analog Devices AD7265/AD7266 ADC driver"
    56		depends on SPI_MASTER
    57		select IIO_BUFFER
    58		select IIO_TRIGGER
    59		select IIO_TRIGGERED_BUFFER
    60		help
    61		  Say yes here to build support for Analog Devices AD7265 and AD7266
    62		  ADCs.
    63	
    64		  To compile this driver as a module, choose M here: the module will be
    65		  called ad7266.
    66	
    67	config AD7280
    68		tristate "Analog Devices AD7280A Lithium Ion Battery Monitoring System"
    69		depends on SPI
    70		select CRC8
    71		help
    72		  Say yes here to build support for Analog Devices AD7280A
    73		  Lithium Ion Battery Monitoring System.
    74	
    75		  To compile this driver as a module, choose M here: the
    76		  module will be called ad7280a
    77	
    78	config AD7291
    79		tristate "Analog Devices AD7291 ADC driver"
    80		depends on I2C
    81		help
    82		  Say yes here to build support for Analog Devices AD7291
    83		  8 Channel ADC with temperature sensor.
    84	
    85		  To compile this driver as a module, choose M here: the
    86		  module will be called ad7291.
    87	
    88	config AD7292
    89		tristate "Analog Devices AD7292 ADC driver"
    90		depends on SPI
    91		help
    92		  Say yes here to build support for Analog Devices AD7292
    93		  8 Channel ADC with temperature sensor.
    94	
    95		  To compile this driver as a module, choose M here: the
    96		  module will be called ad7292.
    97	
    98	config AD7298
    99		tristate "Analog Devices AD7298 ADC driver"
   100		depends on SPI
   101		select IIO_BUFFER
   102		select IIO_TRIGGERED_BUFFER
   103		help
   104		  Say yes here to build support for Analog Devices AD7298
   105		  8 Channel ADC with temperature sensor.
   106	
   107		  To compile this driver as a module, choose M here: the
   108		  module will be called ad7298.
   109	
   110	config AD7476
   111		tristate "Analog Devices AD7476 1-channel ADCs driver and other similar devices from AD and TI"
   112		depends on SPI
   113		select IIO_BUFFER
   114		select IIO_TRIGGERED_BUFFER
   115		help
   116		  Say yes here to build support for the following SPI analog to
   117		  digital converters (ADCs):
   118		  Analog Devices: AD7273, AD7274, AD7276, AD7277, AD7278, AD7475,
   119		  AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495, AD7910,
   120		  AD7920.
   121		  Texas Instruments: ADS7866, ADS7867, ADS7868.
   122	
   123		  To compile this driver as a module, choose M here: the
   124		  module will be called ad7476.
   125	
   126	config AD7606
   127		tristate
   128		select IIO_BUFFER
   129		select IIO_TRIGGERED_BUFFER
   130	
   131	config AD7606_IFACE_PARALLEL
   132		tristate "Analog Devices AD7606 ADC driver with parallel interface support"
   133		depends on HAS_IOMEM
   134		select AD7606
   135		help
   136		  Say yes here to build parallel interface support for Analog Devices:
   137		  ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC).
   138	
   139		  To compile this driver as a module, choose M here: the
   140		  module will be called ad7606_parallel.
   141	
   142	config AD7606_IFACE_SPI
   143		tristate "Analog Devices AD7606 ADC driver with spi interface support"
   144		depends on SPI
   145		select AD7606
   146		help
   147		  Say yes here to build spi interface support for Analog Devices:
   148		  ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC).
   149	
   150		  To compile this driver as a module, choose M here: the
   151		  module will be called ad7606_spi.
   152	
   153	config AD7766
   154		tristate "Analog Devices AD7766/AD7767 ADC driver"
   155		depends on SPI_MASTER
   156		select IIO_BUFFER
   157		select IIO_TRIGGERED_BUFFER
   158		help
   159		  Say yes here to build support for Analog Devices AD7766, AD7766-1,
   160		  AD7766-2, AD7767, AD7767-1, AD7767-2 SPI analog to digital converters.
   161	
   162		  To compile this driver as a module, choose M here: the module will be
   163		  called ad7766.
   164	
   165	config AD7768_1
   166		tristate "Analog Devices AD7768-1 ADC driver"
   167		depends on SPI
   168		select IIO_BUFFER
   169		select IIO_TRIGGER
   170		select IIO_TRIGGERED_BUFFER
   171		help
   172		  Say yes here to build support for Analog Devices AD7768-1 SPI
   173		  simultaneously sampling sigma-delta analog to digital converter (ADC).
   174	
   175		  To compile this driver as a module, choose M here: the module will be
   176		  called ad7768-1.
   177	
   178	config AD7780
   179		tristate "Analog Devices AD7780 and similar ADCs driver"
   180		depends on SPI
   181		depends on GPIOLIB || COMPILE_TEST
   182		select AD_SIGMA_DELTA
   183		help
   184		  Say yes here to build support for Analog Devices AD7170, AD7171,
   185		  AD7780 and AD7781 SPI analog to digital converters (ADC).
   186	
   187		  To compile this driver as a module, choose M here: the
   188		  module will be called ad7780.
   189	
   190	config AD7791
   191		tristate "Analog Devices AD7791 ADC driver"
   192		depends on SPI
   193		select AD_SIGMA_DELTA
   194		help
   195		  Say yes here to build support for Analog Devices AD7787, AD7788, AD7789,
   196		  AD7790 and AD7791 SPI analog to digital converters (ADC).
   197	
   198		  To compile this driver as a module, choose M here: the module will be
   199		  called ad7791.
   200	
   201	config AD7793
   202		tristate "Analog Devices AD7793 and similar ADCs driver"
   203		depends on SPI
   204		select AD_SIGMA_DELTA
   205		help
   206		  Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
   207		  AD7794 and AD7795 SPI analog to digital converters (ADC).
   208	
   209		  To compile this driver as a module, choose M here: the
   210		  module will be called AD7793.
   211	
   212	config AD7887
   213		tristate "Analog Devices AD7887 ADC driver"
   214		depends on SPI
   215		select IIO_BUFFER
   216		select IIO_TRIGGERED_BUFFER
   217		help
   218		  Say yes here to build support for Analog Devices
   219		  AD7887 SPI analog to digital converter (ADC).
   220	
   221		  To compile this driver as a module, choose M here: the
   222		  module will be called ad7887.
   223	
   224	config AD7923
   225		tristate "Analog Devices AD7923 and similar ADCs driver"
   226		depends on SPI
   227		select IIO_BUFFER
   228		select IIO_TRIGGERED_BUFFER
   229		help
   230		  Say yes here to build support for Analog Devices
   231		  AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
   232	
   233		  To compile this driver as a module, choose M here: the
   234		  module will be called ad7923.
   235	
   236	config AD7949
   237		tristate "Analog Devices AD7949 and similar ADCs driver"
   238		depends on SPI
   239		help
   240		  Say yes here to build support for Analog Devices
   241		  AD7949, AD7682, AD7689 8 Channel ADCs.
   242	
   243		  To compile this driver as a module, choose M here: the
   244		  module will be called ad7949.
   245	
   246	config AD799X
   247		tristate "Analog Devices AD799x ADC driver"
   248		depends on I2C
   249		select IIO_BUFFER
   250		select IIO_TRIGGERED_BUFFER
   251		help
   252		  Say yes here to build support for Analog Devices:
   253		  ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, ad7998
   254		  i2c analog to digital converters (ADC). Provides direct access
   255		  via sysfs.
   256	
   257		  To compile this driver as a module, choose M here: the module will be
   258		  called ad799x.
   259	
   260	config AD9467
   261		tristate "Analog Devices AD9467 High Speed ADC driver"
   262		depends on SPI
   263		depends on ADI_AXI_ADC
   264		help
   265		  Say yes here to build support for Analog Devices:
   266		  * AD9467 16-Bit, 200 MSPS/250 MSPS Analog-to-Digital Converter
   267	
   268		  The driver requires the assistance of the AXI ADC IP core to operate,
   269		  since SPI is used for configuration only, while data has to be
   270		  streamed into memory via DMA.
   271	
   272		  To compile this driver as a module, choose M here: the module will be
   273		  called ad9467.
   274	
   275	config ADI_AXI_ADC
   276		tristate "Analog Devices Generic AXI ADC IP core driver"
   277		select IIO_BUFFER
   278		select IIO_BUFFER_HW_CONSUMER
   279		select IIO_BUFFER_DMAENGINE
   280		depends on HAS_IOMEM
   281		depends on OF
   282		help
   283		  Say yes here to build support for Analog Devices Generic
   284		  AXI ADC IP core. The IP core is used for interfacing with
   285		  analog-to-digital (ADC) converters that require either a high-speed
   286		  serial interface (JESD204B/C) or a source synchronous parallel
   287		  interface (LVDS/CMOS).
   288		  Typically (for such devices) SPI will be used for configuration only,
   289		  while this IP core handles the streaming of data into memory via DMA.
   290	
   291		  Link: https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
   292		  If unsure, say N (but it's safe to say "Y").
   293	
   294		  To compile this driver as a module, choose M here: the
   295		  module will be called adi-axi-adc.
   296	
   297	config ASPEED_ADC
   298		tristate "Aspeed ADC"
   299		depends on ARCH_ASPEED || COMPILE_TEST
   300		depends on COMMON_CLK
   301		help
   302		  If you say yes here you get support for the ADC included in Aspeed
   303		  BMC SoCs.
   304	
   305		  To compile this driver as a module, choose M here: the module will be
   306		  called aspeed_adc.
   307	
   308	config AT91_ADC
   309		tristate "Atmel AT91 ADC"
   310		depends on ARCH_AT91 || COMPILE_TEST
   311		depends on INPUT && SYSFS && OF
   312		select IIO_BUFFER
   313		select IIO_TRIGGERED_BUFFER
   314		help
   315		  Say yes here to build support for Atmel AT91 ADC.
   316	
   317		  To compile this driver as a module, choose M here: the module will be
   318		  called at91_adc.
   319	
   320	config AT91_SAMA5D2_ADC
   321		tristate "Atmel AT91 SAMA5D2 ADC"
   322		depends on ARCH_AT91 || COMPILE_TEST
   323		depends on HAS_IOMEM
   324		select IIO_BUFFER
   325		select IIO_TRIGGERED_BUFFER
   326		help
   327		  Say yes here to build support for Atmel SAMA5D2 ADC which is
   328		  available on SAMA5D2 SoC family.
   329	
   330		  To compile this driver as a module, choose M here: the module will be
   331		  called at91-sama5d2_adc.
   332	
   333	config AXP20X_ADC
   334		tristate "X-Powers AXP20X and AXP22X ADC driver"
   335		depends on MFD_AXP20X
   336		help
   337		  Say yes here to have support for X-Powers power management IC (PMIC)
   338		  AXP20X and AXP22X ADC devices.
   339	
   340		  To compile this driver as a module, choose M here: the module will be
   341		  called axp20x_adc.
   342	
   343	config AXP288_ADC
   344		tristate "X-Powers AXP288 ADC driver"
   345		depends on MFD_AXP20X
   346		help
   347		  Say yes here to have support for X-Powers power management IC (PMIC) ADC
   348		  device. Depending on platform configuration, this general purpose ADC can
   349		  be used for sampling sensors such as thermal resistors.
   350	
   351		  To compile this driver as a module, choose M here: the module will be
   352		  called axp288_adc.
   353	
   354	config BCM_IPROC_ADC
   355		tristate "Broadcom IPROC ADC driver"
   356		depends on (ARCH_BCM_IPROC && OF) || COMPILE_TEST
   357		depends on MFD_SYSCON
   358		default ARCH_BCM_CYGNUS
   359		help
   360		  Say Y here if you want to add support for the Broadcom static
   361		  ADC driver.
   362	
   363		  Broadcom iProc ADC driver. Broadcom iProc ADC controller has 8
   364		  channels. The driver allows the user to read voltage values.
   365	
   366	config BERLIN2_ADC
   367		tristate "Marvell Berlin2 ADC driver"
   368		depends on ARCH_BERLIN || COMPILE_TEST
   369		help
   370		  Marvell Berlin2 ADC driver. This ADC has 8 channels, with one used for
   371		  temperature measurement.
   372	
   373	config CC10001_ADC
   374		tristate "Cosmic Circuits 10001 ADC driver"
   375		depends on HAS_IOMEM && HAVE_CLK && REGULATOR
   376		select IIO_BUFFER
   377		select IIO_TRIGGERED_BUFFER
   378		help
   379		  Say yes here to build support for Cosmic Circuits 10001 ADC.
   380	
   381		  This driver can also be built as a module. If so, the module will be
   382		  called cc10001_adc.
   383	
   384	config CPCAP_ADC
   385		tristate "Motorola CPCAP PMIC ADC driver"
   386		depends on MFD_CPCAP
   387		select IIO_BUFFER
   388		select IIO_TRIGGERED_BUFFER
   389		help
   390		  Say yes here to build support for Motorola CPCAP PMIC ADC.
   391	
   392		  This driver can also be built as a module. If so, the module will be
   393		  called cpcap-adc.
   394	
   395	config DA9150_GPADC
   396		tristate "Dialog DA9150 GPADC driver support"
   397		depends on MFD_DA9150
   398		help
   399		  Say yes here to build support for Dialog DA9150 GPADC.
   400	
   401		  This driver can also be built as a module. If chosen, the module name
   402		  will be da9150-gpadc.
   403	
   404		  To compile this driver as a module, choose M here: the module will be
   405		  called berlin2-adc.
   406	
   407	config DLN2_ADC
   408		tristate "Diolan DLN-2 ADC driver support"
   409		depends on MFD_DLN2
   410		select IIO_BUFFER
   411		select IIO_TRIGGERED_BUFFER
   412		help
   413		  Say yes here to build support for Diolan DLN-2 ADC.
   414	
   415		  This driver can also be built as a module. If so, the module will be
   416		  called adc_dln2.
   417	
   418	config ENVELOPE_DETECTOR
   419		tristate "Envelope detector using a DAC and a comparator"
   420		depends on OF
   421		help
   422		  Say yes here to build support for an envelope detector using a DAC
   423		  and a comparator.
   424	
   425		  To compile this driver as a module, choose M here: the module will be
   426		  called envelope-detector.
   427	
   428	config EP93XX_ADC
   429		tristate "Cirrus Logic EP93XX ADC driver"
   430		depends on ARCH_EP93XX
   431		help
   432		  Driver for the ADC module on the EP93XX series of SoC from Cirrus Logic.
   433		  It's recommended to switch on CONFIG_HIGH_RES_TIMERS option, in this
   434		  case driver will reduce its CPU usage by 90% in some use cases.
   435	
   436		  To compile this driver as a module, choose M here: the module will be
   437		  called ep93xx_adc.
   438	
   439	config EXYNOS_ADC
   440		tristate "Exynos ADC driver support"
   441		depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210 || (OF && COMPILE_TEST)
   442		depends on HAS_IOMEM
   443		help
   444		  Driver for the ADC block found in the Samsung S3C (S3C2410, S3C2416,
   445		  S3C2440, S3C2443, S3C6410), S5Pv210 and Exynos SoCs.
   446		  Choose Y here only if you build for such Samsung SoC.
   447	
   448		  To compile this driver as a module, choose M here: the module will be
   449		  called exynos_adc.
   450	
   451	config MXS_LRADC_ADC
   452		tristate "Freescale i.MX23/i.MX28 LRADC ADC"
   453		depends on MFD_MXS_LRADC
   454		select IIO_BUFFER
   455		select IIO_TRIGGERED_BUFFER
   456		help
   457		  Say yes here to build support for the ADC functions of the
   458		  i.MX23/i.MX28 LRADC. This includes general-purpose ADC readings,
   459		  battery voltage measurement, and die temperature measurement.
   460	
   461		  This driver can also be built as a module. If so, the module will be
   462		  called mxs-lradc-adc.
   463	
   464	config FSL_MX25_ADC
   465		tristate "Freescale MX25 ADC driver"
   466		depends on MFD_MX25_TSADC
   467		help
   468		  Generic Conversion Queue driver used for general purpose ADC in the
   469		  MX25. This driver supports single measurements using the MX25 ADC.
   470	
   471	config HI8435
   472		tristate "Holt Integrated Circuits HI-8435 threshold detector"
   473		select IIO_TRIGGERED_EVENT
   474		depends on SPI
   475		help
   476		  If you say yes here you get support for Holt Integrated Circuits
   477		  HI-8435 chip.
   478	
   479		  This driver can also be built as a module. If so, the module will be
   480		  called hi8435.
   481	
   482	config HX711
   483		tristate "AVIA HX711 ADC for weight cells"
   484		depends on GPIOLIB
   485		select IIO_BUFFER
   486		select IIO_TRIGGERED_BUFFER
   487		help
   488		  If you say yes here you get support for AVIA HX711 ADC which is used
   489		  for weigh cells
   490	
   491		  This driver uses two GPIOs, one acts as the clock and controls the
   492		  channel selection and gain, the other one is used for the measurement
   493		  data
   494	
   495		  Currently the raw value is read from the chip and delivered.
   496		  To get an actual weight one needs to subtract the
   497		  zero offset and multiply by a scale factor.
   498		  This should be done in userspace.
   499	
   500		  This driver can also be built as a module. If so, the module will be
   501		  called hx711.
   502	
   503	config INA2XX_ADC
   504		tristate "Texas Instruments INA2xx Power Monitors IIO driver"
   505		depends on I2C && !SENSORS_INA2XX
   506		select REGMAP_I2C
   507		select IIO_BUFFER
   508		select IIO_KFIFO_BUF
   509		help
   510		  Say yes here to build support for TI INA2xx family of Power Monitors.
   511		  This driver is mutually exclusive with the HWMON version.
   512	
   513	config INGENIC_ADC
   514		tristate "Ingenic JZ47xx SoCs ADC driver"
   515		depends on MIPS || COMPILE_TEST
   516		select IIO_BUFFER
   517		help
   518		  Say yes here to build support for the Ingenic JZ47xx SoCs ADC unit.
   519	
   520		  This driver can also be built as a module. If so, the module will be
   521		  called ingenic_adc.
   522	
   523	config INTEL_MRFLD_ADC
   524		tristate "Intel Merrifield Basin Cove ADC driver"
   525		depends on INTEL_SOC_PMIC_MRFLD
   526		help
   527		  Say yes here to have support for Basin Cove power management IC (PMIC) ADC
   528		  device. Depending on platform configuration, this general purpose ADC can
   529		  be used for sampling sensors such as thermal resistors.
   530	
   531		  To compile this driver as a module, choose M here: the module will be
   532		  called intel_mrfld_adc.
   533	
   534	config IMX7D_ADC
   535		tristate "Freescale IMX7D ADC driver"
   536		depends on ARCH_MXC || COMPILE_TEST
   537		depends on HAS_IOMEM
   538		help
   539		  Say yes here to build support for IMX7D ADC.
   540	
   541		  This driver can also be built as a module. If so, the module will be
   542		  called imx7d_adc.
   543	
   544	config IMX8QXP_ADC
   545		tristate "NXP IMX8QXP ADC driver"
   546		depends on ARCH_MXC || COMPILE_TEST
   547		depends on HAS_IOMEM
   548		help
   549		  Say yes here to build support for IMX8QXP ADC.
   550	
   551		  This driver can also be built as a module. If so, the module will be
   552		  called imx8qxp-adc.
   553	
   554	config LP8788_ADC
   555		tristate "LP8788 ADC driver"
   556		depends on MFD_LP8788
   557		help
   558		  Say yes here to build support for TI LP8788 ADC.
   559	
   560		  To compile this driver as a module, choose M here: the module will be
   561		  called lp8788_adc.
   562	
   563	config LPC18XX_ADC
   564		tristate "NXP LPC18xx ADC driver"
   565		depends on ARCH_LPC18XX || COMPILE_TEST
   566		depends on OF && HAS_IOMEM
   567		help
   568		  Say yes here to build support for NXP LPC18XX ADC.
   569	
   570		  To compile this driver as a module, choose M here: the module will be
   571		  called lpc18xx_adc.
   572	
   573	config LPC32XX_ADC
   574		tristate "NXP LPC32XX ADC"
   575		depends on ARCH_LPC32XX || COMPILE_TEST
   576		depends on HAS_IOMEM
   577		help
   578		  Say yes here to build support for the integrated ADC inside the
   579		  LPC32XX SoC. Note that this feature uses the same hardware as the
   580		  touchscreen driver, so you should either select only one of the two
   581		  drivers (lpc32xx_adc or lpc32xx_ts) or, in the OpenFirmware case,
   582		  activate only one via device tree selection.  Provides direct access
   583		  via sysfs.
   584	
   585	config LTC2471
   586		tristate "Linear Technology LTC2471 and LTC2473 ADC driver"
   587		depends on I2C
   588		help
   589		  Say yes here to build support for Linear Technology LTC2471 and
   590		  LTC2473 16-bit I2C ADC.
   591	
   592		  This driver can also be built as a module. If so, the module will
   593		  be called ltc2471.
   594	
   595	config LTC2485
   596		tristate "Linear Technology LTC2485 ADC driver"
   597		depends on I2C
   598		help
   599		  Say yes here to build support for Linear Technology LTC2485 ADC.
   600	
   601		  To compile this driver as a module, choose M here: the module will be
   602		  called ltc2485.
   603	
   604	config LTC2496
   605		tristate "Linear Technology LTC2496 ADC driver"
   606		depends on SPI
   607		help
   608		  Say yes here to build support for Linear Technology LTC2496
   609		  16-Bit 8-/16-Channel Delta Sigma ADC.
   610	
   611		  To compile this driver as a module, choose M here: the module will be
   612		  called ltc2496.
   613	
   614	config LTC2497
   615		tristate "Linear Technology LTC2497 ADC driver"
   616		depends on I2C
   617		help
   618		  Say yes here to build support for Linear Technology LTC2497
   619		  16-Bit 8-/16-Channel Delta Sigma ADC.
   620	
   621		  To compile this driver as a module, choose M here: the module will be
   622		  called ltc2497.
   623	
   624	config MAX1027
   625		tristate "Maxim max1027 ADC driver"
   626		depends on SPI
   627		select IIO_BUFFER
   628		select IIO_TRIGGERED_BUFFER
   629		help
   630		  Say yes here to build support for Maxim SPI {10,12}-bit ADC models:
   631		  max1027, max1029, max1031, max1227, max1229 and max1231.
   632	
   633		  To compile this driver as a module, choose M here: the module will be
   634		  called max1027.
   635	
   636	config MAX11100
   637		tristate "Maxim max11100 ADC driver"
   638		depends on SPI_MASTER
   639		help
   640		  Say yes here to build support for Maxim max11100 SPI ADC
   641	
   642		  To compile this driver as a module, choose M here: the module will be
   643		  called max11100.
   644	
   645	config MAX1118
   646		tristate "Maxim max1117/max1118/max1119 ADCs driver"
   647		depends on SPI
   648		select IIO_BUFFER
   649		select IIO_TRIGGERED_BUFFER
   650		help
   651		  Say yes here to build support for Maxim max1117/max1118/max1119
   652		  8-bit, dual-channel ADCs.
   653	
   654		  To compile this driver as a module, choose M here: the module will be
   655		  called max1118.
   656	
   657	config MAX1241
   658		tristate "Maxim max1241 ADC driver"
   659		depends on SPI_MASTER
   660		help
   661		  Say yes here to build support for Maxim max1241 12-bit, single-channel
   662		  ADC.
   663	
   664		  To compile this driver as a module, choose M here: the module will be
   665		  called max1241.
   666	
   667	config MAX1363
   668		tristate "Maxim max1363 ADC driver"
   669		depends on I2C
   670		select IIO_BUFFER
   671		select IIO_TRIGGERED_BUFFER
   672		help
   673		  Say yes here to build support for many Maxim i2c analog to digital
   674		  converters (ADC). (max1361, max1362, max1363, max1364, max1036,
   675		  max1037, max1038, max1039, max1136, max1136, max1137, max1138,
   676		  max1139, max1236, max1237, max11238, max1239, max11600, max11601,
   677		  max11602, max11603, max11604, max11605, max11606, max11607,
   678		  max11608, max11609, max11610, max11611, max11612, max11613,
   679		  max11614, max11615, max11616, max11617, max11644, max11645,
   680		  max11646, max11647) Provides direct access via sysfs and buffered
   681		  data via the iio dev interface.
   682	
   683		  To compile this driver as a module, choose M here: the module will be
   684		  called max1363.
   685	
   686	config MAX597X_IIO
   687		tristate "Maxim 597x power switch and monitor"
   688		depends on I2C
   689		depends on OF
   690		depends MFD_MAX597X
 > 691		help
   692		  This driver exposes Maxim 5970/5978 voltage/current monitoring
   693		  interface using iio framework.
   694	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/5] mfd: max597x: Add support for MAX5970 and MAX5978
  2022-07-07 13:41 ` [PATCH v2 2/5] mfd: max597x: Add support " Naresh Solanki
@ 2022-08-08 13:55   ` Lee Jones
  0 siblings, 0 replies; 9+ messages in thread
From: Lee Jones @ 2022-08-08 13:55 UTC (permalink / raw)
  To: Naresh Solanki
  Cc: linux-kernel, Patrick Rudolph, Marcello Sylvester Bauer,
	Lee Jones

On Thu, 07 Jul 2022, Naresh Solanki wrote:

> From: Patrick Rudolph <patrick.rudolph@9elements.com>
> 
> Implement a regulator driver with IRQ support for fault management.
> Written against documentation [1] and [2] and tested on real hardware.
> 
> Every channel has it's own regulator supply nammed 'vss1-supply' and

Nit "its" and "supplies"

> 'vss2-supply'. The regulator supply is used to determine the output
> voltage, as the smart switch provides no output regulation.
> The driver requires the 'shunt-resistor-micro-ohms' to be present in

"property to be ..."

> the devicetree to properly calculate current related values.

Drop "the" and it's  "Device Tree"

> You must specify compatible devictree layout:

This doesn't need to be in the commit message.

Save it for the documentation.

> regulator@3a {
>         reg = <0x3a>;
>         vss1-supply = <&p3v3>;
>         compatible = "maxim,max5978";
> 
>         ...
> 
>         regulators {
>                 sw0_ref: SW0 {
>                         regulator-compatible = "SW0";
>                         shunt-resistor-micro-ohms = <12000>;
>                         ...
>                 }
>         }
> }
> 
> 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf
> 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf
> 
> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
> Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
> Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com>

What is the relationship between all of these people?

What did each of them provide to the patch?

> ---
>  drivers/mfd/Kconfig         |  12 ++++
>  drivers/mfd/Makefile        |   2 +
>  drivers/mfd/max597x.c       | 109 ++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/max597x.h | 100 +++++++++++++++++++++++++++++++++
>  4 files changed, 223 insertions(+)
>  create mode 100644 drivers/mfd/max597x.c
>  create mode 100644 include/linux/mfd/max597x.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 3b59456f5545..2422ae155118 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -253,6 +253,18 @@ config MFD_MADERA_SPI
>  	  Support for the Cirrus Logic Madera platform audio SoC
>  	  core functionality controlled via SPI.
>  
> +config MFD_MAX597X
> +	tristate "Maxim 597x power switch and monitor"

Power Switch and Monitor

> +	depends on I2C
> +	depends on OF
> +	select MFD_CORE
> +	select REGMAP_I2C
> +	help
> +	  This driver controls a Maxim 5970/5978 switch via I2C bus.
> +	  The MAX5970/5978 is a smart switch with no output regulation, but
> +	  fault protection and voltage and current monitoring capabilities.
> +	  Also it supports upto 4 indication leds.

LEDs

> +
>  config MFD_CS47L15
>  	bool "Cirrus Logic CS47L15"
>  	select PINCTRL_CS47L15
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 858cacf659d6..f5f46b86401f 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -95,6 +95,8 @@ obj-$(CONFIG_MFD_MADERA)	+= madera.o
>  obj-$(CONFIG_MFD_MADERA_I2C)	+= madera-i2c.o
>  obj-$(CONFIG_MFD_MADERA_SPI)	+= madera-spi.o
>  
> +obj-$(CONFIG_MFD_MAX597X) += max597x.o

Why don't you put it next to the existing MAX entries?

>  obj-$(CONFIG_TPS6105X)		+= tps6105x.o
>  obj-$(CONFIG_TPS65010)		+= tps65010.o
>  obj-$(CONFIG_TPS6507X)		+= tps6507x.o
> diff --git a/drivers/mfd/max597x.c b/drivers/mfd/max597x.c
> new file mode 100644
> index 000000000000..b2450e64d3eb
> --- /dev/null
> +++ b/drivers/mfd/max597x.c
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Device driver for regulators in MAX5970 and MAX5978 IC

This is not a regulator driver.

Please state what the 2 devices are.

> + * Copyright (c) 2022 9elements GmbH
> + *
> + * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/i2c.h>
> +#include <linux/mfd/core.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/regulator/of_regulator.h>
> +#include <linux/version.h>
> +#include <linux/mfd/max597x.h>

Alphabetical.

Also, are you sure *all* of these are needed?

> +static const struct regmap_config max597x_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = MAX_REGISTERS,
> +};
> +
> +static const struct mfd_cell max597x_devs[] = {

max597x_cells

> +	{
> +	 .name = "max597x-regulator",
> +	 },
> +	{
> +	 .name = "max597x-iio",
> +	 },
> +	{
> +	 .name = "max597x-led",
> +	 },

Like this please:

	{ .name = "max597x-regulator" },
	{ .name = "max597x-iio" },
	{ .name = "max597x-led" },

> +};
> +
> +static int max597x_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
> +{
> +	struct max597x_data *max597x;

"_ddata *ddata"

> +	struct regmap *regmap;
> +	enum max597x_chip_type chip = id->driver_data;
> +
> +	max597x =

No break.

> +	    devm_kzalloc(&i2c->dev, sizeof(struct max597x_data), GFP_KERNEL);

sizeof(*ddata)

'\n'

> +	switch (chip) {
> +	case MAX597x_TYPE_MAX5970:
> +		max597x->num_switches = 2;
> +		break;
> +	case MAX597x_TYPE_MAX5978:
> +		max597x->num_switches = 1;
> +		break;
> +	}

Are you planning on expanding the information in .data?

If not, why not put the number of switches in there instead?

> +	regmap = devm_regmap_init_i2c(i2c, &max597x_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&i2c->dev, "No regmap\n");

Is that really what that means?

"Failed to initialise regmap"

> +		return -EINVAL;
> +	}

'\n'

> +	max597x->regmap = regmap;

Why not put the value straight into max597x->regmap instead of
creating a local variable that's only used once?

> +	max597x->irq = i2c->irq;
> +	max597x->dev = &i2c->dev;

What the reason for saving this?

> +	i2c_set_clientdata(i2c, max597x);
> +
> +	return devm_mfd_add_devices(max597x->dev, PLATFORM_DEVID_AUTO,
> +				    max597x_devs, ARRAY_SIZE(max597x_devs),
> +				    NULL, 0, NULL);
> +}
> +
> +static const struct i2c_device_id max597x_table[] = {
> +	{.name = "max5970", MAX597x_TYPE_MAX5970},
> +	{.name = "max5978", MAX597x_TYPE_MAX5978},

Spaces after the { and before the } please.

> +	{},
> +};
> +

Remove this line.

> +MODULE_DEVICE_TABLE(i2c, max597x_table);
> +
> +static const struct of_device_id max597x_of_match[] = {
> +	{	.compatible = "maxim,max5970",

Needs to be on the line below.

> +		.data = (void *)MAX597x_TYPE_MAX5970
> +	},
> +	{	.compatible = "maxim,max5978",

Line below.

> +		.data = (void *)MAX597x_TYPE_MAX5978
> +	},
> +	{},
> +};
> +

Remove.

> +MODULE_DEVICE_TABLE(of, max597x_of_match);
> +
> +static struct i2c_driver max597x_driver = {
> +	.id_table = max597x_table,
> +	.driver = {
> +		   .name = "max597x",
> +		   .of_match_table = of_match_ptr(max597x_of_match),
> +		   },

Wrong tab spacing.  Should line up with the .driver.

> +	.probe = max597x_probe,
> +};
> +

Remove.

> +module_i2c_driver(max597x_driver);
> +
> +MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
> +MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");

This is not a good description.

> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/max597x.h b/include/linux/mfd/max597x.h
> new file mode 100644
> index 000000000000..ac7e9c84d06c
> --- /dev/null
> +++ b/include/linux/mfd/max597x.h
> @@ -0,0 +1,100 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Device driver for regulators in MAX5970 and MAX5978 IC

As above.

> + * Copyright (c) 2022 9elements GmbH
> + *
> + * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
> + */
> +
> +#ifndef _MAX597X_H
> +#define _MAX597X_H

MFD_

> +#include <linux/regmap.h>

device.h

> +#define MAX5970_NUM_SWITCHES 2
> +#define MAX5978_NUM_SWITCHES 1
> +#define MAX597X_NUM_LEDS     4
> +
> +struct max597x_data {

Place this at the bottom of the file.

> +	struct device *dev;
> +	int irq;
> +	int num_switches;
> +	struct regmap *regmap;

> +	u32 irng[MAX5970_NUM_SWITCHES];
> +	u32 mon_rng[MAX5970_NUM_SWITCHES];
> +	u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES];

Why are these here?

> +};
> +
> +enum max597x_chip_type {
> +	MAX597x_TYPE_MAX5978 = 1,
> +	MAX597x_TYPE_MAX5970,
> +};
> +
> +#define MAX5970_REG_CURRENT_L(ch)		(0x01 + (ch) * 4)
> +#define MAX5970_REG_CURRENT_H(ch)		(0x00 + (ch) * 4)
> +#define MAX5970_REG_VOLTAGE_L(ch)		(0x03 + (ch) * 4)
> +#define MAX5970_REG_VOLTAGE_H(ch)		(0x02 + (ch) * 4)
> +#define MAX5970_REG_MON_RANGE			0x18
> +#define  MAX5970_MON_MASK			0x3
> +#define  MAX5970_MON(reg, ch) \
> +	(((reg) >> ((ch) * 2)) & MAX5970_MON_MASK)
> +#define  MAX5970_MON_MAX_RANGE_UV		16000000
> +
> +#define MAX5970_REG_CH_UV_WARN_H(ch)		(0x1A + (ch) * 10)
> +#define MAX5970_REG_CH_UV_WARN_L(ch)		(0x1B + (ch) * 10)
> +#define MAX5970_REG_CH_UV_CRIT_H(ch)		(0x1C + (ch) * 10)
> +#define MAX5970_REG_CH_UV_CRIT_L(ch)		(0x1D + (ch) * 10)
> +#define MAX5970_REG_CH_OV_WARN_H(ch)		(0x1E + (ch) * 10)
> +#define MAX5970_REG_CH_OV_WARN_L(ch)		(0x1F + (ch) * 10)
> +#define MAX5970_REG_CH_OV_CRIT_H(ch)		(0x20 + (ch) * 10)
> +#define MAX5970_REG_CH_OV_CRIT_L(ch)		(0x21 + (ch) * 10)
> +
> +#define  MAX5970_VAL2REG_H(x)		(((x) >> 2) & 0xFF)
> +#define  MAX5970_VAL2REG_L(x)		((x) & 0x3)
> +
> +#define MAX5970_REG_DAC_FAST(ch)	(0x2E + (ch))
> +
> +#define MAX5970_FAST2SLOW_RATIO		200
> +
> +#define MAX5970_REG_STATUS0		0x31
> +#define  MAX5970_CB_IFAULTF(ch)		(1 << (ch))
> +#define  MAX5970_CB_IFAULTS(ch)		(1 << ((ch) + 4))

BIT()?

Same for the macros below.

> +#define MAX5970_REG_STATUS1		0x32
> +#define  STATUS1_PROT_MASK		0x3
> +#define  STATUS1_PROT(reg) \
> +	(((reg) >> 6) & STATUS1_PROT_MASK)
> +#define  STATUS1_PROT_SHUTDOWN		0
> +#define  STATUS1_PROT_CLEAR_PG		1
> +#define  STATUS1_PROT_ALERT_ONLY	2
> +
> +#define MAX5970_REG_STATUS2		0x33
> +#define  MAX5970_IRNG_MASK		0x3
> +#define  MAX5970_IRNG(reg, ch) \
> +	(((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK)
> +
> +#define MAX5970_REG_STATUS3		0x34
> +#define  MAX5970_STATUS3_ALERT		BIT(4)
> +#define  MAX5970_STATUS3_PG(ch)		BIT(ch)
> +
> +#define MAX5970_REG_FAULT0		0x35
> +#define  UV_STATUS_WARN(ch)		(1 << (ch))
> +#define  UV_STATUS_CRIT(ch)		(1 << ((ch) + 4))
> +
> +#define MAX5970_REG_FAULT1		0x36
> +#define  OV_STATUS_WARN(ch)		(1 << (ch))
> +#define  OV_STATUS_CRIT(ch)		(1 << ((ch) + 4))
> +
> +#define MAX5970_REG_FAULT2		0x37
> +#define  OC_STATUS_WARN(ch)		(1 << (ch))
> +
> +#define MAX5970_REG_CHXEN		0x3b
> +#define  CHXEN(ch)			(3 << ((ch) * 2))
> +
> +#define MAX5970_REG_LED_FLASH		0x43
> +
> +#define MAX_REGISTERS			0x49
> +#define ADC_MASK			0x3FF
> +
> +#endif				/* _MAX597X_H */

-- 
Lee Jones [李琼斯]
Principal Technical Lead - Developer Services
Linaro.org │ Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-08-08 13:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-07 13:41 [PATCH v2 0/5] mfd: max597x: Add support for max597x Naresh Solanki
2022-07-07 13:41 ` [PATCH v2 1/5] dt-bindings: mfd: Add bindings for MAX5970 and MAX5978 Naresh Solanki
2022-07-07 13:41 ` [PATCH v2 2/5] mfd: max597x: Add support " Naresh Solanki
2022-08-08 13:55   ` Lee Jones
2022-07-07 13:41 ` [PATCH v2 3/5] regulator: max597x: Add support for max597x regulator Naresh Solanki
2022-07-07 13:43   ` Mark Brown
2022-07-07 13:41 ` [PATCH v2 4/5] iio: max597x: Add support for max597x Naresh Solanki
2022-07-07 14:38   ` kernel test robot
2022-07-07 13:41 ` [PATCH v2 5/5] leds: " Naresh Solanki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox