summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 06:59:20 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 06:59:20 -1000
commitbfa231bb4c7eae56b9967da19d1678bf0847259d (patch)
tree857a1be5784d9e9600ea1dac5fcd6e4bd67a7eec /drivers/mfd
parent74b1dbf6f236f4fe88bd1077ae4657ca4b2c339e (diff)
parent47f16cf7a6017212230985f6bc7f1b55b6d234d9 (diff)
Merge tag 'gpio-updates-for-v7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio updates from Bartosz Golaszewski: "Nothing stands out as particularly interesting, it's been a calm cycle. We have three new drivers, support for more models and lots of updates across many modules (details are in the signed tag as usual). There are also some minor changes and additions to the in-kernel GPIO API. GPIO core: - provide a new controller API: gpiochip_generic_get_config() - return -EOPNOTSUPP instead of -ENODEV to user-space if it requests hardware timestamping on systems where it's unavailable (no user-space regressions reported) New drivers: - add a driver for ROHM BD73800 PMIC GPIO controller - add a driver for Axiado AX3005 SGPIO controller - add a driver for Analog Devices AD7768 GPIO controller New hardware support: - extend gpio-rcar with support for R-Car X5H (R8A78000) - extend gpio-tegra186 with support for Tegra 268 Driver changes: - refactor and improve gpio-rtd1625: switch to modern or better fitting interfaces and improve coding style - improve error handling of return values of platform_get_irq_optional() in several drivers - normalize the return value of the gpio_chip::get() callback in gpio-siox in order to not propagate invalid values up to the GPIO core - implement gpio_chip::get_direction() for gpio-pcf857x - use managed variants of notifier registration functions in several drivers - remove legacy gpio_set_value_cansleep() as it has no more users - add pinctrl support to gpio-realtek-otto - add runtime PM support to the gpio-regmap helper module - add more ACPI GPIO quirks for various hardware - stop needlessly reading gpio_chip::base in gpio-pxa - add support for tracking of direction of generic GPIO chips with no direction registers via pinctrl backend to gpio-mmio (use the new core API: gpiochip_generic_get_config()) - use the "safe" variants of debugfs_create_file() in gpio-sloppy-analyzer - use device name as GPIO chip label in gpio-omap - refactor bit ops in gpio-dln2 - prepare gpio-it87 for upcoming kmalloc_obj() conversion Devicetree bindings: - document new model in gpio-pca95xx - allow the gpio-hogs property in gpio-zynq and fsl,qoriq-gpio - allow the gpio-ranges property in gpio-realtek-otto Misc fixes: - add missing MODULE_ALIAS() to gpio-crystalcove - fix a comment typo in example GPIO tools - fix unbalanced brackets in documentation - add names to regmaps in gpio-mvebu to avoid collisions in debugfs output - fix GPIO lookup using relative paths in GPIO ACPI" * tag 'gpio-updates-for-v7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (63 commits) gpiolib: acpi: Fix GPIO lookup using relative path gpio: legacy: Kill gpio_set_value_cansleep() dt-bindings: gpio: pca95xx: add onnn,pca9655 with nxp,pca9555 fallback gpiolib: acpi: Ignore GPIO 11 interrupt on Acer Nitro V 16S AI gpio: pxa: stop reading gpio_chip::base in direction callbacks gpio: axiado: add AX3005 SGPIO controller support dt-bindings: gpio: add Axiado AX3005 SGPIO controller gpiolib: acpi: Add quirk for Lenovo IdeaPad Slim 3 15ABR8 MAINTAINERS: Add ROHM BD73800 PMIC files gpio: bd73800: Support ROHM BD73800 PMIC GPIOs clk: bd718x7: Support ROHM BD73800 regulator: bd71828: Support ROHM BD73800 rtc: bd70528: Support RTC on ROHM BD73800 mfd: Support for ROHM BD73800 PMIC core dt-bindings: mfd: ROHM BD73800 PMIC dt-bindings: regulator: ROHM BD73800 regulators dt-bindings: rohm,bd*: Ref common ROHM bindings dt-bindings: mfd: Common ROHM PMIC properties gpio: siox: normalize return value of gpio_get() gpio: dln2: use assign_bit() where applicable ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig15
-rw-r--r--drivers/mfd/rohm-bd71828.c147
2 files changed, 154 insertions, 8 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e4fd4572472f..439dbf5ee110 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2226,7 +2226,7 @@ config MFD_ROHM_BD718XX
and emergency shut down as well as 32,768KHz clock output.
config MFD_ROHM_BD71828
- tristate "ROHM BD718[15/28/79], BD72720 and BD73900 PMICs"
+ tristate "ROHM BD718[15/28/79], BD72720 and BD73[8/9]00 PMICs"
depends on I2C=y
depends on OF
select REGMAP_I2C
@@ -2235,14 +2235,17 @@ config MFD_ROHM_BD71828
select MFD_ROHM_PWRBUTTON
help
Select this option to get support for the ROHM BD71815, BD71828,
- BD71879, BD72720 and BD73900 Power Management ICs (PMICs). These are
- single-chip Power Management ICs (PMIC), mainly for battery-powered
- portable devices.
+ BD71879, BD72720, BD73800 and BD73900 Power Management ICs (PMICs).
+ These are single-chip Power Management ICs (PMIC), mainly for
+ battery-powered portable devices.
The BD71815 has 5 bucks, 7 LDOs, and a boost for driving LEDs.
The BD718[28/79] have 7 buck converters and 7 LDOs.
The BD72720 and the BD73900 have 10 bucks and 11 LDOs.
- All ICs provide a single-cell linear charger, a Coulomb counter,
- a Real-Time Clock (RTC), GPIOs and a 32.768 kHz clock gate.
+ All the above ICs provide a single-cell linear charger, and a Coulomb
+ counter.
+ The BD73800 has 8 bucks, 4 LDOs and ADC for power/current
+ accumulation but no charging logic. All these PMICs integrate also a
+ Real-Time Clock (RTC), GPIOs and a 32.768 kHz clock gate.
config MFD_ROHM_BD957XMUF
tristate "ROHM BD9576MUF and BD9573MUF Power Management ICs"
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index bf4df8e1b34c..46faef7058f8 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2019 ROHM Semiconductors
+ * Copyright (C) 2019, 2026 ROHM Semiconductor
*
- * ROHM BD718[15/28/79] and BD72720 PMIC driver
+ * ROHM BD718[15/28/79], BD72720 and BD73[8/9]00 PMIC driver
*/
#include <linux/i2c.h>
@@ -14,6 +14,7 @@
#include <linux/mfd/rohm-bd71815.h>
#include <linux/mfd/rohm-bd71828.h>
#include <linux/mfd/rohm-bd72720.h>
+#include <linux/mfd/rohm-bd73800.h>
#include <linux/mfd/rohm-generic.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -56,6 +57,12 @@ static const struct resource bd72720_rtc_irqs[] = {
DEFINE_RES_IRQ_NAMED(BD72720_INT_RTC2, "bd70528-rtc-alm-2"),
};
+static const struct resource bd73800_rtc_irqs[] = {
+ DEFINE_RES_IRQ_NAMED(BD73800_INT_RTC0, "bd70528-rtc-alm-0"),
+ DEFINE_RES_IRQ_NAMED(BD73800_INT_RTC1, "bd70528-rtc-alm-1"),
+ DEFINE_RES_IRQ_NAMED(BD73800_INT_RTC2, "bd70528-rtc-alm-2"),
+};
+
static const struct resource bd71815_power_irqs[] = {
DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_RMV, "bd71815-dcin-rmv"),
DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-dcin-clps-out"),
@@ -230,6 +237,17 @@ static const struct mfd_cell bd72720_mfd_cells[] = {
/* Power button is registered separately */
};
+static const struct mfd_cell bd73800_mfd_cells[] = {
+ { .name = "bd73800-pmic", },
+ { .name = "bd73800-clk", },
+ { .name = "bd73800-gpio", },
+ {
+ .name = "bd73800-rtc",
+ .num_resources = ARRAY_SIZE(bd73800_rtc_irqs),
+ .resources = bd73800_rtc_irqs,
+ },
+};
+
static const struct regmap_range bd71815_volatile_ranges[] = {
regmap_reg_range(BD71815_REG_SEC, BD71815_REG_YEAR),
regmap_reg_range(BD71815_REG_CONF, BD71815_REG_BAT_TEMP),
@@ -339,6 +357,17 @@ static const struct regmap_range bd72720_volatile_ranges_4c[] = {
BD72720_UNWRAP_REG_RANGE(BD72720_REG_IMPCHK_CTRL, BD72720_REG_IMPCHK_CTRL),
};
+static const struct regmap_range bd73800_volatile_ranges[] = {
+ regmap_reg_range(BD73800_REG_POR_REASON, BD73800_REG_POW_STATE),
+ regmap_reg_range(BD73800_REG_PS_CTRL_1, BD73800_REG_PS_CTRL_2),
+ regmap_reg_range(BD73800_REG_RCVNUM, BD73800_REG_RCVNUM),
+ regmap_reg_range(BD73800_REG_RTC_SEC, BD73800_REG_RTC_YEAR),
+ regmap_reg_range(BD73800_REG_RTC_CONF, BD73800_REG_RTC_CONF),
+ regmap_reg_range(BD73800_REG_ADC_ACCUM_KICK, BD73800_REG_ADC_TEMP_VAL0),
+ regmap_reg_range(BD73800_REG_INT_MAIN_STAT, BD73800_REG_INT_5_STAT),
+ regmap_reg_range(BD73800_REG_INT_MAIN_SRC, BD73800_REG_INT_5_SRC),
+};
+
static const struct regmap_access_table bd71815_volatile_regs = {
.yes_ranges = &bd71815_volatile_ranges[0],
.n_yes_ranges = ARRAY_SIZE(bd71815_volatile_ranges),
@@ -364,6 +393,24 @@ static const struct regmap_access_table bd72720_volatile_regs_4c = {
.n_yes_ranges = ARRAY_SIZE(bd72720_volatile_ranges_4c),
};
+static const struct regmap_access_table bd73800_volatile_regs = {
+ .yes_ranges = bd73800_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(bd73800_volatile_ranges),
+};
+
+static const struct regmap_range bd73800_read_only_ranges[] = {
+ regmap_reg_range(BD73800_REG_PRODUCT_ID, BD73800_REG_NVMVERSION),
+ regmap_reg_range(BD73800_REG_POW_STATE, BD73800_REG_POW_STATE),
+ regmap_reg_range(BD73800_REG_ADC_ACCUM_CNT2, BD73800_REG_ADC_TEMP_VAL0),
+ regmap_reg_range(BD73800_REG_INT_MAIN_STAT, BD73800_REG_INT_MAIN_STAT),
+ regmap_reg_range(BD73800_REG_INT_MAIN_SRC, BD73800_REG_INT_5_SRC),
+};
+
+static const struct regmap_access_table bd73800_ro_regs = {
+ .no_ranges = bd73800_read_only_ranges,
+ .n_no_ranges = ARRAY_SIZE(bd73800_read_only_ranges),
+};
+
static const struct regmap_config bd71815_regmap = {
.reg_bits = 8,
.val_bits = 8,
@@ -448,6 +495,15 @@ static const struct regmap_config bd72720_regmap_4c = {
.cache_type = REGCACHE_MAPLE,
};
+static const struct regmap_config bd73800_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .wr_table = &bd73800_ro_regs,
+ .volatile_table = &bd73800_volatile_regs,
+ .max_register = BD73800_MAX_REGISTER - 1,
+ .cache_type = REGCACHE_MAPLE,
+};
+
/*
* Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
* access corect sub-IRQ registers based on bits that are set in main IRQ
@@ -779,6 +835,60 @@ static int bd72720_set_type_config(unsigned int **buf, unsigned int type,
return regmap_irq_set_type_config_simple(buf, type, irq_data, idx, irq_drv_data);
}
+static const struct regmap_irq bd73800_irqs[] = {
+ /* INT_STAT_1 register IRQs, ADC and RTC */
+ REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_DONE, 0, BD73800_INT_ADC_ACCUM_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_OVF, 0, BD73800_INT_ADC_ACCUM_OVF_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_VAL, 0, BD73800_INT_ADC_ACCUM_VAL_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_TW, 0, BD73800_INT_ADC_ACCUM_TW_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_ADC_POW_VAL, 0, BD73800_INT_ADC_POW_VAL_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_RTC0, 0, BD73800_INT_RTC0_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_RTC1, 0, BD73800_INT_RTC1_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_RTC2, 0, BD73800_INT_RTC2_MASK),
+
+ /* BUCK reg interrupts */
+ /* INT_STAT_2 IRQs */
+ REGMAP_IRQ_REG(BD73800_INT_BUCK1_DVS_DONE, 1, BD73800_INT_BUCK1_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK2_DVS_DONE, 1, BD73800_INT_BUCK2_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK3_DVS_DONE, 1, BD73800_INT_BUCK3_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK4_DVS_DONE, 1, BD73800_INT_BUCK4_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK5_DVS_DONE, 1, BD73800_INT_BUCK5_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK6_DVS_DONE, 1, BD73800_INT_BUCK6_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK7_DVS_DONE, 1, BD73800_INT_BUCK7_DVS_DONE_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK8_DVS_DONE, 1, BD73800_INT_BUCK8_DVS_DONE_MASK),
+ /* INT_STAT_3 IRQs */
+ REGMAP_IRQ_REG(BD73800_INT_BUCK1_OCP, 2, BD73800_INT_BUCK1_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK2_OCP, 2, BD73800_INT_BUCK2_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK3_OCP, 2, BD73800_INT_BUCK3_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK4_OCP, 2, BD73800_INT_BUCK4_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK5_OCP, 2, BD73800_INT_BUCK5_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK6_OCP, 2, BD73800_INT_BUCK6_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK7_OCP, 2, BD73800_INT_BUCK7_OCP_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_BUCK8_OCP, 2, BD73800_INT_BUCK8_OCP_MASK),
+
+ /* INT_STAT_4 IRQs, power-button, WDG and reset */
+ REGMAP_IRQ_REG(BD73800_INT_PBTN_LONG_PRESS, 3, BD73800_INT_PBTN_LONG_PRESS_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_PBTN_MID_PRESS, 3, BD73800_INT_PBTN_MID_PRESS_MASK),
+ /*
+ * The SHORT_PUSH is generated when button is first pressed (longer
+ * than configured time limit), and then released before the MID_PRESS
+ * time limit. The SHORT_PRESS is generated immediately when button is
+ * pressed for longer than configured limit, whether it is released or
+ * not.
+ */
+ REGMAP_IRQ_REG(BD73800_INT_PBTN_SHORT_PUSH, 3, BD73800_INT_PBTN_SHORT_PUSH_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_PBTN_SHORT_PRESS, 3, BD73800_INT_PBTN_SHORT_PRESS_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_WDG, 3, BD73800_INT_WDG_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_SWRESET, 3, BD73800_INT_SWRESET_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_SEQ_DONE, 3, BD73800_INT_SEQ_DONE_MASK),
+
+ /* INT_STAT_5 IRQs, GPIO */
+ REGMAP_IRQ_REG(BD73800_INT_GPIO1, 4, BD73800_INT_GPIO1_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_GPIO2, 4, BD73800_INT_GPIO2_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_GPIO3, 4, BD73800_INT_GPIO3_MASK),
+ REGMAP_IRQ_REG(BD73800_INT_GPIO4, 4, BD73800_INT_GPIO4_MASK),
+};
+
static const struct regmap_irq_chip bd71828_irq_chip = {
.name = "bd71828_irq",
.main_status = BD71828_REG_INT_MAIN,
@@ -833,6 +943,25 @@ static const struct regmap_irq_chip bd72720_irq_chip = {
.irq_reg_stride = 1,
};
+static const struct regmap_irq_chip bd73800_irq_chip = {
+ .name = "bd73800_irq",
+ .main_status = BD73800_REG_INT_MAIN_STAT,
+ .irqs = bd73800_irqs,
+ .num_irqs = ARRAY_SIZE(bd73800_irqs),
+ .status_base = BD73800_REG_INT_1_STAT,
+ .unmask_base = BD73800_REG_INT_1_EN,
+ .ack_base = BD73800_REG_INT_1_STAT,
+ .init_ack_masked = true,
+ .num_regs = 5,
+ .num_main_regs = 1,
+ /*
+ * Ignore mirrored bits [7:5]. They are handled as part of normal INT_4
+ * handling.
+ */
+ .num_main_status_bits = 5,
+ .irq_reg_stride = 1,
+};
+
static int set_clk_mode(struct device *dev, struct regmap *regmap,
int clkmode_reg)
{
@@ -971,6 +1100,17 @@ static int bd71828_i2c_probe(struct i2c_client *i2c)
main_lvl_val = BD72720_MASK_LVL1_EN_ALL;
break;
}
+ case ROHM_CHIP_TYPE_BD73800:
+ mfd = bd73800_mfd_cells;
+ cells = ARRAY_SIZE(bd73800_mfd_cells);
+ regmap_config = &bd73800_regmap;
+ irqchip = &bd73800_irq_chip;
+ clkmode_reg = BD73800_REG_OUT32K;
+ button_irq = BD73800_INT_PBTN_SHORT_PUSH;
+ main_lvl_mask_reg = BD73800_REG_INT_MAIN_EN;
+ main_lvl_val = BD73800_INT_MAIN_EN_ALL;
+ break;
+
default:
dev_err(&i2c->dev, "Unknown device type");
return -EINVAL;
@@ -1051,6 +1191,9 @@ static const struct of_device_id bd71828_of_match[] = {
}, {
.compatible = "rohm,bd72720",
.data = (void *)ROHM_CHIP_TYPE_BD72720,
+ }, {
+ .compatible = "rohm,bd73800",
+ .data = (void *)ROHM_CHIP_TYPE_BD73800,
},
{ },
};