diff options
author | Michal Wilczynski <m.wilczynski@samsung.com> | 2024-08-22 09:11:58 +0200 |
---|---|---|
committer | Michal Wilczynski <m.wilczynski@samsung.com> | 2024-08-22 13:53:33 +0200 |
commit | 8da2b698216f35beb194ee60394b43d25941330c (patch) | |
tree | e1a9827812740a12d4f2ab8078ed8ae5fc908a0a | |
parent | a0d1af9316437143ff59db146e84843e89fd8c59 (diff) | |
download | linux-riscv-8da2b698216f35beb194ee60394b43d25941330c.tar.gz linux-riscv-8da2b698216f35beb194ee60394b43d25941330c.tar.bz2 linux-riscv-8da2b698216f35beb194ee60394b43d25941330c.zip |
regulator: Add SpacemiT K1-X regulator driver
Regulator is an important dependecy for other hardware. Port it from the
vendor kernel [1].
[1] - https://github.com/BPI-SINOVOIP/pi-linux.git
Change-Id: I8537925fbc9b31a4dab8d70f107e80bc16033f6f
Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com>
-rw-r--r-- | drivers/regulator/Kconfig | 9 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 2 | ||||
-rw-r--r-- | drivers/regulator/spacemit-regulator.c | 109 |
3 files changed, 120 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 965d4f0c18a6..0028e4c0086c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1663,4 +1663,13 @@ config REGULATOR_QCOM_LABIBB boost regulator and IBB can be used as a negative boost regulator for LCD display panel. +config REGULATOR_SPACEMIT + tristate "Spacemit regulator support" + depends on MFD_SPACEMIT_PMIC + select REGULATOR_FIXED_VOLTAGE + help + This driver provides support for the voltage regulators on the + spacemit pmic. + + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 23074714a81a..2a8cf2152e89 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -196,4 +196,6 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o +obj-$(CONFIG_REGULATOR_SPACEMIT) += spacemit-regulator.o + ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/spacemit-regulator.c b/drivers/regulator/spacemit-regulator.c new file mode 100644 index 000000000000..b96323366cf0 --- /dev/null +++ b/drivers/regulator/spacemit-regulator.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Regulator driver for Spacemit PMIC + * + * Copyright (c) 2023, SPACEMIT Co., Ltd + * + */ + +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/of_regulator.h> +#include <linux/gpio/consumer.h> +#include <linux/mfd/spacemit/spacemit_pmic.h> + +static const struct regulator_ops pmic_dcdc_ldo_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_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, +}; + +static const struct regulator_ops pmic_switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +SPM8821_BUCK_LINER_RANGE;SPM8821_LDO_LINER_RANGE;SPM8821_REGULATOR_DESC; +SPM8821_REGULATOR_MATCH_DATA; + +PM853_BUCK_LINER_RANGE1;PM853_BUCK_LINER_RANGE2;PM853_LDO_LINER_RANGE1; +PM853_LDO_LINER_RANGE2;PM853_LDO_LINER_RANGE3;PM853_LDO_LINER_RANGE4; +PM853_REGULATOR_DESC;PM853_REGULATOR_MATCH_DATA; + +SY8810L_BUCK_LINER_RANGE;SY8810L_REGULATOR_DESC;SY8810L_REGULATOR_MATCH_DATA; + +static const struct of_device_id spacemit_regulator_of_match[] = { + { .compatible = "pmic,regulator,spm8821", .data = (void *)&spm8821_regulator_match_data }, + { .compatible = "pmic,regulator,pm853", .data = (void *)&pm853_regulator_match_data }, + { .compatible = "pmic,regulator,sy8810l", .data = (void *)&sy8810l_regulator_match_data }, + { }, +}; +MODULE_DEVICE_TABLE(of, spacemit_regulator_of_match); + +static int spacemit_regulator_probe(struct platform_device *pdev) +{ + struct regulator_config config = {}; + struct spacemit_pmic *pmic = dev_get_drvdata(pdev->dev.parent); + struct i2c_client *client; + const struct of_device_id *of_id; + struct regulator_match_data *match_data; + struct regulator_dev *regulator_dev; + int i; + + of_id = of_match_device(spacemit_regulator_of_match, &pdev->dev); + if (!of_id) { + pr_err("Unable to match OF ID\n"); + return -ENODEV; + } + + match_data = (struct regulator_match_data *)of_id->data; + + client = pmic->i2c; + config.dev = &client->dev; + config.regmap = pmic->regmap; + + if (strcmp(match_data->name, "pm853") == 0) { + client = pmic->sub->power_page; + config.dev = &pmic->i2c->dev; + config.regmap = pmic->sub->power_regmap; + } + + for (i = 0; i < match_data->nr_desc; ++i) { + regulator_dev = devm_regulator_register(&pdev->dev, + match_data->desc + i, &config); + if (IS_ERR(regulator_dev)) { + pr_err("failed to register %d regulator\n", i); + return PTR_ERR(regulator_dev); + } + } + + return 0; +} + +static struct platform_driver spacemit_regulator_driver = { + .probe = spacemit_regulator_probe, + .driver = { + .name = "spacemit-regulator", + .of_match_table = spacemit_regulator_of_match, + }, +}; + +static int spacemit_regulator_init(void) +{ + return platform_driver_register(&spacemit_regulator_driver); +} +subsys_initcall(spacemit_regulator_init); + +MODULE_DESCRIPTION("regulator drivers for the Spacemit series PMICs"); + |