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@xxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxx>"); > +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 |