diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2023-01-30 08:16:22 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2023-01-31 09:21:52 +0100 |
commit | 09bea7ff6ad8ebc777bb4a6ab138095137042b9c (patch) | |
tree | 65f7d50f9955fd6a9c07c6bc570ed06e537378a9 /drivers/mfd | |
parent | 0497aadf94f2fffa9f742588a3b6b07930031ed4 (diff) | |
download | barebox-09bea7ff6ad8ebc777bb4a6ab138095137042b9c.tar.gz |
mfd: add regmap driver for rohm-bd718x7
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>
Link: https://lore.barebox.org/20230130071622.34094-1-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/Kconfig | 13 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/rohm-bd718x7.c | 140 |
3 files changed, 154 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f1f7e27fad..39a40c2a3f 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 b89ddab594..f19bf53655 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 0000000000..20c572b6d7 --- /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"); |