Files
linux/drivers/regulator/spacemit-p1.c
Javier Martinez Canillas 99f0c3a654 regulator: spacemit: Align input supply name with the DT binding
The Device Tree binding schema for the SpacemiT P1 PMIC defines the main
input supply property as "vin-supply", but the driver defines the supply
name for BUCK and ALDO regulators as "vcc".

This causes the regulator core to lookup for a non-existent "vcc-supply".
Rename the supply from "vcc" to "vin", to match the DT binding and ensure
that the regulators input supplies are correctly resolved.

After this change, the regulators supply hierarchy is correctly reported:

  $ cat /sys/kernel/debug/regulator/regulator_summary
   regulator                      use open bypass opmode voltage current     min     max
  ---------------------------------------------------------------------------------------
   regulator-dummy                  1    0      0 unknown     0mV     0mA     0mV     0mV
   dc_in_12v                        2    1      0 unknown 12000mV     0mA 12000mV 12000mV
      vcc_4v                        7   10      0 unknown  4000mV     0mA  4000mV  4000mV
         buck1                      1    0      0 unknown  1050mV     0mA   500mV  3425mV
         buck2                      1    0      0 unknown   900mV     0mA   500mV  3425mV
         buck3                      1    0      0 unknown  1800mV     0mA   500mV  1800mV
         buck4                      1    0      0 unknown  3300mV     0mA   500mV  3300mV
         buck5                      3    7      0 unknown  2100mV     0mA   500mV  3425mV
            dldo1                   0    0      0 unknown  1200mV     0mA   500mV  3125mV
            dldo2                   0    0      0 unknown   500mV     0mA   500mV  3125mV
            dldo3                   0    0      0 unknown   500mV     0mA   500mV  3125mV
            dldo4                   1    0      0 unknown  1800mV     0mA   500mV  3125mV
            dldo5                   0    0      0 unknown   500mV     0mA   500mV  3125mV
            dldo6                   1    0      0 unknown  1800mV     0mA   500mV  3125mV
            dldo7                   0    0      0 unknown   500mV     0mA   500mV  3125mV
         buck6                      1    0      0 unknown  1100mV     0mA   500mV  3425mV
         aldo1                      0    0      0 unknown  1800mV     0mA   500mV  3125mV
         aldo2                      0    0      0 unknown   500mV     0mA   500mV  3125mV
         aldo3                      0    0      0 unknown   500mV     0mA   500mV  3125mV
         aldo4                      0    0      0 unknown   500mV     0mA   500mV  3125mV

Fixes: 8b84d712ad ("regulator: spacemit: support SpacemiT P1 regulators")
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20251206133852.1739475-1-javierm@redhat.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2025-12-09 10:01:25 +09:00

158 lines
3.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Driver for regulators found in the SpacemiT P1 PMIC
*
* Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved.
* Derived from code from SpacemiT.
* Copyright (c) 2023, SPACEMIT Co., Ltd
*/
#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/device.h>
#include <linux/linear_range.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#define MOD_NAME "spacemit-p1-regulator"
enum p1_regulator_id {
P1_BUCK1,
P1_BUCK2,
P1_BUCK3,
P1_BUCK4,
P1_BUCK5,
P1_BUCK6,
P1_ALDO1,
P1_ALDO2,
P1_ALDO3,
P1_ALDO4,
P1_DLDO1,
P1_DLDO2,
P1_DLDO3,
P1_DLDO4,
P1_DLDO5,
P1_DLDO6,
P1_DLDO7,
};
static const struct regulator_ops p1_regulator_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
/* Selector value 255 can be used to disable the buck converter on sleep */
static const struct linear_range p1_buck_ranges[] = {
REGULATOR_LINEAR_RANGE(500000, 0, 170, 5000),
REGULATOR_LINEAR_RANGE(1375000, 171, 254, 25000),
};
/* Selector value 0 can be used for suspend */
static const struct linear_range p1_ldo_ranges[] = {
REGULATOR_LINEAR_RANGE(500000, 11, 127, 25000),
};
/* These define the voltage selector field for buck and LDO regulators */
#define BUCK_MASK GENMASK(7, 0)
#define LDO_MASK GENMASK(6, 0)
#define P1_ID(_TYPE, _n) P1_ ## _TYPE ## _n
#define P1_ENABLE_REG(_off, _n) ((_off) + 3 * ((_n) - 1))
#define P1_REG_DESC(_TYPE, _type, _n, _s, _off, _mask, _nv, _ranges) \
{ \
.name = #_type #_n, \
.supply_name = _s, \
.of_match = of_match_ptr(#_type #_n), \
.regulators_node = of_match_ptr("regulators"), \
.id = P1_ID(_TYPE, _n), \
.n_voltages = _nv, \
.ops = &p1_regulator_ops, \
.owner = THIS_MODULE, \
.linear_ranges = _ranges, \
.n_linear_ranges = ARRAY_SIZE(_ranges), \
.vsel_reg = P1_ENABLE_REG(_off, _n) + 1, \
.vsel_mask = _mask, \
.enable_reg = P1_ENABLE_REG(_off, _n), \
.enable_mask = BIT(0), \
}
#define P1_BUCK_DESC(_n) \
P1_REG_DESC(BUCK, buck, _n, "vin", 0x47, BUCK_MASK, 254, p1_buck_ranges)
#define P1_ALDO_DESC(_n) \
P1_REG_DESC(ALDO, aldo, _n, "vin", 0x5b, LDO_MASK, 117, p1_ldo_ranges)
#define P1_DLDO_DESC(_n) \
P1_REG_DESC(DLDO, dldo, _n, "buck5", 0x67, LDO_MASK, 117, p1_ldo_ranges)
static const struct regulator_desc p1_regulator_desc[] = {
P1_BUCK_DESC(1),
P1_BUCK_DESC(2),
P1_BUCK_DESC(3),
P1_BUCK_DESC(4),
P1_BUCK_DESC(5),
P1_BUCK_DESC(6),
P1_ALDO_DESC(1),
P1_ALDO_DESC(2),
P1_ALDO_DESC(3),
P1_ALDO_DESC(4),
P1_DLDO_DESC(1),
P1_DLDO_DESC(2),
P1_DLDO_DESC(3),
P1_DLDO_DESC(4),
P1_DLDO_DESC(5),
P1_DLDO_DESC(6),
P1_DLDO_DESC(7),
};
static int p1_regulator_probe(struct platform_device *pdev)
{
struct regulator_config config = { };
struct device *dev = &pdev->dev;
u32 i;
/*
* The parent device (PMIC) owns the regmap. Since we don't
* provide one in the config structure, that one will be used.
*/
config.dev = dev->parent;
for (i = 0; i < ARRAY_SIZE(p1_regulator_desc); i++) {
const struct regulator_desc *desc = &p1_regulator_desc[i];
struct regulator_dev *rdev;
rdev = devm_regulator_register(dev, desc, &config);
if (IS_ERR(rdev))
return dev_err_probe(dev, PTR_ERR(rdev),
"error registering regulator %s\n",
desc->name);
}
return 0;
}
static struct platform_driver p1_regulator_driver = {
.probe = p1_regulator_probe,
.driver = {
.name = MOD_NAME,
},
};
module_platform_driver(p1_regulator_driver);
MODULE_DESCRIPTION("SpacemiT P1 regulator driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" MOD_NAME);