From: Pablo Mazzini <pmazzini@gmail.com>
To: Mark Brown <broonie@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
Guenter Roeck <linux@roeck-us.net>, Lee Jones <lee@kernel.org>
Cc: Pablo Mazzini <pmazzini@gmail.com>,
Alistair Francis <alistair@alistair23.me>,
Andreas Kemnade <andreas@kemnade.info>,
linux-hwmon@vger.kernel.org, mfd@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 6/7] regulator: sy7636a: bind to the I2C device directly
Date: Sun, 1 Nov 2026 22:31:24 +0000 [thread overview]
Message-ID: <20261101223125.302001-7-pmazzini@gmail.com> (raw)
In-Reply-To: <20261101223125.302001-1-pmazzini@gmail.com>
Bind the regulator to the chip directly, as the TPS65185 and FP9931
drivers do, and have it create an auxiliary device for the hwmon driver,
instead of simple-mfd-i2c creating a cell for each. Drop the MFD glue
and header. It now probes before the GPIOs may be ready, so report the
power good GPIO with dev_err_probe(). The hwmon driver then only
accesses the chip after vin-supply is enabled.
Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
drivers/hwmon/Kconfig | 2 +-
drivers/hwmon/sy7636a-hwmon.c | 33 +++++-----
drivers/mfd/Kconfig | 10 ----
drivers/mfd/simple-mfd-i2c.c | 11 ----
drivers/regulator/Kconfig | 4 +-
drivers/regulator/sy7636a-regulator.c | 86 ++++++++++++++++-----------
include/linux/mfd/sy7636a.h | 34 -----------
7 files changed, 73 insertions(+), 107 deletions(-)
delete mode 100644 include/linux/mfd/sy7636a.h
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 18c682e1a475..247507a4ddde 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2106,7 +2106,7 @@ config SENSORS_SIS5595
config SENSORS_SY7636A
tristate "Silergy SY7636A"
- depends on MFD_SY7636A
+ depends on REGULATOR_SY7636A
help
If you say yes here you get support for the thermistor readout of
the Silergy SY7636A PMIC.
diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c
index 475aff997c2d..14d9516f15e7 100644
--- a/drivers/hwmon/sy7636a-hwmon.c
+++ b/drivers/hwmon/sy7636a-hwmon.c
@@ -8,14 +8,15 @@
* Alistair Francis <alistair@alistair23.me>
*/
+#include <linux/auxiliary_bus.h>
+#include <linux/bits.h>
#include <linux/err.h>
#include <linux/hwmon.h>
-#include <linux/init.h>
#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/regmap.h>
-#include <linux/mfd/sy7636a.h>
+#define SY7636A_REG_FAULT_FLAG 0x07
+#define SY7636A_FAULT_FLAG_PG BIT(0)
static int sy7636a_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *temp)
@@ -70,36 +71,40 @@ static const struct hwmon_chip_info sy7636a_chip_info = {
.info = sy7636a_info,
};
-static int sy7636a_sensor_probe(struct platform_device *pdev)
+static int sy7636a_sensor_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
{
- struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ struct regmap *regmap = dev_get_regmap(adev->dev.parent, NULL);
struct device *hwmon_dev;
int err;
if (!regmap)
- return -EPROBE_DEFER;
+ return -ENODEV;
- hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+ hwmon_dev = devm_hwmon_device_register_with_info(&adev->dev,
"sy7636a", regmap,
&sy7636a_chip_info, NULL);
if (IS_ERR(hwmon_dev)) {
err = PTR_ERR(hwmon_dev);
- dev_err(&pdev->dev, "Unable to register hwmon device, returned %d\n", err);
+ dev_err(&adev->dev, "Unable to register hwmon device, returned %d\n", err);
return err;
}
return 0;
}
-static struct platform_driver sy7636a_sensor_driver = {
+static const struct auxiliary_device_id sy7636a_sensor_ids[] = {
+ { .name = "sy7636a_regulator.hwmon" },
+ { }
+};
+MODULE_DEVICE_TABLE(auxiliary, sy7636a_sensor_ids);
+
+static struct auxiliary_driver sy7636a_sensor_driver = {
.probe = sy7636a_sensor_probe,
- .driver = {
- .name = "sy7636a-temperature",
- },
+ .id_table = sy7636a_sensor_ids,
};
-module_platform_driver(sy7636a_sensor_driver);
+module_auxiliary_driver(sy7636a_sensor_driver);
MODULE_DESCRIPTION("SY7636A sensor driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:sy7636a-temperature");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 87ed55c155f0..c7ff8997beb1 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1319,16 +1319,6 @@ config MFD_SPMI_PMIC
Say M here if you want to include support for the SPMI PMIC
series as a module. The module will be called "qcom-spmi-pmic".
-config MFD_SY7636A
- tristate "Silergy SY7636A voltage regulator"
- depends on I2C
- select MFD_SIMPLE_MFD_I2C
- help
- Enable support for Silergy SY7636A voltage regulator.
-
- To enable support for building sub-devices as modules,
- choose M here.
-
config MFD_RDC321X
tristate "RDC R-321x southbridge"
select MFD_CORE
diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index ef3ce4bdf98b..0c9162034899 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -67,16 +67,6 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
return ret;
}
-static const struct mfd_cell sy7636a_cells[] = {
- { .name = "sy7636a-regulator", },
- { .name = "sy7636a-temperature", },
-};
-
-static const struct simple_mfd_data silergy_sy7636a = {
- .mfd_cell = sy7636a_cells,
- .mfd_cell_size = ARRAY_SIZE(sy7636a_cells),
-};
-
static const struct mfd_cell max5970_cells[] = {
{ .name = "max5970-regulator", },
{ .name = "max5970-iio", },
@@ -124,7 +114,6 @@ static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "maxim,max5970", .data = &maxim_max5970 },
{ .compatible = "maxim,max5978", .data = &maxim_max5970 },
{ .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705 },
- { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a },
{ .compatible = "spacemit,p1", .data = &spacemit_p1 },
{}
};
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 88ba2770e378..6039abec0c37 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1621,7 +1621,9 @@ config REGULATOR_SUN20I
config REGULATOR_SY7636A
tristate "Silergy SY7636A voltage regulator"
- depends on MFD_SY7636A
+ depends on I2C
+ select AUXILIARY_BUS
+ select REGMAP_I2C
help
This driver supports Silergy SY7636A voltage regulator.
diff --git a/drivers/regulator/sy7636a-regulator.c b/drivers/regulator/sy7636a-regulator.c
index f87144e921da..709e90517821 100644
--- a/drivers/regulator/sy7636a-regulator.c
+++ b/drivers/regulator/sy7636a-regulator.c
@@ -7,18 +7,26 @@
// Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>
// Alistair Francis <alistair@alistair23.me>
+#include <linux/auxiliary_bus.h>
#include <linux/completion.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
-#include <linux/mfd/sy7636a.h>
#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
+#define SY7636A_REG_OPERATION_MODE_CRL 0x00
+#define SY7636A_OPERATION_MODE_CRL_ONOFF BIT(7)
+#define SY7636A_REG_VCOM_ADJUST_CTRL_L 0x01
+#define SY7636A_REG_VCOM_ADJUST_CTRL_H 0x02
+#define SY7636A_REG_POWER_ON_DELAY_TIME 0x06
+
+#define VCOM_ADJUST_CTRL_MASK 0x1ff
+#define VCOM_ADJUST_CTRL_SCAL 10000
+
#define PGOOD_TIMEOUT_MSECS 200
struct sy7636a_data {
@@ -133,50 +141,54 @@ static const struct regulator_desc desc = {
.of_match = of_match_ptr("vcom"),
};
-static int sy7636a_regulator_probe(struct platform_device *pdev)
+static const struct regmap_config sy7636a_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int sy7636a_regulator_probe(struct i2c_client *client)
{
- struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ struct device *dev = &client->dev;
struct regulator_config config = { };
+ struct auxiliary_device *adev;
struct regulator_dev *rdev;
struct gpio_desc *gdp;
struct sy7636a_data *data;
+ struct regmap *regmap;
int irq, ret;
- if (!regmap)
- return -EPROBE_DEFER;
-
- device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+ regmap = devm_regmap_init_i2c(client, &sy7636a_regmap_config);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap), "failed to allocate regmap\n");
- gdp = devm_gpiod_get(&pdev->dev, "epd-pwr-good", GPIOD_IN);
- if (IS_ERR(gdp)) {
- dev_err(&pdev->dev, "Power good GPIO fault %ld\n", PTR_ERR(gdp));
- return PTR_ERR(gdp);
- }
+ gdp = devm_gpiod_get(dev, "epd-pwr-good", GPIOD_IN);
+ if (IS_ERR(gdp))
+ return dev_err_probe(dev, PTR_ERR(gdp), "Power good GPIO fault\n");
- data = devm_kzalloc(&pdev->dev, sizeof(struct sy7636a_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct sy7636a_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->regmap = regmap;
data->pgood_gpio = gdp;
- ret = devm_regulator_get_enable_optional(&pdev->dev, "vin");
+ ret = devm_regulator_get_enable_optional(dev, "vin");
if (ret)
- return dev_err_probe(&pdev->dev, ret,
+ return dev_err_probe(dev, ret,
"failed to get vin regulator\n");
- data->en_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
+ data->en_gpio = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_HIGH);
if (IS_ERR(data->en_gpio))
- return dev_err_probe(&pdev->dev,
+ return dev_err_probe(dev,
PTR_ERR(data->en_gpio),
"failed to get en gpio\n");
/* Let VCOM just follow the default power on sequence */
- data->vcom_en_gpio = devm_gpiod_get_optional(&pdev->dev,
+ data->vcom_en_gpio = devm_gpiod_get_optional(dev,
"vcom-en", GPIOD_OUT_LOW);
if (IS_ERR(data->vcom_en_gpio))
- return dev_err_probe(&pdev->dev,
+ return dev_err_probe(dev,
PTR_ERR(data->vcom_en_gpio),
"failed to get vcom-en gpio\n");
@@ -184,54 +196,56 @@ static int sy7636a_regulator_probe(struct platform_device *pdev)
if (data->en_gpio)
usleep_range(2500, 4000);
- platform_set_drvdata(pdev, data);
+ i2c_set_clientdata(client, data);
ret = regmap_write(regmap, SY7636A_REG_POWER_ON_DELAY_TIME, 0x0);
if (ret) {
- dev_err(pdev->dev.parent, "Failed to initialize regulator: %d\n", ret);
+ dev_err(dev, "Failed to initialize regulator: %d\n", ret);
return ret;
}
irq = gpiod_to_irq(data->pgood_gpio);
if (irq < 0)
- return dev_err_probe(&pdev->dev, irq, "no power good interrupt\n");
+ return dev_err_probe(dev, irq, "no power good interrupt\n");
init_completion(&data->pgood_completion);
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, sy7636a_pgood_handler,
+ ret = devm_request_threaded_irq(dev, irq, NULL, sy7636a_pgood_handler,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"sy7636a-pgood", data);
if (ret)
- return dev_err_probe(&pdev->dev, ret,
- "failed to request power good interrupt\n");
+ return dev_err_probe(dev, ret, "failed to request power good interrupt\n");
- config.dev = &pdev->dev;
+ config.dev = dev;
config.regmap = regmap;
- rdev = devm_regulator_register(&pdev->dev, &desc, &config);
+ rdev = devm_regulator_register(dev, &desc, &config);
if (IS_ERR(rdev)) {
- dev_err(pdev->dev.parent, "Failed to register %s regulator\n",
- pdev->name);
+ dev_err(dev, "Failed to register %s regulator\n", desc.name);
return PTR_ERR(rdev);
}
+ adev = devm_auxiliary_device_create(dev, "hwmon", NULL);
+ if (!adev)
+ return dev_err_probe(dev, -ENODEV, "failed to create hwmon device\n");
+
return 0;
}
-static const struct platform_device_id sy7636a_regulator_id_table[] = {
- { .name = "sy7636a-regulator" },
+static const struct of_device_id sy7636a_of_match[] = {
+ { .compatible = "silergy,sy7636a" },
{ }
};
-MODULE_DEVICE_TABLE(platform, sy7636a_regulator_id_table);
+MODULE_DEVICE_TABLE(of, sy7636a_of_match);
-static struct platform_driver sy7636a_regulator_driver = {
+static struct i2c_driver sy7636a_regulator_driver = {
.driver = {
.name = "sy7636a-regulator",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ .of_match_table = sy7636a_of_match,
},
.probe = sy7636a_regulator_probe,
- .id_table = sy7636a_regulator_id_table,
};
-module_platform_driver(sy7636a_regulator_driver);
+module_i2c_driver(sy7636a_regulator_driver);
MODULE_AUTHOR("Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>");
MODULE_DESCRIPTION("SY7636A voltage regulator driver");
diff --git a/include/linux/mfd/sy7636a.h b/include/linux/mfd/sy7636a.h
deleted file mode 100644
index 22f03b2f851e..000000000000
--- a/include/linux/mfd/sy7636a.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Functions to access SY3686A power management chip.
- *
- * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/
- */
-
-#ifndef __MFD_SY7636A_H
-#define __MFD_SY7636A_H
-
-#define SY7636A_REG_OPERATION_MODE_CRL 0x00
-/* It is set if a gpio is used to control the regulator */
-#define SY7636A_OPERATION_MODE_CRL_VCOMCTL BIT(6)
-#define SY7636A_OPERATION_MODE_CRL_ONOFF BIT(7)
-#define SY7636A_REG_VCOM_ADJUST_CTRL_L 0x01
-#define SY7636A_REG_VCOM_ADJUST_CTRL_H 0x02
-#define SY7636A_REG_VCOM_ADJUST_CTRL_MASK 0x01ff
-#define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL 0x03
-#define SY7636A_REG_POWER_ON_DELAY_TIME 0x06
-#define SY7636A_REG_FAULT_FLAG 0x07
-#define SY7636A_FAULT_FLAG_PG BIT(0)
-#define SY7636A_REG_TERMISTOR_READOUT 0x08
-
-#define SY7636A_REG_MAX 0x08
-
-#define VCOM_ADJUST_CTRL_MASK 0x1ff
-// Used to shift the high byte
-#define VCOM_ADJUST_CTRL_SHIFT 8
-// Used to scale from VCOM_ADJUST_CTRL to mv
-#define VCOM_ADJUST_CTRL_SCAL 10000
-
-#define FAULT_FLAG_SHIFT 1
-
-#endif /* __LINUX_MFD_SY7636A_H */
--
2.52.0
next prev parent reply other threads:[~2026-11-01 22:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 22:31 [PATCH v2 0/7] sy7636a: power the panel only during updates Pablo Mazzini
2026-11-01 22:31 ` [PATCH v2 1/7] regulator: sy7636a: fix the chip name Pablo Mazzini
2026-11-01 22:31 ` [PATCH v2 2/7] regulator: sy7636a: add VCOM voltage control Pablo Mazzini
2026-11-01 22:31 ` [PATCH v2 3/7] regulator: sy7636a: wait for power good on enable Pablo Mazzini
2026-11-02 7:28 ` Andreas Kemnade
2026-11-01 22:31 ` [PATCH v2 4/7] hwmon: sy7636a: fix negative temperatures Pablo Mazzini
2026-11-01 22:31 ` [PATCH v2 5/7] hwmon: sy7636a: read the temperature only while the rails are on Pablo Mazzini
2026-11-02 3:35 ` Guenter Roeck
2026-11-02 8:09 ` Pablo Mazzini
2026-11-02 10:25 ` Andreas Kemnade
2026-11-01 22:31 ` Pablo Mazzini [this message]
2026-11-01 22:31 ` [PATCH v2 7/7] ARM: imx_v6_v7_defconfig: drop the SY7636A MFD option Pablo Mazzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261101223125.302001-7-pmazzini@gmail.com \
--to=pmazzini@gmail.com \
--cc=alistair@alistair23.me \
--cc=andreas@kemnade.info \
--cc=broonie@kernel.org \
--cc=lee@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mfd@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®