Regulator driver for ADI MAX77643/MAX77654/MAX77658/MAX77659.
MAX77643/MAX77659 has 1 LDO regulator.
MAX77654/MAX77658 has two LDO regulators.
Signed-off-by: Nurettin Bolucu <Nurettin.Bolucu@analog.com>
Signed-off-by: Zeynep Arslanbenzer <Zeynep.Arslanbenzer@analog.com>
---
drivers/regulator/Kconfig | 8 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/max77658-regulator.c | 171 +++++++++++++++++++++++++
3 files changed, 180 insertions(+)
create mode 100644 drivers/regulator/max77658-regulator.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 820c9a0788e5..98591d637d0c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -573,6 +573,14 @@ config REGULATOR_MAX77650
Semiconductor. This device has a SIMO with three independent
power rails and an LDO.
+config REGULATOR_MAX77658
+ tristate "Analog Devices MAX77643/MAX77654/MAX77658/MAX77659 Regulator"
+ depends on MFD_MAX77658
+ help
+ Regulator driver for MAX77643/MAX77654/MAX77658/MAX77659
+ PMIC from Analog Devices. This driver supports LDO regulators.
+ Say Y here to enable the regulator driver.
+
config REGULATOR_MAX8649
tristate "Maxim 8649 voltage regulator"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index b9f5eb35bf5f..14b5f9fd75bf 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -70,6 +70,7 @@ 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_MAX77658) += max77658-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
obj-$(CONFIG_REGULATOR_MAX8893) += max8893.o
diff --git a/drivers/regulator/max77658-regulator.c b/drivers/regulator/max77658-regulator.c
new file mode 100644
index 000000000000..09ef72b979e4
--- /dev/null
+++ b/drivers/regulator/max77658-regulator.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Analog Devices, Inc.
+ * ADI regulator driver for the MAX77643/MAX77654/MAX77658/MAX77659
+ */
+
+#include <linux/mfd/max77658.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define MAX77658_LDO_VOLT_REG_MAX 0x7F
+#define MAX77658_LDO_VOLT_N_RANGE 0x80
+#define MAX77658_LDO_VOLT_STEP 25000
+#define MAX77658_LDO_VOLT_BASE 500000
+#define MAX77654_LDO_VOLT_BASE 800000
+
+#define MAX77658_REG_CNFG_LDO0_A 0x48
+#define MAX77658_REG_CNFG_LDO0_B 0x49
+
+#define MAX77654_REG_CNFG_LDO0_A 0x38
+#define MAX77654_REG_CNFG_LDO0_B 0x39
+
+#define MAX77658_REG_CNFG_LDO1_A 0x4A
+#define MAX77658_REG_CNFG_LDO1_B 0x4B
+
+#define MAX77654_REG_CNFG_LDO1_A 0x3A
+#define MAX77654_REG_CNFG_LDO1_B 0x3B
+
+#define MAX77658_BITS_CONFIG_LDOX_A_TV_LDO GENMASK(6, 0)
+#define MAX77658_BITS_CONFIG_LDOX_B_EN_LDO GENMASK(2, 0)
+
+#define MAX77658_REG_MAX 2
+
+/*
+ * 0.500 to 3.675V (25mV step)
+ */
+static const struct linear_range MAX77658_LDO_volts[] = {
+ REGULATOR_LINEAR_RANGE(MAX77658_LDO_VOLT_BASE, 0x00,
+ MAX77658_LDO_VOLT_REG_MAX,
+ MAX77658_LDO_VOLT_STEP),
+};
+
+static const struct linear_range MAX77654_LDO_volts[] = {
+ REGULATOR_LINEAR_RANGE(MAX77654_LDO_VOLT_BASE, 0x00,
+ MAX77658_LDO_VOLT_REG_MAX,
+ MAX77658_LDO_VOLT_STEP),
+};
+
+static const struct regulator_ops max77658_LDO_ops = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_ascend,
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+};
+
+#define REGULATOR_DESC_LDO(num, volts, vsel_r, vsel_m, enable_r, enable_m) { \
+ .name = "LDO"#num, \
+ .id = num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &max77658_LDO_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .linear_ranges = volts, \
+ .n_linear_ranges = MAX77658_LDO_VOLT_N_RANGE, \
+ .vsel_reg = vsel_r, \
+ .vsel_mask = vsel_m, \
+ .enable_reg = enable_r, \
+ .enable_mask = enable_m, \
+ .enable_val = 0x06, \
+ .disable_val = 0x04, \
+}
+
+static const struct regulator_desc max77643_ldo_desc[] = {
+ REGULATOR_DESC_LDO(0, MAX77658_LDO_volts, MAX77654_REG_CNFG_LDO0_A,
+ MAX77658_BITS_CONFIG_LDOX_A_TV_LDO,
+ MAX77654_REG_CNFG_LDO0_B,
+ MAX77658_BITS_CONFIG_LDOX_B_EN_LDO),
+};
+
+static const struct regulator_desc max77654_ldo_desc[] = {
+ REGULATOR_DESC_LDO(0, MAX77654_LDO_volts, MAX77654_REG_CNFG_LDO0_A,
+ MAX77658_BITS_CONFIG_LDOX_A_TV_LDO,
+ MAX77654_REG_CNFG_LDO0_B,
+ MAX77658_BITS_CONFIG_LDOX_B_EN_LDO),
+ REGULATOR_DESC_LDO(1, MAX77654_LDO_volts, MAX77654_REG_CNFG_LDO1_A,
+ MAX77658_BITS_CONFIG_LDOX_A_TV_LDO,
+ MAX77654_REG_CNFG_LDO1_B,
+ MAX77658_BITS_CONFIG_LDOX_B_EN_LDO),
+};
+
+static const struct regulator_desc max77658_ldo_desc[] = {
+ REGULATOR_DESC_LDO(0, MAX77658_LDO_volts, MAX77658_REG_CNFG_LDO0_A,
+ MAX77658_BITS_CONFIG_LDOX_A_TV_LDO,
+ MAX77658_REG_CNFG_LDO0_B,
+ MAX77658_BITS_CONFIG_LDOX_B_EN_LDO),
+ REGULATOR_DESC_LDO(1, MAX77658_LDO_volts, MAX77658_REG_CNFG_LDO1_A,
+ MAX77658_BITS_CONFIG_LDOX_A_TV_LDO,
+ MAX77658_REG_CNFG_LDO1_B,
+ MAX77658_BITS_CONFIG_LDOX_B_EN_LDO),
+};
+
+static int max77658_regulator_probe(struct platform_device *pdev)
+{
+ struct max77658_dev *max77658 = dev_get_drvdata(pdev->dev.parent);
+ const struct regulator_desc *regulators;
+ struct regulator_config config = {};
+ struct regulator_dev *rdev;
+ int n_regulators = 0;
+ int i;
+
+ switch (max77658->chip->id) {
+ case ID_MAX77643:
+ case ID_MAX77659:
+ regulators = max77643_ldo_desc;
+ n_regulators = ARRAY_SIZE(max77643_ldo_desc);
+ break;
+ case ID_MAX77654:
+ regulators = max77654_ldo_desc;
+ n_regulators = ARRAY_SIZE(max77654_ldo_desc);
+ break;
+ case ID_MAX77658:
+ regulators = max77658_ldo_desc;
+ n_regulators = ARRAY_SIZE(max77658_ldo_desc);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ config.dev = pdev->dev.parent;
+
+ for (i = 0; i < n_regulators; i++) {
+ rdev = devm_regulator_register(&pdev->dev, ®ulators[i],
+ &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "Failed to register %s regulator\n",
+ regulators[i].name);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id max77658_regulator_id[] = {
+ { "max77643-regulator" },
+ { "max77654-regulator" },
+ { "max77658-regulator" },
+ { "max77659-regulator" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, max77658_regulator_id);
+
+static struct platform_driver max77658_regulator_driver = {
+ .driver = {
+ .name = "max77658-regulator",
+ },
+ .probe = max77658_regulator_probe,
+ .id_table = max77658_regulator_id,
+};
+
+module_platform_driver(max77658_regulator_driver);
+
+MODULE_DESCRIPTION("MAX77658 Regulator Driver");
+MODULE_AUTHOR("Nurettin.Bolucu@analog.com, Zeynep.Arslanbenzer@analog.com");
+MODULE_LICENSE("GPL");
--
2.25.1
On 22/03/2023 06:56, Zeynep Arslanbenzer wrote:
> Regulator driver for ADI MAX77643/MAX77654/MAX77658/MAX77659.
>
> MAX77643/MAX77659 has 1 LDO regulator.
> MAX77654/MAX77658 has two LDO regulators.
>
> Signed-off-by: Nurettin Bolucu <Nurettin.Bolucu@analog.com>
> Signed-off-by: Zeynep Arslanbenzer <Zeynep.Arslanbenzer@analog.com>
> +
> + return 0;
> +}
> +
> +static const struct platform_device_id max77658_regulator_id[] = {
> + { "max77643-regulator" },
> + { "max77654-regulator" },
> + { "max77658-regulator" },
> + { "max77659-regulator" },
Why do you need so many entries? They do not differ.
Best regards,
Krzysztof
On Wed, 22 Mar 2023, Krzysztof Kozlowski wrote:
>On 22/03/2023 06:56, Zeynep Arslanbenzer wrote:
>> Regulator driver for ADI MAX77643/MAX77654/MAX77658/MAX77659.
>>
>> MAX77643/MAX77659 has 1 LDO regulator.
>> MAX77654/MAX77658 has two LDO regulators.
>>
>> Signed-off-by: Nurettin Bolucu <Nurettin.Bolucu@analog.com>
>> Signed-off-by: Zeynep Arslanbenzer <Zeynep.Arslanbenzer@analog.com>
>
>
>
>> +
>> + return 0;
>> +}
>> +
>> +static const struct platform_device_id max77658_regulator_id[] = {
>> + { "max77643-regulator" },
>> + { "max77654-regulator" },
>> + { "max77658-regulator" },
>> + { "max77659-regulator" },
>
>Why do you need so many entries? They do not differ.
They are slightly different. Just MAX77659 and MAX77643 regulators have exactly the same features. MAX77659 and MAX77643 have 1 LDO regulator but others have 2 and the voltage base of the MAX77654 regulators is different from others. Should I use the same entry for the MAX77643 and MAX77659?
Best regards,
Zeynep
On 02/05/2023 08:32, Arslanbenzer, Zeynep wrote:
> On Wed, 22 Mar 2023, Krzysztof Kozlowski wrote:
>> On 22/03/2023 06:56, Zeynep Arslanbenzer wrote:
>>> Regulator driver for ADI MAX77643/MAX77654/MAX77658/MAX77659.
>>>
>>> MAX77643/MAX77659 has 1 LDO regulator.
>>> MAX77654/MAX77658 has two LDO regulators.
>>>
>>> Signed-off-by: Nurettin Bolucu <Nurettin.Bolucu@analog.com>
>>> Signed-off-by: Zeynep Arslanbenzer <Zeynep.Arslanbenzer@analog.com>
>>
>>
>>
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static const struct platform_device_id max77658_regulator_id[] = {
>>> + { "max77643-regulator" },
>>> + { "max77654-regulator" },
>>> + { "max77658-regulator" },
>>> + { "max77659-regulator" },
>>
>> Why do you need so many entries? They do not differ.
>
> They are slightly different. Just MAX77659 and MAX77643 regulators have exactly the same features. MAX77659 and MAX77643 have 1 LDO regulator but others have 2 and the voltage base of the MAX77654 regulators is different from others. Should I use the same entry for the MAX77643 and MAX77659?
Wrap your email replies, it's difficult to read and reply.
Your driver does not choose regulators based on these compatibles. Your
of_device_id table claims all devices are fully compatible and do not
differ from regulators point of view. If they are different, you should
encode the difference. If not, use only one entry in of_device_id (only
of_device_id, not bindings).
Best regards,
Krzysztof
On Tue, 2 May 2023, Krzysztof Kozlowski wrote:
>On 02/05/2023 08:32, Arslanbenzer, Zeynep wrote:
>> On Wed, 22 Mar 2023, Krzysztof Kozlowski wrote:
>>> On 22/03/2023 06:56, Zeynep Arslanbenzer wrote:
>>>> Regulator driver for ADI MAX77643/MAX77654/MAX77658/MAX77659.
>>>>
>>>> MAX77643/MAX77659 has 1 LDO regulator.
>>>> MAX77654/MAX77658 has two LDO regulators.
>>>>
>>>> Signed-off-by: Nurettin Bolucu <Nurettin.Bolucu@analog.com>
>>>> Signed-off-by: Zeynep Arslanbenzer <Zeynep.Arslanbenzer@analog.com>
>>>
>>>
>>>
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static const struct platform_device_id max77658_regulator_id[] = {
>>>> + { "max77643-regulator" },
>>>> + { "max77654-regulator" },
>>>> + { "max77658-regulator" },
>>>> + { "max77659-regulator" },
>>>
>>> Why do you need so many entries? They do not differ.
>>
>> They are slightly different. Just MAX77659 and MAX77643 regulators have
>> exactly the same features. MAX77659 and MAX77643 have 1 LDO regulator but
>> others have 2 and the voltage base of the MAX77654 regulators is different
>> from others. Should I use the same entry for the MAX77643 and MAX77659?
>
>Your driver does not choose regulators based on these compatibles. Your
>of_device_id table claims all devices are fully compatible and do not
>differ from regulators point of view. If they are different, you should
>encode the difference. If not, use only one entry in of_device_id (only
>of_device_id, not bindings).
I used id table matching and I did not use of_device_id table. Should I use
OF style match instead?
Best regards,
Zeynep
On 04/05/2023 12:36, Arslanbenzer, Zeynep wrote:
> On Tue, 2 May 2023, Krzysztof Kozlowski wrote:
>> On 02/05/2023 08:32, Arslanbenzer, Zeynep wrote:
>>> On Wed, 22 Mar 2023, Krzysztof Kozlowski wrote:
>>>> On 22/03/2023 06:56, Zeynep Arslanbenzer wrote:
>>>>> Regulator driver for ADI MAX77643/MAX77654/MAX77658/MAX77659.
>>>>>
>>>>> MAX77643/MAX77659 has 1 LDO regulator.
>>>>> MAX77654/MAX77658 has two LDO regulators.
>>>>>
>>>>> Signed-off-by: Nurettin Bolucu <Nurettin.Bolucu@analog.com>
>>>>> Signed-off-by: Zeynep Arslanbenzer <Zeynep.Arslanbenzer@analog.com>
>>>>
>>>>
>>>>
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +static const struct platform_device_id max77658_regulator_id[] = {
>>>>> + { "max77643-regulator" },
>>>>> + { "max77654-regulator" },
>>>>> + { "max77658-regulator" },
>>>>> + { "max77659-regulator" },
>>>>
>>>> Why do you need so many entries? They do not differ.
>>>
>>> They are slightly different. Just MAX77659 and MAX77643 regulators have
>>> exactly the same features. MAX77659 and MAX77643 have 1 LDO regulator but
>>> others have 2 and the voltage base of the MAX77654 regulators is different
>>> from others. Should I use the same entry for the MAX77643 and MAX77659?
>>
>> Your driver does not choose regulators based on these compatibles. Your
>> of_device_id table claims all devices are fully compatible and do not
>> differ from regulators point of view. If they are different, you should
>> encode the difference. If not, use only one entry in of_device_id (only
>> of_device_id, not bindings).
>
> I used id table matching and I did not use of_device_id table. Should I use
> OF style match instead?
My comment stands regardless which device ID table you use. It's the
same mechanism.
Best regards,
Krzysztof
© 2016 - 2026 Red Hat, Inc.