mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] mfd: add regmap driver for rohm-bd718x7
@ 2023-01-30  7:16 Ahmad Fatoum
  2023-01-31  8:22 ` Sascha Hauer
  0 siblings, 1 reply; 2+ messages in thread
From: Ahmad Fatoum @ 2023-01-30  7:16 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Rohm BD71837 is a PMIC for i.MX8MM, which is used on most boards
supported by barebox. So far, we didn't need to change PMIC
configuration after the initial setup in PBL, but to support future
debugging and development, let's port the Linux MFD driver sans the
regulators, so we get a regmap for interacting with the device.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mfd/Kconfig        |  13 ++++
 drivers/mfd/Makefile       |   1 +
 drivers/mfd/rohm-bd718x7.c | 140 +++++++++++++++++++++++++++++++++++++
 include/mfd/bd71837.h      |   3 +
 4 files changed, 157 insertions(+)
 create mode 100644 drivers/mfd/rohm-bd718x7.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f1f7e27fadfe..39a40c2a3fb5 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -129,6 +129,19 @@ config MFD_AXP20X_I2C
 	  management ICs (PMICs) controlled with I2C.
 	  This driver currently only provide a character device in /dev.
 
+config MFD_ROHM_BD718XX
+	tristate "ROHM BD71837 Power Management IC"
+	depends on I2C=y
+	depends on OFDEVICE
+	select REGMAP_I2C
+	help
+	  Select this option to get support for the ROHM BD71837
+	  Power Management ICs. BD71837 is designed to power processors like
+	  NXP i.MX8. It contains 8 BUCK outputs and 7 LDOs, voltage monitoring
+	  and emergency shut down as well as 32,768KHz clock output.
+
+	  This driver currently only provide a character device in /dev.
+
 config MFD_ATMEL_SMC
 	bool
 	select MFD_SYSCON
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b89ddab5947d..f19bf5365533 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
 obj-$(CONFIG_MFD_RK808)		+= rk808.o
 obj-$(CONFIG_MFD_AXP20X_I2C)	+= axp20x-i2c.o axp20x.o
 obj-$(CONFIG_MFD_ATMEL_SMC)	+= atmel-smc.o
+obj-$(CONFIG_MFD_ROHM_BD718XX)	+= rohm-bd718x7.o
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
new file mode 100644
index 000000000000..20c572b6d766
--- /dev/null
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// Copyright (C) 2018 ROHM Semiconductors
+//
+// ROHM BD71837MWV and BD71847MWV PMIC driver
+//
+// Datasheet for BD71837MWV available from
+// https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
+
+#include <common.h>
+#include <i2c/i2c.h>
+#include <mfd/bd71837.h>
+#include <linux/mfd/core.h>
+#include <driver.h>
+#include <poweroff.h>
+#include <of.h>
+#include <regmap.h>
+
+static struct mfd_cell bd71837_mfd_cells[] = {
+	{ .name = "gpio-keys", },
+	{ .name = "bd71837-clk", },
+	{ .name = "bd71837-pmic", },
+};
+
+static struct mfd_cell bd71847_mfd_cells[] = {
+	{ .name = "gpio-keys", },
+	{ .name = "bd71847-clk", },
+	{ .name = "bd71847-pmic", },
+};
+
+static const struct regmap_config bd718xx_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = BD718XX_MAX_REGISTER - 1,
+};
+
+static int bd718xx_init_press_duration(struct regmap *regmap,
+				       struct device *dev)
+{
+	u32 short_press_ms, long_press_ms;
+	u32 short_press_value, long_press_value;
+	int ret;
+
+	ret = of_property_read_u32(dev->of_node, "rohm,short-press-ms",
+				   &short_press_ms);
+	if (!ret) {
+		short_press_value = min(15u, (short_press_ms + 250) / 500);
+		ret = regmap_update_bits(regmap, BD718XX_PWRONCONFIG0,
+					 BD718XX_PWRBTN_PRESS_DURATION_MASK,
+					 short_press_value);
+		if (ret) {
+			dev_err(dev, "Failed to init pwron short press\n");
+			return ret;
+		}
+	}
+
+	ret = of_property_read_u32(dev->of_node, "rohm,long-press-ms",
+				   &long_press_ms);
+	if (!ret) {
+		long_press_value = min(15u, (long_press_ms + 500) / 1000);
+		ret = regmap_update_bits(regmap, BD718XX_PWRONCONFIG1,
+					 BD718XX_PWRBTN_PRESS_DURATION_MASK,
+					 long_press_value);
+		if (ret) {
+			dev_err(dev, "Failed to init pwron long press\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int bd718xx_i2c_probe(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct regmap *regmap;
+	int ret;
+	unsigned int chip_type;
+	struct mfd_cell *mfd;
+	int cells;
+
+	chip_type = (unsigned int)(uintptr_t)device_get_match_data(dev);
+	switch (chip_type) {
+	case ROHM_CHIP_TYPE_BD71837:
+		mfd = bd71837_mfd_cells;
+		cells = ARRAY_SIZE(bd71837_mfd_cells);
+		break;
+	case ROHM_CHIP_TYPE_BD71847:
+		mfd = bd71847_mfd_cells;
+		cells = ARRAY_SIZE(bd71847_mfd_cells);
+		break;
+	default:
+		dev_err(dev, "Unknown device type");
+		return -EINVAL;
+	}
+
+	regmap = regmap_init_i2c(i2c, &bd718xx_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap initialization failed\n");
+		return PTR_ERR(regmap);
+	}
+
+	ret = bd718xx_init_press_duration(regmap, dev);
+	if (ret)
+		return ret;
+
+	ret = mfd_add_devices(dev, mfd, cells);
+	if (ret)
+		dev_err(dev, "Failed to create subdevices\n");
+
+	return regmap_register_cdev(regmap, NULL);
+}
+
+static const struct of_device_id bd718xx_of_match[] = {
+	{
+		.compatible = "rohm,bd71837",
+		.data = (void *)ROHM_CHIP_TYPE_BD71837,
+	},
+	{
+		.compatible = "rohm,bd71847",
+		.data = (void *)ROHM_CHIP_TYPE_BD71847,
+	},
+	{
+		.compatible = "rohm,bd71850",
+		.data = (void *)ROHM_CHIP_TYPE_BD71847,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bd718xx_of_match);
+
+static struct driver bd718xx_i2c_driver = {
+	.name = "rohm-bd718x7",
+	.of_match_table = bd718xx_of_match,
+	.probe = bd718xx_i2c_probe,
+};
+coredevice_i2c_driver(bd718xx_i2c_driver);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("ROHM BD71837/BD71847 Power Management IC driver");
+MODULE_LICENSE("GPL");
diff --git a/include/mfd/bd71837.h b/include/mfd/bd71837.h
index 75e07e1de31e..4e285a647a92 100644
--- a/include/mfd/bd71837.h
+++ b/include/mfd/bd71837.h
@@ -100,4 +100,7 @@ enum {
 #define BD71847_LDO5_RANGE_MASK		0x20
 #define BD71837_LDO7_MASK		0x0f
 
+#define BD718XX_PWRBTN_PRESS_DURATION_MASK 0xF
+
+
 #endif
-- 
2.30.2




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] mfd: add regmap driver for rohm-bd718x7
  2023-01-30  7:16 [PATCH] mfd: add regmap driver for rohm-bd718x7 Ahmad Fatoum
@ 2023-01-31  8:22 ` Sascha Hauer
  0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2023-01-31  8:22 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, Jan 30, 2023 at 08:16:22AM +0100, Ahmad Fatoum wrote:
> Rohm BD71837 is a PMIC for i.MX8MM, which is used on most boards
> supported by barebox. So far, we didn't need to change PMIC
> configuration after the initial setup in PBL, but to support future
> debugging and development, let's port the Linux MFD driver sans the
> regulators, so we get a regmap for interacting with the device.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  drivers/mfd/Kconfig        |  13 ++++
>  drivers/mfd/Makefile       |   1 +
>  drivers/mfd/rohm-bd718x7.c | 140 +++++++++++++++++++++++++++++++++++++
>  include/mfd/bd71837.h      |   3 +
>  4 files changed, 157 insertions(+)
>  create mode 100644 drivers/mfd/rohm-bd718x7.c

Applied, thanks

Sascha

> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index f1f7e27fadfe..39a40c2a3fb5 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -129,6 +129,19 @@ config MFD_AXP20X_I2C
>  	  management ICs (PMICs) controlled with I2C.
>  	  This driver currently only provide a character device in /dev.
>  
> +config MFD_ROHM_BD718XX
> +	tristate "ROHM BD71837 Power Management IC"
> +	depends on I2C=y
> +	depends on OFDEVICE
> +	select REGMAP_I2C
> +	help
> +	  Select this option to get support for the ROHM BD71837
> +	  Power Management ICs. BD71837 is designed to power processors like
> +	  NXP i.MX8. It contains 8 BUCK outputs and 7 LDOs, voltage monitoring
> +	  and emergency shut down as well as 32,768KHz clock output.
> +
> +	  This driver currently only provide a character device in /dev.
> +
>  config MFD_ATMEL_SMC
>  	bool
>  	select MFD_SYSCON
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index b89ddab5947d..f19bf5365533 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -24,3 +24,4 @@ obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
>  obj-$(CONFIG_MFD_RK808)		+= rk808.o
>  obj-$(CONFIG_MFD_AXP20X_I2C)	+= axp20x-i2c.o axp20x.o
>  obj-$(CONFIG_MFD_ATMEL_SMC)	+= atmel-smc.o
> +obj-$(CONFIG_MFD_ROHM_BD718XX)	+= rohm-bd718x7.o
> diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
> new file mode 100644
> index 000000000000..20c572b6d766
> --- /dev/null
> +++ b/drivers/mfd/rohm-bd718x7.c
> @@ -0,0 +1,140 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +//
> +// Copyright (C) 2018 ROHM Semiconductors
> +//
> +// ROHM BD71837MWV and BD71847MWV PMIC driver
> +//
> +// Datasheet for BD71837MWV available from
> +// https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
> +
> +#include <common.h>
> +#include <i2c/i2c.h>
> +#include <mfd/bd71837.h>
> +#include <linux/mfd/core.h>
> +#include <driver.h>
> +#include <poweroff.h>
> +#include <of.h>
> +#include <regmap.h>
> +
> +static struct mfd_cell bd71837_mfd_cells[] = {
> +	{ .name = "gpio-keys", },
> +	{ .name = "bd71837-clk", },
> +	{ .name = "bd71837-pmic", },
> +};
> +
> +static struct mfd_cell bd71847_mfd_cells[] = {
> +	{ .name = "gpio-keys", },
> +	{ .name = "bd71847-clk", },
> +	{ .name = "bd71847-pmic", },
> +};
> +
> +static const struct regmap_config bd718xx_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = BD718XX_MAX_REGISTER - 1,
> +};
> +
> +static int bd718xx_init_press_duration(struct regmap *regmap,
> +				       struct device *dev)
> +{
> +	u32 short_press_ms, long_press_ms;
> +	u32 short_press_value, long_press_value;
> +	int ret;
> +
> +	ret = of_property_read_u32(dev->of_node, "rohm,short-press-ms",
> +				   &short_press_ms);
> +	if (!ret) {
> +		short_press_value = min(15u, (short_press_ms + 250) / 500);
> +		ret = regmap_update_bits(regmap, BD718XX_PWRONCONFIG0,
> +					 BD718XX_PWRBTN_PRESS_DURATION_MASK,
> +					 short_press_value);
> +		if (ret) {
> +			dev_err(dev, "Failed to init pwron short press\n");
> +			return ret;
> +		}
> +	}
> +
> +	ret = of_property_read_u32(dev->of_node, "rohm,long-press-ms",
> +				   &long_press_ms);
> +	if (!ret) {
> +		long_press_value = min(15u, (long_press_ms + 500) / 1000);
> +		ret = regmap_update_bits(regmap, BD718XX_PWRONCONFIG1,
> +					 BD718XX_PWRBTN_PRESS_DURATION_MASK,
> +					 long_press_value);
> +		if (ret) {
> +			dev_err(dev, "Failed to init pwron long press\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int bd718xx_i2c_probe(struct device *dev)
> +{
> +	struct i2c_client *i2c = to_i2c_client(dev);
> +	struct regmap *regmap;
> +	int ret;
> +	unsigned int chip_type;
> +	struct mfd_cell *mfd;
> +	int cells;
> +
> +	chip_type = (unsigned int)(uintptr_t)device_get_match_data(dev);
> +	switch (chip_type) {
> +	case ROHM_CHIP_TYPE_BD71837:
> +		mfd = bd71837_mfd_cells;
> +		cells = ARRAY_SIZE(bd71837_mfd_cells);
> +		break;
> +	case ROHM_CHIP_TYPE_BD71847:
> +		mfd = bd71847_mfd_cells;
> +		cells = ARRAY_SIZE(bd71847_mfd_cells);
> +		break;
> +	default:
> +		dev_err(dev, "Unknown device type");
> +		return -EINVAL;
> +	}
> +
> +	regmap = regmap_init_i2c(i2c, &bd718xx_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap initialization failed\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	ret = bd718xx_init_press_duration(regmap, dev);
> +	if (ret)
> +		return ret;
> +
> +	ret = mfd_add_devices(dev, mfd, cells);
> +	if (ret)
> +		dev_err(dev, "Failed to create subdevices\n");
> +
> +	return regmap_register_cdev(regmap, NULL);
> +}
> +
> +static const struct of_device_id bd718xx_of_match[] = {
> +	{
> +		.compatible = "rohm,bd71837",
> +		.data = (void *)ROHM_CHIP_TYPE_BD71837,
> +	},
> +	{
> +		.compatible = "rohm,bd71847",
> +		.data = (void *)ROHM_CHIP_TYPE_BD71847,
> +	},
> +	{
> +		.compatible = "rohm,bd71850",
> +		.data = (void *)ROHM_CHIP_TYPE_BD71847,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, bd718xx_of_match);
> +
> +static struct driver bd718xx_i2c_driver = {
> +	.name = "rohm-bd718x7",
> +	.of_match_table = bd718xx_of_match,
> +	.probe = bd718xx_i2c_probe,
> +};
> +coredevice_i2c_driver(bd718xx_i2c_driver);
> +
> +MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
> +MODULE_DESCRIPTION("ROHM BD71837/BD71847 Power Management IC driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/mfd/bd71837.h b/include/mfd/bd71837.h
> index 75e07e1de31e..4e285a647a92 100644
> --- a/include/mfd/bd71837.h
> +++ b/include/mfd/bd71837.h
> @@ -100,4 +100,7 @@ enum {
>  #define BD71847_LDO5_RANGE_MASK		0x20
>  #define BD71837_LDO7_MASK		0x0f
>  
> +#define BD718XX_PWRBTN_PRESS_DURATION_MASK 0xF
> +
> +
>  #endif
> -- 
> 2.30.2
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-01-31  8:23 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-30  7:16 [PATCH] mfd: add regmap driver for rohm-bd718x7 Ahmad Fatoum
2023-01-31  8:22 ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox