lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <7bec6fc2-6643-4ddf-9475-8ead4b312912@gmail.com>
Date: Thu, 17 Jul 2025 10:28:35 +0300
From: Ivaylo Ivanov <ivo.ivanov.ivanov1@...il.com>
To: Dzmitry Sankouski <dsankouski@...il.com>,
 Krzysztof Kozlowski <krzk@...nel.org>, Lee Jones <lee@...nel.org>,
 Rob Herring <robh@...nel.org>, Conor Dooley <conor+dt@...nel.org>,
 Liam Girdwood <lgirdwood@...il.com>, Mark Brown <broonie@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
 devicetree@...r.kernel.org
Subject: Re: [PATCH v5 3/3] regulator: add s2dos05 regulator support

On 9/26/24 12:47, Dzmitry Sankouski wrote:
> S2DOS05 has 1 buck and 4 LDO regulators, used for powering
> panel/touchscreen.
>
> Signed-off-by: Dzmitry Sankouski <dsankouski@...il.com>

When is this going to get merged? This patch brings the regulators
functionality of the pmic, so not having it merged is odd. This PMIC is
used on other devices too, like the Galaxy S22.

It seems like this has been hanging for almost an year at this point.
If the author won't, will somebody resend it?

Regards,
Ivaylo

> ---
> Changes in v4:
> - remove excessive linux/module.h import
> - use generic regulator helpers
> - use of_match
> - use devm_* for mem allocations
> - use // style comment
> - drop all junk Samsung code
> - adjust to depend on sec-core
>
> Changes in v5:
> - fix Kconfig and module description to be the same
> - make regulators const
> - code refactoring
> - replace s2m* pattern on s2* to include s2dos05
> ---
>  MAINTAINERS                           |   2 +-
>  drivers/regulator/Kconfig             |   8 ++++
>  drivers/regulator/Makefile            |   1 +
>  drivers/regulator/s2dos05-regulator.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/regulator/s2dos05.h     |  73 +++++++++++++++++++++++++++++++++++++
>  5 files changed, 259 insertions(+), 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6a6c769a341a..0b9fca1030a8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20474,7 +20474,7 @@ F:	Documentation/devicetree/bindings/regulator/samsung,s2m*.yaml
>  F:	Documentation/devicetree/bindings/regulator/samsung,s5m*.yaml
>  F:	drivers/clk/clk-s2mps11.c
>  F:	drivers/mfd/sec*.c
> -F:	drivers/regulator/s2m*.c
> +F:	drivers/regulator/s2*.c
>  F:	drivers/regulator/s5m*.c
>  F:	drivers/rtc/rtc-s5m.c
>  F:	include/linux/mfd/samsung/
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 39297f7d8177..249933d6388d 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -1322,6 +1322,14 @@ config REGULATOR_RTQ2208
>  	  and two ldos. It features wide output voltage range from 0.4V to 2.05V
>  	  and the capability to configure the corresponding power stages.
>  
> +config REGULATOR_S2DOS05
> +	tristate "Samsung S2DOS05 voltage regulator"
> +	depends on MFD_SEC_CORE || COMPILE_TEST
> +	help
> +	  This driver provides support for the voltage regulators of the S2DOS05.
> +	  The S2DOS05 is a companion power management IC for the smart phones.
> +	  The S2DOS05 has 4 LDOs and 1 BUCK outputs.
> +
>  config REGULATOR_S2MPA01
>  	tristate "Samsung S2MPA01 voltage regulator"
>  	depends on MFD_SEC_CORE || COMPILE_TEST
> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
> index 3d5a803dce8a..9b69546fb3f6 100644
> --- a/drivers/regulator/Makefile
> +++ b/drivers/regulator/Makefile
> @@ -154,6 +154,7 @@ obj-$(CONFIG_REGULATOR_RTMV20)	+= rtmv20-regulator.o
>  obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o
>  obj-$(CONFIG_REGULATOR_RTQ6752)	+= rtq6752-regulator.o
>  obj-$(CONFIG_REGULATOR_RTQ2208) += rtq2208-regulator.o
> +obj-$(CONFIG_REGULATOR_S2DOS05) += s2dos05-regulator.o
>  obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
>  obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
>  obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
> diff --git a/drivers/regulator/s2dos05-regulator.c b/drivers/regulator/s2dos05-regulator.c
> new file mode 100644
> index 000000000000..258cabf104ce
> --- /dev/null
> +++ b/drivers/regulator/s2dos05-regulator.c
> @@ -0,0 +1,176 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +//
> +// s2dos05.c - Regulator driver for the Samsung s2dos05
> +//
> +// Copyright (C) 2024 Dzmitry Sankouski <dsankouski@...il.com>
> +
> +#include <linux/bug.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/regulator/of_regulator.h>
> +#include <linux/mfd/samsung/core.h>
> +#include <linux/regulator/s2dos05.h>
> +#include <linux/i2c.h>
> +
> +struct s2dos05_data {
> +	struct regmap *regmap;
> +	struct device *dev;
> +};
> +
> +#define _BUCK(macro)	S2DOS05_BUCK##macro
> +#define _buck_ops(num)	s2dos05_ops##num
> +#define _LDO(macro)	S2DOS05_LDO##macro
> +#define _REG(ctrl)	S2DOS05_REG##ctrl
> +#define _ldo_ops(num)	s2dos05_ops##num
> +#define _MASK(macro)	S2DOS05_ENABLE_MASK##macro
> +#define _TIME(macro)	S2DOS05_ENABLE_TIME##macro
> +
> +#define BUCK_DESC(_name, _id, _ops, m, s, v, e, em, t, a) {	\
> +	.name		= _name,				\
> +	.id		= _id,					\
> +	.ops		= _ops,					\
> +	.of_match = of_match_ptr(_name),			\
> +	.of_match_full_name = true,				\
> +	.regulators_node = of_match_ptr("regulators"),		\
> +	.type		= REGULATOR_VOLTAGE,			\
> +	.owner		= THIS_MODULE,				\
> +	.min_uV		= m,					\
> +	.uV_step	= s,					\
> +	.n_voltages	= S2DOS05_BUCK_N_VOLTAGES,		\
> +	.vsel_reg	= v,					\
> +	.vsel_mask	= S2DOS05_BUCK_VSEL_MASK,		\
> +	.enable_reg	= e,					\
> +	.enable_mask	= em,					\
> +	.enable_time	= t,					\
> +	.active_discharge_off = 0,				\
> +	.active_discharge_on = S2DOS05_BUCK_FD_MASK,		\
> +	.active_discharge_reg	= a,				\
> +	.active_discharge_mask	= S2DOS05_BUCK_FD_MASK		\
> +}
> +
> +#define LDO_DESC(_name, _id, _ops, m, s, v, e, em, t, a) {	\
> +	.name		= _name,				\
> +	.id		= _id,					\
> +	.ops		= _ops,					\
> +	.of_match = of_match_ptr(_name),			\
> +	.of_match_full_name = true,				\
> +	.regulators_node = of_match_ptr("regulators"),		\
> +	.type		= REGULATOR_VOLTAGE,			\
> +	.owner		= THIS_MODULE,				\
> +	.min_uV		= m,					\
> +	.uV_step	= s,					\
> +	.n_voltages	= S2DOS05_LDO_N_VOLTAGES,		\
> +	.vsel_reg	= v,					\
> +	.vsel_mask	= S2DOS05_LDO_VSEL_MASK,		\
> +	.enable_reg	= e,					\
> +	.enable_mask	= em,					\
> +	.enable_time	= t,					\
> +	.active_discharge_off = 0,				\
> +	.active_discharge_on = S2DOS05_LDO_FD_MASK,		\
> +	.active_discharge_reg	= a,				\
> +	.active_discharge_mask	= S2DOS05_LDO_FD_MASK		\
> +}
> +
> +static const struct regulator_ops s2dos05_ops = {
> +	.list_voltage		= regulator_list_voltage_linear,
> +	.map_voltage		= regulator_map_voltage_linear,
> +	.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,
> +	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
> +	.set_active_discharge	= regulator_set_active_discharge_regmap,
> +};
> +
> +static const struct regulator_desc regulators[S2DOS05_REGULATOR_MAX] = {
> +		// name, id, ops, min_uv, uV_step, vsel_reg, enable_reg
> +		LDO_DESC("ldo1", _LDO(1), &_ldo_ops(), _LDO(_MIN1),
> +			_LDO(_STEP1), _REG(_LDO1_CFG),
> +			_REG(_EN), _MASK(_L1), _TIME(_LDO), _REG(_LDO1_CFG)),
> +		LDO_DESC("ldo2", _LDO(2), &_ldo_ops(), _LDO(_MIN1),
> +			_LDO(_STEP1), _REG(_LDO2_CFG),
> +			_REG(_EN), _MASK(_L2), _TIME(_LDO), _REG(_LDO2_CFG)),
> +		LDO_DESC("ldo3", _LDO(3), &_ldo_ops(), _LDO(_MIN2),
> +			_LDO(_STEP1), _REG(_LDO3_CFG),
> +			_REG(_EN), _MASK(_L3), _TIME(_LDO), _REG(_LDO3_CFG)),
> +		LDO_DESC("ldo4", _LDO(4), &_ldo_ops(), _LDO(_MIN2),
> +			_LDO(_STEP1), _REG(_LDO4_CFG),
> +			_REG(_EN), _MASK(_L4), _TIME(_LDO), _REG(_LDO4_CFG)),
> +		BUCK_DESC("buck", _BUCK(1), &_buck_ops(), _BUCK(_MIN1),
> +			_BUCK(_STEP1), _REG(_BUCK_VOUT),
> +			_REG(_EN), _MASK(_B1), _TIME(_BUCK), _REG(_BUCK_CFG)),
> +};
> +
> +static int s2dos05_pmic_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
> +	struct of_regulator_match *rdata = NULL;
> +	struct s2dos05_data *s2dos05;
> +	struct regulator_config config = { };
> +	unsigned int rdev_num = ARRAY_SIZE(regulators);
> +	int i, ret;
> +
> +	s2dos05 = devm_kzalloc(dev, sizeof(*s2dos05), GFP_KERNEL);
> +	if (!s2dos05)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, s2dos05);
> +
> +	rdata = devm_kcalloc(dev, rdev_num, sizeof(*rdata), GFP_KERNEL);
> +	if (!rdata)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < rdev_num; i++)
> +		rdata[i].name = regulators[i].name;
> +
> +	s2dos05->regmap = iodev->regmap_pmic;
> +	s2dos05->dev = dev;
> +	if (!dev->of_node)
> +		dev->of_node = dev->parent->of_node;
> +
> +	for (i = 0; i < rdev_num; i++) {
> +		struct regulator_dev *regulator;
> +
> +		config.init_data = rdata[i].init_data;
> +		config.of_node = rdata[i].of_node;
> +		config.dev = dev;
> +		config.driver_data = s2dos05;
> +		regulator = devm_regulator_register(&pdev->dev,
> +						&regulators[i], &config);
> +		if (IS_ERR(regulator)) {
> +			ret = PTR_ERR(regulator);
> +			dev_err(&pdev->dev, "regulator init failed for %d\n",
> +				i);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct platform_device_id s2dos05_pmic_id[] = {
> +	{ "s2dos05-regulator" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(platform, s2dos05_pmic_id);
> +
> +static struct platform_driver s2dos05_platform_driver = {
> +	.driver = {
> +		.name = "s2dos05",
> +	},
> +	.probe = s2dos05_pmic_probe,
> +	.id_table = s2dos05_pmic_id,
> +};
> +module_platform_driver(s2dos05_platform_driver);
> +
> +MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@...il.com>");
> +MODULE_DESCRIPTION("Samsung S2DOS05 Regulator Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/regulator/s2dos05.h b/include/linux/regulator/s2dos05.h
> new file mode 100644
> index 000000000000..2e89fcbce769
> --- /dev/null
> +++ b/include/linux/regulator/s2dos05.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +// s2dos05.h
> +//
> +// Copyright (c) 2016 Samsung Electronics Co., Ltd
> +//              http://www.samsung.com
> +// Copyright (C) 2024 Dzmitry Sankouski <dsankouski@...il.com>
> +
> +#ifndef __LINUX_S2DOS05_H
> +#define __LINUX_S2DOS05_H
> +
> +// S2DOS05 registers
> +// Slave Addr : 0xC0
> +enum S2DOS05_reg {
> +	S2DOS05_REG_DEV_ID,
> +	S2DOS05_REG_TOPSYS_STAT,
> +	S2DOS05_REG_STAT,
> +	S2DOS05_REG_EN,
> +	S2DOS05_REG_LDO1_CFG,
> +	S2DOS05_REG_LDO2_CFG,
> +	S2DOS05_REG_LDO3_CFG,
> +	S2DOS05_REG_LDO4_CFG,
> +	S2DOS05_REG_BUCK_CFG,
> +	S2DOS05_REG_BUCK_VOUT,
> +	S2DOS05_REG_IRQ_MASK = 0x0D,
> +	S2DOS05_REG_SSD_TSD = 0x0E,
> +	S2DOS05_REG_OCL = 0x10,
> +	S2DOS05_REG_IRQ = 0x11
> +};
> +
> +// S2DOS05 regulator ids
> +enum S2DOS05_regulators {
> +	S2DOS05_LDO1,
> +	S2DOS05_LDO2,
> +	S2DOS05_LDO3,
> +	S2DOS05_LDO4,
> +	S2DOS05_BUCK1,
> +	S2DOS05_REG_MAX,
> +};
> +
> +#define S2DOS05_IRQ_PWRMT_MASK	BIT(5)
> +#define S2DOS05_IRQ_TSD_MASK	BIT(4)
> +#define S2DOS05_IRQ_SSD_MASK	BIT(3)
> +#define S2DOS05_IRQ_SCP_MASK	BIT(2)
> +#define S2DOS05_IRQ_UVLO_MASK	BIT(1)
> +#define S2DOS05_IRQ_OCD_MASK	BIT(0)
> +
> +#define S2DOS05_BUCK_MIN1	506250
> +#define S2DOS05_LDO_MIN1	1500000
> +#define S2DOS05_LDO_MIN2	2700000
> +#define S2DOS05_BUCK_STEP1	6250
> +#define S2DOS05_LDO_STEP1	25000
> +#define S2DOS05_LDO_VSEL_MASK	0x7F
> +#define S2DOS05_LDO_FD_MASK	0x80
> +#define S2DOS05_BUCK_VSEL_MASK	0xFF
> +#define S2DOS05_BUCK_FD_MASK	0x08
> +
> +#define S2DOS05_ENABLE_MASK_L1	BIT(0)
> +#define S2DOS05_ENABLE_MASK_L2	BIT(1)
> +#define S2DOS05_ENABLE_MASK_L3	BIT(2)
> +#define S2DOS05_ENABLE_MASK_L4	BIT(3)
> +#define S2DOS05_ENABLE_MASK_B1	BIT(4)
> +
> +#define S2DOS05_RAMP_DELAY	12000
> +
> +#define S2DOS05_ENABLE_TIME_LDO		50
> +#define S2DOS05_ENABLE_TIME_BUCK	350
> +
> +#define S2DOS05_LDO_N_VOLTAGES	(S2DOS05_LDO_VSEL_MASK + 1)
> +#define S2DOS05_BUCK_N_VOLTAGES (S2DOS05_BUCK_VSEL_MASK + 1)
> +
> +#define S2DOS05_REGULATOR_MAX	(S2DOS05_REG_MAX)
> +
> +#endif // __LINUX_S2DOS05_H
>


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ