linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] power: supply: add charger for BD71828
@ 2025-08-21 18:23 Andreas Kemnade
  2025-08-21 18:23 ` [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support Andreas Kemnade
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Andreas Kemnade @ 2025-08-21 18:23 UTC (permalink / raw)
  To: Matti Vaittinen, Lee Jones, Sebastian Reichel
  Cc: linux-kernel, linux-pm, Krzysztof Kozlowski, Andreas Kemnade,
	Matti Vaittinen

Add basic charger which does just read out simple registers without
doing any sophisticated things. 

This is a stripped down version of
https://lore.kernel.org/lkml/dbd97c1b0d715aa35a8b4d79741e433d97c562aa.1637061794.git.matti.vaittinen@fi.rohmeurope.com/

That version includes all the bells-and-whistles you might imagine
around coloumb counter handling and capacity measurement which includes
changes no the power supply core.
Rather do a step by step approach to keep that reviewable.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
Changes in v3:
- remove unused defines
- some minor style nits
- add MAINTAINER entry
- Link to v2: https://lore.kernel.org/r/20250820-bd71828-charger-v2-0-32fc96027e92@kemnade.info

Changes in v2:
- fix some be16 handling reported by bots
- fix some style issues
- do not sneak in additional chip ids
- remove useless debug output 
- remove wrong/useless alias
- remove fuel gauge remains
- fix error checks in temperature reading
- sync properties in switch/case with list
- Link to v1: https://lore.kernel.org/r/20250816-bd71828-charger-v1-0-71b11bde5c73@kemnade.info

---
Andreas Kemnade (2):
      power: supply: Add bd718(15/28/78) charger driver
      MAINTAINERS: Add entry for BD71828 charger

Matti Vaittinen (1):
      mfd: bd71828, bd71815 prepare for power-supply support

 MAINTAINERS                          |    6 +
 drivers/mfd/rohm-bd71828.c           |   44 +-
 drivers/power/supply/Kconfig         |    9 +
 drivers/power/supply/Makefile        |    1 +
 drivers/power/supply/bd71828-power.c | 1060 ++++++++++++++++++++++++++++++++++
 include/linux/mfd/rohm-bd71828.h     |   63 ++
 6 files changed, 1174 insertions(+), 9 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250816-bd71828-charger-9d187346f734

Best regards,
--  
Andreas Kemnade <andreas@kemnade.info>


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

* [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support
  2025-08-21 18:23 [PATCH v3 0/3] power: supply: add charger for BD71828 Andreas Kemnade
@ 2025-08-21 18:23 ` Andreas Kemnade
  2025-09-03 12:23   ` Lee Jones
  2025-08-21 18:23 ` [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver Andreas Kemnade
  2025-08-21 18:23 ` [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger Andreas Kemnade
  2 siblings, 1 reply; 13+ messages in thread
From: Andreas Kemnade @ 2025-08-21 18:23 UTC (permalink / raw)
  To: Matti Vaittinen, Lee Jones, Sebastian Reichel
  Cc: linux-kernel, linux-pm, Krzysztof Kozlowski, Andreas Kemnade,
	Matti Vaittinen

From: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>

Add core support for ROHM BD718(15/28/78) PMIC's charger blocks.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 drivers/mfd/rohm-bd71828.c       | 44 ++++++++++++++++++++++------
 include/linux/mfd/rohm-bd71828.h | 63 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index a14b7aa69c3c6..84a64c3b9c9f5 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -45,8 +45,8 @@ static const struct resource bd71828_rtc_irqs[] = {
 
 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-clps-out"),
-	DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-clps-in"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-dcin-clps-out"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-dcin-clps-in"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_RES, "bd71815-dcin-ovp-res"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_DET, "bd71815-dcin-ovp-det"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_RES, "bd71815-dcin-mon-res"),
@@ -56,7 +56,7 @@ static const struct resource bd71815_power_irqs[] = {
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_RES, "bd71815-vsys-low-res"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_DET, "bd71815-vsys-low-det"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-res"),
-	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-det"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_DET, "bd71815-vsys-mon-det"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TEMP, "bd71815-chg-wdg-temp"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TIME, "bd71815-chg-wdg"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_RES, "bd71815-rechg-res"),
@@ -87,10 +87,10 @@ static const struct resource bd71815_power_irqs[] = {
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_DET, "bd71815-bat-oc2-det"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_RES, "bd71815-bat-oc3-res"),
 	DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_DET, "bd71815-bat-oc3-det"),
-	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-bat-low-res"),
-	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-bat-low-det"),
-	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-bat-hi-res"),
-	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-bat-hi-det"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-temp-bat-low-res"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-temp-bat-low-det"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-temp-bat-hi-res"),
+	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-temp-bat-hi-det"),
 };
 
 static const struct mfd_cell bd71815_mfd_cells[] = {
@@ -109,7 +109,30 @@ static const struct mfd_cell bd71815_mfd_cells[] = {
 	},
 };
 
-static const struct mfd_cell bd71828_mfd_cells[] = {
+static const struct resource bd71828_power_irqs[] = {
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_CHG_TOPOFF_TO_DONE,
+			     "bd71828-chg-done"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_DCIN_DET, "bd71828-pwr-dcin-in"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_DCIN_RMV, "bd71828-pwr-dcin-out"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_BAT_LOW_VOLT_RES,
+			     "bd71828-vbat-normal"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_BAT_LOW_VOLT_DET, "bd71828-vbat-low"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_HI_DET, "bd71828-btemp-hi"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_HI_RES, "bd71828-btemp-cool"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_LOW_DET, "bd71828-btemp-lo"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_LOW_RES,
+			     "bd71828-btemp-warm"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_VF_DET,
+			     "bd71828-temp-hi"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_VF_RES,
+			     "bd71828-temp-norm"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_125_DET,
+			     "bd71828-temp-125-over"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_125_RES,
+			     "bd71828-temp-125-under"),
+};
+
+static struct mfd_cell bd71828_mfd_cells[] = {
 	{ .name = "bd71828-pmic", },
 	{ .name = "bd71828-gpio", },
 	{ .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" },
@@ -118,8 +141,11 @@ static const struct mfd_cell bd71828_mfd_cells[] = {
 	 * BD70528 clock gate are the register address and mask.
 	 */
 	{ .name = "bd71828-clk", },
-	{ .name = "bd71827-power", },
 	{
+		.name = "bd71828-power",
+		.resources = bd71828_power_irqs,
+		.num_resources = ARRAY_SIZE(bd71828_power_irqs),
+	}, {
 		.name = "bd71828-rtc",
 		.resources = bd71828_rtc_irqs,
 		.num_resources = ARRAY_SIZE(bd71828_rtc_irqs),
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
index ce786c96404a3..73a71ef691525 100644
--- a/include/linux/mfd/rohm-bd71828.h
+++ b/include/linux/mfd/rohm-bd71828.h
@@ -189,6 +189,69 @@ enum {
 /* Charger/Battey */
 #define BD71828_REG_CHG_STATE		0x65
 #define BD71828_REG_CHG_FULL		0xd2
+#define BD71828_REG_CHG_EN		0x6F
+#define BD71828_REG_DCIN_STAT		0x68
+#define BD71828_MASK_DCIN_DET		0x01
+#define BD71828_REG_VDCIN_U		0x9c
+#define BD71828_MASK_CHG_EN		0x01
+#define BD71828_CHG_MASK_DCIN_U		0x0f
+#define BD71828_REG_BAT_STAT		0x67
+#define BD71828_REG_BAT_TEMP		0x6c
+#define BD71828_MASK_BAT_TEMP		0x07
+#define BD71828_BAT_TEMP_OPEN		0x07
+#define BD71828_MASK_BAT_DET		0x20
+#define BD71828_MASK_BAT_DET_DONE	0x10
+#define BD71828_REG_CHG_STATE		0x65
+#define BD71828_REG_VBAT_U		0x8c
+#define BD71828_MASK_VBAT_U		0x0f
+#define BD71828_REG_VBAT_REX_AVG_U	0x92
+
+#define BD71828_REG_OCV_PWRON_U		0x8A
+
+#define BD71828_REG_VBAT_MIN_AVG_U	0x8e
+#define BD71828_REG_VBAT_MIN_AVG_L	0x8f
+
+#define BD71828_REG_CC_CNT3		0xb5
+#define BD71828_REG_CC_CNT2		0xb6
+#define BD71828_REG_CC_CNT1		0xb7
+#define BD71828_REG_CC_CNT0		0xb8
+#define BD71828_REG_CC_CURCD_AVG_U	0xb2
+#define BD71828_MASK_CC_CURCD_AVG_U	0x3f
+#define BD71828_MASK_CC_CUR_DIR		0x80
+#define BD71828_REG_VM_BTMP_U		0xa1
+#define BD71828_REG_VM_BTMP_L		0xa2
+#define BD71828_MASK_VM_BTMP_U		0x0f
+#define BD71828_REG_COULOMB_CTRL	0xc4
+#define BD71828_REG_COULOMB_CTRL2	0xd2
+#define BD71828_MASK_REX_CC_CLR		0x01
+#define BD71828_MASK_FULL_CC_CLR	0x10
+#define BD71828_REG_CC_CNT_FULL3	0xbd
+#define BD71828_REG_CC_CNT_CHG3		0xc1
+
+#define BD71828_REG_VBAT_INITIAL1_U	0x86
+#define BD71828_REG_VBAT_INITIAL1_L	0x87
+
+#define BD71828_REG_VBAT_INITIAL2_U	0x88
+#define BD71828_REG_VBAT_INITIAL2_L	0x89
+
+#define BD71828_REG_IBAT_U		0xb0
+#define BD71828_REG_IBAT_L		0xb1
+
+#define BD71828_REG_IBAT_AVG_U		0xb2
+#define BD71828_REG_IBAT_AVG_L		0xb3
+
+#define BD71828_REG_VSYS_AVG_U		0x96
+#define BD71828_REG_VSYS_AVG_L		0x97
+#define BD71828_REG_VSYS_MIN_AVG_U	0x98
+#define BD71828_REG_VSYS_MIN_AVG_L	0x99
+#define BD71828_REG_CHG_SET1		0x75
+#define BD71828_REG_ALM_VBAT_LIMIT_U	0xaa
+#define BD71828_REG_BATCAP_MON_LIMIT_U	0xcc
+#define BD71828_REG_CONF		0x64
+
+#define BD71828_REG_DCIN_CLPS		0x71
+
+#define BD71828_REG_MEAS_CLEAR		0xaf
 
 /* LEDs */
 #define BD71828_REG_LED_CTRL		0x4A

-- 
2.39.5


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

* [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver
  2025-08-21 18:23 [PATCH v3 0/3] power: supply: add charger for BD71828 Andreas Kemnade
  2025-08-21 18:23 ` [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support Andreas Kemnade
@ 2025-08-21 18:23 ` Andreas Kemnade
  2025-08-28  7:45   ` Linus Walleij
  2025-08-21 18:23 ` [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger Andreas Kemnade
  2 siblings, 1 reply; 13+ messages in thread
From: Andreas Kemnade @ 2025-08-21 18:23 UTC (permalink / raw)
  To: Matti Vaittinen, Lee Jones, Sebastian Reichel
  Cc: linux-kernel, linux-pm, Krzysztof Kozlowski, Andreas Kemnade

Add charger driver for ROHM BD718(15/28/78) PMIC charger block.
It is a stripped down version of the driver here:
https://lore.kernel.org/lkml/dbd97c1b0d715aa35a8b4d79741e433d97c562aa.1637061794.git.matti.vaittinen@fi.rohmeurope.com/

For the ease of review and to do a step-by-step approach remove all the
coloumb counter related stuff and do not sneak in BD71827 support. That
also avoids non-trivial rebasing of the above series.

Changes besides that:
Replace the custom property by a standard one and do not use megaohms
for the current sense resistor.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
---
 drivers/power/supply/Kconfig         |    9 +
 drivers/power/supply/Makefile        |    1 +
 drivers/power/supply/bd71828-power.c | 1060 ++++++++++++++++++++++++++++++++++
 3 files changed, 1070 insertions(+)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 79ddb006e2dad..16dddb2355d9b 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -974,6 +974,15 @@ config CHARGER_UCS1002
 	  Say Y to enable support for Microchip UCS1002 Programmable
 	  USB Port Power Controller with Charger Emulation.
 
+config CHARGER_BD71828
+	tristate "Power-supply driver for ROHM BD71828 and BD71815 PMIC"
+	depends on MFD_ROHM_BD71828
+	help
+	  Say Y here to enable support for charger and battery
+	  in ROHM BD71815, BD71817, ROHM BD71828 power management
+	  ICs. This driver gets various bits of information about battery
+	  and charger states.
+
 config CHARGER_BD99954
 	tristate "ROHM bd99954 charger driver"
 	depends on I2C
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index f943c9150b326..c6520a11f021c 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_CHARGER_SC2731)	+= sc2731_charger.o
 obj-$(CONFIG_FUEL_GAUGE_SC27XX)	+= sc27xx_fuel_gauge.o
 obj-$(CONFIG_FUEL_GAUGE_STC3117)       += stc3117_fuel_gauge.o
 obj-$(CONFIG_CHARGER_UCS1002)	+= ucs1002_power.o
+obj-$(CONFIG_CHARGER_BD71828)	+= bd71828-power.o
 obj-$(CONFIG_CHARGER_BD99954)	+= bd99954-charger.o
 obj-$(CONFIG_CHARGER_WILCO)	+= wilco-charger.o
 obj-$(CONFIG_RN5T618_POWER)	+= rn5t618_power.o
diff --git a/drivers/power/supply/bd71828-power.c b/drivers/power/supply/bd71828-power.c
new file mode 100644
index 0000000000000..8f7ece6837df8
--- /dev/null
+++ b/drivers/power/supply/bd71828-power.c
@@ -0,0 +1,1060 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * bd71828-power.c
+ * @file ROHM BD71815, BD71828 and BD71878 Charger driver
+ *
+ * Copyright 2021.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/rohm-bd71815.h>
+#include <linux/mfd/rohm-bd71828.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+/* common defines */
+#define BD7182x_MASK_VBAT_U			0x1f
+#define BD7182x_MASK_VDCIN_U			0x0f
+#define BD7182x_MASK_IBAT_U			0x3f
+#define BD7182x_MASK_CURDIR_DISCHG		0x80
+#define BD7182x_MASK_CHG_STATE			0x7f
+#define BD7182x_MASK_BAT_TEMP			0x07
+#define BD7182x_MASK_DCIN_DET			BIT(0)
+#define BD7182x_MASK_CONF_PON			BIT(0)
+#define BD71815_MASK_CONF_XSTB			BIT(1)
+#define BD7182x_MASK_BAT_STAT			0x3f
+#define BD7182x_MASK_DCIN_STAT			0x07
+
+#define BD7182x_MASK_WDT_AUTO			0x40
+#define BD7182x_MASK_VBAT_ALM_LIMIT_U		0x01
+#define BD7182x_MASK_CHG_EN			0x01
+
+#define BD7182x_DCIN_COLLAPSE_DEFAULT		0x36
+
+#define MAX_CURRENT_DEFAULT			890000		/* uA */
+#define AC_NAME					"bd71828_ac"
+#define BAT_NAME				"bd71828_bat"
+
+/*
+ * VBAT Low voltage detection Threshold
+ * 0x00D4*16mV = 212*0.016 = 3.392v
+ */
+#define VBAT_LOW_TH			0x00D4
+
+struct pwr_regs {
+	u8 vbat_avg;
+	u8 ibat;
+	u8 ibat_avg;
+	u8 btemp_vth;
+	u8 chg_state;
+	u8 bat_temp;
+	u8 dcin_stat;
+	u8 dcin_collapse_limit;
+	u8 chg_set1;
+	u8 chg_en;
+	u8 vbat_alm_limit_u;
+	u8 conf;
+	u8 vdcin;
+};
+
+static const struct pwr_regs pwr_regs_bd71828 = {
+	.vbat_avg = BD71828_REG_VBAT_U,
+	.ibat = BD71828_REG_IBAT_U,
+	.ibat_avg = BD71828_REG_IBAT_AVG_U,
+	.btemp_vth = BD71828_REG_VM_BTMP_U,
+	.chg_state = BD71828_REG_CHG_STATE,
+	.bat_temp = BD71828_REG_BAT_TEMP,
+	.dcin_stat = BD71828_REG_DCIN_STAT,
+	.dcin_collapse_limit = BD71828_REG_DCIN_CLPS,
+	.chg_set1 = BD71828_REG_CHG_SET1,
+	.chg_en   = BD71828_REG_CHG_EN,
+	.vbat_alm_limit_u = BD71828_REG_ALM_VBAT_LIMIT_U,
+	.conf = BD71828_REG_CONF,
+	.vdcin = BD71828_REG_VDCIN_U,
+};
+
+static const struct pwr_regs pwr_regs_bd71815 = {
+	.vbat_avg = BD71815_REG_VM_SA_VBAT_U,
+	/* BD71815 does not have separate current and current avg */
+	.ibat = BD71815_REG_CC_CURCD_U,
+	.ibat_avg = BD71815_REG_CC_CURCD_U,
+
+	.btemp_vth = BD71815_REG_VM_BTMP,
+	.chg_state = BD71815_REG_CHG_STATE,
+	.bat_temp = BD71815_REG_BAT_TEMP,
+	.dcin_stat = BD71815_REG_DCIN_STAT,
+	.dcin_collapse_limit = BD71815_REG_DCIN_CLPS,
+	.chg_set1 = BD71815_REG_CHG_SET1,
+	.chg_en   = BD71815_REG_CHG_SET1,
+	.vbat_alm_limit_u = BD71815_REG_ALM_VBAT_TH_U,
+	.conf = BD71815_REG_CONF,
+
+	.vdcin = BD71815_REG_VM_DCIN_U,
+};
+
+struct bd71828_power {
+	struct regmap *regmap;
+	enum rohm_chip_type chip_type;
+	struct device *dev;
+	struct power_supply *ac;
+	struct power_supply *bat;
+
+	const struct pwr_regs *regs;
+	/* Reg val to uA */
+	int curr_factor;
+	int rsens;
+	int (*get_temp)(struct bd71828_power *pwr, int *temp);
+	int (*bat_inserted)(struct bd71828_power *pwr);
+};
+
+static int bd7182x_write16(struct bd71828_power *pwr, int reg, u16 val)
+{
+	__be16 tmp;
+
+	tmp = cpu_to_be16(val);
+
+	return regmap_bulk_write(pwr->regmap, reg, &tmp, sizeof(tmp));
+}
+
+static int bd7182x_read16_himask(struct bd71828_power *pwr, int reg, int himask,
+				 u16 *val)
+{
+	struct regmap *regmap = pwr->regmap;
+	int ret;
+	__be16 rvals;
+	u8 *tmp = (u8 *)&rvals;
+
+	ret = regmap_bulk_read(regmap, reg, &rvals, sizeof(*val));
+	if (!ret) {
+		*tmp &= himask;
+		*val = be16_to_cpu(rvals);
+	}
+
+	return ret;
+}
+
+static int bd71828_get_vbat(struct bd71828_power *pwr, int *vcell)
+{
+	u16 tmp_vcell;
+	int ret;
+
+	ret = bd7182x_read16_himask(pwr, pwr->regs->vbat_avg,
+				    BD7182x_MASK_VBAT_U, &tmp_vcell);
+	if (ret)
+		dev_err(pwr->dev, "Failed to read battery average voltage\n");
+	else
+		*vcell = ((int)tmp_vcell) * 1000;
+
+	return ret;
+}
+
+static int bd71828_get_current_ds_adc(struct bd71828_power *pwr, int *curr, int *curr_avg)
+{
+	__be16 tmp_curr;
+	char *tmp = (char *)&tmp_curr;
+	int dir = 1;
+	int regs[] = { pwr->regs->ibat, pwr->regs->ibat_avg };
+	int *vals[] = { curr, curr_avg };
+	int ret, i;
+
+	for (dir = 1, i = 0; i < ARRAY_SIZE(regs); i++) {
+		ret = regmap_bulk_read(pwr->regmap, regs[i], &tmp_curr,
+				       sizeof(tmp_curr));
+		if (ret)
+			break;
+
+		if (*tmp & BD7182x_MASK_CURDIR_DISCHG)
+			dir = -1;
+
+		*tmp &= BD7182x_MASK_IBAT_U;
+
+		*vals[i] = dir * ((int)be16_to_cpu(tmp_curr)) * pwr->curr_factor;
+	}
+
+	return ret;
+}
+
+/* Unit is tenths of degree C */
+static int bd71815_get_temp(struct bd71828_power *pwr, int *temp)
+{
+	struct regmap *regmap = pwr->regmap;
+	int ret;
+	int t;
+
+	ret = regmap_read(regmap, pwr->regs->btemp_vth, &t);
+	if (ret)
+		return ret;
+
+	t = 200 - t;
+
+	if (t > 200) {
+		dev_err(pwr->dev, "Failed to read battery temperature\n");
+		return -ENODATA;
+	}
+
+	return 0;
+}
+
+/* Unit is tenths of degree C */
+static int bd71828_get_temp(struct bd71828_power *pwr, int *temp)
+{
+	u16 t;
+	int ret;
+	int tmp = 200 * 10000;
+
+	ret = bd7182x_read16_himask(pwr, pwr->regs->btemp_vth,
+				    BD71828_MASK_VM_BTMP_U, &t);
+	if (ret)
+		return ret;
+
+	if (t > 3200) {
+		dev_err(pwr->dev,
+			"Failed to read battery temperature\n");
+		return -ENODATA;
+	}
+
+	tmp -= 625ULL * (unsigned int)t;
+	*temp = tmp / 1000;
+
+	return ret;
+}
+
+static int bd71828_charge_status(struct bd71828_power *pwr,
+				 int *s, int *h)
+{
+	unsigned int state;
+	int status, health;
+	int ret = 1;
+
+	ret = regmap_read(pwr->regmap, pwr->regs->chg_state, &state);
+	if (ret) {
+		dev_err(pwr->dev, "charger status reading failed (%d)\n", ret);
+		return ret;
+	}
+
+	state &= BD7182x_MASK_CHG_STATE;
+
+	dev_dbg(pwr->dev, "CHG_STATE %d\n", state);
+
+	switch (state) {
+	case 0x00:
+		ret = 0;
+		status = POWER_SUPPLY_STATUS_DISCHARGING;
+		health = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+	case 0x01:
+	case 0x02:
+	case 0x03:
+	case 0x0E:
+		status = POWER_SUPPLY_STATUS_CHARGING;
+		health = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+	case 0x0F:
+		ret = 0;
+		status = POWER_SUPPLY_STATUS_FULL;
+		health = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+	case 0x10:
+	case 0x11:
+	case 0x12:
+	case 0x13:
+	case 0x14:
+	case 0x20:
+	case 0x21:
+	case 0x22:
+	case 0x23:
+	case 0x24:
+		ret = 0;
+		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		health = POWER_SUPPLY_HEALTH_OVERHEAT;
+		break;
+	case 0x30:
+	case 0x31:
+	case 0x32:
+	case 0x40:
+		ret = 0;
+		status = POWER_SUPPLY_STATUS_DISCHARGING;
+		health = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+	case 0x7f:
+	default:
+		ret = 0;
+		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		health = POWER_SUPPLY_HEALTH_DEAD;
+		break;
+	}
+
+	if (s)
+		*s = status;
+	if (h)
+		*h = health;
+
+	return ret;
+}
+
+static int get_chg_online(struct bd71828_power *pwr, int *chg_online)
+{
+	int r, ret;
+
+	ret = regmap_read(pwr->regmap, pwr->regs->dcin_stat, &r);
+	if (ret) {
+		dev_err(pwr->dev, "Failed to read DCIN status\n");
+		return ret;
+	}
+	*chg_online = ((r & BD7182x_MASK_DCIN_DET) != 0);
+
+	return 0;
+}
+
+static int get_bat_online(struct bd71828_power *pwr, int *bat_online)
+{
+	int r, ret;
+
+#define BAT_OPEN	0x7
+	ret = regmap_read(pwr->regmap, pwr->regs->bat_temp, &r);
+	if (ret) {
+		dev_err(pwr->dev, "Failed to read battery temperature\n");
+		return ret;
+	}
+	*bat_online = ((r & BD7182x_MASK_BAT_TEMP) != BAT_OPEN);
+
+	return 0;
+}
+
+static int bd71828_bat_inserted(struct bd71828_power *pwr)
+{
+	int ret, val;
+
+	ret = regmap_read(pwr->regmap, pwr->regs->conf, &val);
+	if (ret) {
+		dev_err(pwr->dev, "Failed to read CONF register\n");
+		return 0;
+	}
+	ret = val & BD7182x_MASK_CONF_PON;
+
+	if (ret)
+		regmap_update_bits(pwr->regmap, pwr->regs->conf,
+				   BD7182x_MASK_CONF_PON, 0);
+
+	return ret;
+}
+
+static int bd71815_bat_inserted(struct bd71828_power *pwr)
+{
+	int ret, val;
+
+	ret = regmap_read(pwr->regmap, pwr->regs->conf, &val);
+	if (ret) {
+		dev_err(pwr->dev, "Failed to read CONF register\n");
+		return ret;
+	}
+
+	ret = !(val & BD71815_MASK_CONF_XSTB);
+	if (ret)
+		regmap_write(pwr->regmap, pwr->regs->conf,  val |
+			     BD71815_MASK_CONF_XSTB);
+
+	return ret;
+}
+
+static int bd71828_init_hardware(struct bd71828_power *pwr)
+{
+	int ret;
+
+	/* TODO: Collapse limit should come from device-tree ? */
+	ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit,
+			   BD7182x_DCIN_COLLAPSE_DEFAULT);
+	if (ret) {
+		dev_err(pwr->dev, "Failed to write DCIN collapse limit\n");
+		return ret;
+	}
+
+	ret = pwr->bat_inserted(pwr);
+	if (ret < 0)
+		return ret;
+
+	if (ret) {
+		/* WDT_FST auto set */
+		ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_set1,
+					 BD7182x_MASK_WDT_AUTO,
+					 BD7182x_MASK_WDT_AUTO);
+		if (ret)
+			return ret;
+
+		ret = bd7182x_write16(pwr, pwr->regs->vbat_alm_limit_u,
+				      VBAT_LOW_TH);
+		if (ret)
+			return ret;
+
+		/*
+		 * On BD71815 "we mask the power-state" from relax detection.
+		 * I am unsure what the impact of the power-state would be if
+		 * we didn't - but this is what the vendor driver did - and
+		 * that driver has been used in few projects so I just assume
+		 * this is needed.
+		 */
+		if (pwr->chip_type == ROHM_CHIP_TYPE_BD71815) {
+			ret = regmap_set_bits(pwr->regmap,
+					      BD71815_REG_REX_CTRL_1,
+					      REX_PMU_STATE_MASK);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int bd71828_charger_get_property(struct power_supply *psy,
+					enum power_supply_property psp,
+					union power_supply_propval *val)
+{
+	struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
+	u32 vot;
+	u16 tmp;
+	int online;
+	int ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		ret = get_chg_online(pwr, &online);
+		if (!ret)
+			val->intval = online;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = bd7182x_read16_himask(pwr, pwr->regs->vdcin,
+					    BD7182x_MASK_VDCIN_U, &tmp);
+		if (ret)
+			return ret;
+
+		vot = tmp;
+		/* 5 milli volt steps */
+		val->intval = 5000 * vot;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int bd71828_battery_get_property(struct power_supply *psy,
+					enum power_supply_property psp,
+					union power_supply_propval *val)
+{
+	struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
+	int ret = 0;
+	int status, health, tmp, curr, curr_avg, chg_en;
+
+	if (psp == POWER_SUPPLY_PROP_STATUS ||
+	    psp == POWER_SUPPLY_PROP_HEALTH ||
+	    psp == POWER_SUPPLY_PROP_CHARGE_TYPE)
+		ret = bd71828_charge_status(pwr, &status, &health);
+	else if (psp == POWER_SUPPLY_PROP_CURRENT_AVG ||
+		 psp == POWER_SUPPLY_PROP_CURRENT_NOW)
+		ret = bd71828_get_current_ds_adc(pwr, &curr, &curr_avg);
+	if (ret)
+		return ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = status;
+		break;
+	case POWER_SUPPLY_PROP_HEALTH:
+		val->intval = health;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		ret = get_bat_online(pwr, &tmp);
+		if (!ret)
+			val->intval = tmp;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = bd71828_get_vbat(pwr, &tmp);
+		val->intval = tmp;
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_AVG:
+		val->intval = curr_avg;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		val->intval = curr;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		val->intval = MAX_CURRENT_DEFAULT;
+		break;
+	case POWER_SUPPLY_PROP_TEMP:
+		ret = pwr->get_temp(pwr, &val->intval);
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+		ret = regmap_read(pwr->regmap, pwr->regs->chg_en, &chg_en);
+		if (ret)
+			return ret;
+
+		val->intval = (chg_en & BD7182x_MASK_CHG_EN) ?
+			POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO :
+			POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int bd71828_battery_set_property(struct power_supply *psy,
+					enum power_supply_property psp,
+					const union power_supply_propval *val)
+{
+	struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
+	int ret = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+		if (val->intval == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO)
+			ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en,
+						 BD7182x_MASK_CHG_EN,
+						 BD7182x_MASK_CHG_EN);
+		else
+			ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en,
+						 BD7182x_MASK_CHG_EN,
+						 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int bd71828_battery_property_is_writeable(struct power_supply *psy,
+						 enum power_supply_property psp)
+{
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/** @brief ac properties */
+static const enum power_supply_property bd71828_charger_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static const enum power_supply_property bd71828_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+	POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
+};
+
+/** @brief powers supplied by bd71828_ac */
+static char *bd71828_ac_supplied_to[] = {
+	BAT_NAME,
+};
+
+static const struct power_supply_desc bd71828_ac_desc = {
+	.name		= AC_NAME,
+	.type		= POWER_SUPPLY_TYPE_MAINS,
+	.properties	= bd71828_charger_props,
+	.num_properties	= ARRAY_SIZE(bd71828_charger_props),
+	.get_property	= bd71828_charger_get_property,
+};
+
+static const struct power_supply_desc bd71828_bat_desc = {
+	.name		= BAT_NAME,
+	.type		= POWER_SUPPLY_TYPE_BATTERY,
+	.charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) |
+			     BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE),
+	.properties	= bd71828_battery_props,
+	.num_properties = ARRAY_SIZE(bd71828_battery_props),
+	.get_property	= bd71828_battery_get_property,
+	.set_property	= bd71828_battery_set_property,
+	.property_is_writeable   = bd71828_battery_property_is_writeable,
+};
+
+#define RSENS_CURR 10000000LLU
+
+#define BD_ISR_NAME(name) \
+bd7181x_##name##_isr
+
+#define BD_ISR_BAT(name, print, run_gauge)				\
+static irqreturn_t BD_ISR_NAME(name)(int irq, void *data)		\
+{									\
+	struct bd71828_power *pwr = (struct bd71828_power *)data;	\
+									\
+	dev_dbg(pwr->dev, "%s\n", print);				\
+	power_supply_changed(pwr->bat);				\
+									\
+	return IRQ_HANDLED;						\
+}
+
+#define BD_ISR_AC(name, print, run_gauge)				\
+static irqreturn_t BD_ISR_NAME(name)(int irq, void *data)		\
+{									\
+	struct bd71828_power *pwr = (struct bd71828_power *)data;	\
+									\
+	power_supply_changed(pwr->ac);					\
+	dev_dbg(pwr->dev, "%s\n", print);				\
+	power_supply_changed(pwr->bat);				\
+									\
+	return IRQ_HANDLED;						\
+}
+
+#define BD_ISR_DUMMY(name, print)					\
+static irqreturn_t BD_ISR_NAME(name)(int irq, void *data)		\
+{									\
+	struct bd71828_power *pwr = (struct bd71828_power *)data;	\
+									\
+	dev_dbg(pwr->dev, "%s\n", print);				\
+									\
+	return IRQ_HANDLED;						\
+}
+
+BD_ISR_BAT(chg_state_changed, "CHG state changed", true)
+/* DCIN voltage changes */
+BD_ISR_AC(dcin_removed, "DCIN removed", true)
+BD_ISR_AC(clps_out, "DCIN voltage back to normal", true)
+BD_ISR_AC(clps_in, "DCIN voltage collapsed", false)
+BD_ISR_AC(dcin_ovp_res, "DCIN voltage normal", true)
+BD_ISR_AC(dcin_ovp_det, "DCIN OVER VOLTAGE", true)
+
+BD_ISR_DUMMY(dcin_mon_det, "DCIN voltage below threshold")
+BD_ISR_DUMMY(dcin_mon_res, "DCIN voltage above threshold")
+
+BD_ISR_DUMMY(vsys_uv_res, "VSYS under-voltage cleared")
+BD_ISR_DUMMY(vsys_uv_det, "VSYS under-voltage")
+BD_ISR_DUMMY(vsys_low_res, "'VSYS low' cleared")
+BD_ISR_DUMMY(vsys_low_det, "VSYS low")
+BD_ISR_DUMMY(vsys_mon_res, "VSYS mon - resumed")
+BD_ISR_DUMMY(vsys_mon_det, "VSYS mon - detected")
+BD_ISR_BAT(chg_wdg_temp, "charger temperature watchdog triggered", true)
+BD_ISR_BAT(chg_wdg, "charging watchdog triggered", true)
+BD_ISR_BAT(bat_removed, "Battery removed", true)
+BD_ISR_BAT(bat_det, "Battery detected", true)
+/* TODO: Verify the meaning of these interrupts */
+BD_ISR_BAT(rechg_det, "Recharging", true)
+BD_ISR_BAT(rechg_res, "Recharge ending", true)
+BD_ISR_DUMMY(temp_transit, "Temperature transition")
+BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false)
+BD_ISR_BAT(therm_det, "bd71815-therm-det", true)
+BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false)
+BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true)
+BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false)
+BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true)
+BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true)
+BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true)
+/* What should we do here? */
+BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false)
+BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true)
+BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true)
+BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false)
+BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true)
+BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false)
+BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true)
+BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false)
+BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true)
+BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false)
+BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true)
+BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true)
+BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true)
+BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true)
+
+static irqreturn_t bd7182x_dcin_removed(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	power_supply_changed(pwr->ac);
+	dev_dbg(pwr->dev, "DCIN removed\n");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd718x7_chg_done(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd7182x_dcin_detected(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "DCIN inserted\n");
+	power_supply_changed(pwr->ac);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_vbat_low_res(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "VBAT LOW Resumed\n");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_vbat_low_det(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "VBAT LOW Detected\n");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_bat_hi_det(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_warn(pwr->dev, "Overtemp Detected\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_bat_hi_res(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "Overtemp Resumed\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_bat_low_det(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "Lowtemp Detected\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_bat_low_res(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "Lowtemp Resumed\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_vf_det(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "VF Detected\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_vf_res(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "VF Resumed\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_vf125_det(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "VF125 Detected\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t bd71828_temp_vf125_res(int irq, void *data)
+{
+	struct bd71828_power *pwr = (struct bd71828_power *)data;
+
+	dev_dbg(pwr->dev, "VF125 Resumed\n");
+	power_supply_changed(pwr->bat);
+
+	return IRQ_HANDLED;
+}
+
+struct bd7182x_irq_res {
+	const char *name;
+	irq_handler_t handler;
+};
+
+#define BDIRQ(na, hn) { .name = (na), .handler = (hn) }
+
+static int bd7182x_get_irqs(struct platform_device *pdev,
+			    struct bd71828_power *pwr)
+{
+	int i, irq, ret;
+	static const struct bd7182x_irq_res bd71815_irqs[] = {
+		BDIRQ("bd71815-dcin-rmv", BD_ISR_NAME(dcin_removed)),
+		BDIRQ("bd71815-dcin-clps-out", BD_ISR_NAME(clps_out)),
+		BDIRQ("bd71815-dcin-clps-in", BD_ISR_NAME(clps_in)),
+		BDIRQ("bd71815-dcin-ovp-res", BD_ISR_NAME(dcin_ovp_res)),
+		BDIRQ("bd71815-dcin-ovp-det", BD_ISR_NAME(dcin_ovp_det)),
+		BDIRQ("bd71815-dcin-mon-res", BD_ISR_NAME(dcin_mon_res)),
+		BDIRQ("bd71815-dcin-mon-det", BD_ISR_NAME(dcin_mon_det)),
+
+		BDIRQ("bd71815-vsys-uv-res", BD_ISR_NAME(vsys_uv_res)),
+		BDIRQ("bd71815-vsys-uv-det", BD_ISR_NAME(vsys_uv_det)),
+		BDIRQ("bd71815-vsys-low-res", BD_ISR_NAME(vsys_low_res)),
+		BDIRQ("bd71815-vsys-low-det",  BD_ISR_NAME(vsys_low_det)),
+		BDIRQ("bd71815-vsys-mon-res",  BD_ISR_NAME(vsys_mon_res)),
+		BDIRQ("bd71815-vsys-mon-det",  BD_ISR_NAME(vsys_mon_det)),
+		BDIRQ("bd71815-chg-wdg-temp", BD_ISR_NAME(chg_wdg_temp)),
+		BDIRQ("bd71815-chg-wdg",  BD_ISR_NAME(chg_wdg)),
+		BDIRQ("bd71815-rechg-det", BD_ISR_NAME(rechg_det)),
+		BDIRQ("bd71815-rechg-res", BD_ISR_NAME(rechg_res)),
+		BDIRQ("bd71815-ranged-temp-transit", BD_ISR_NAME(temp_transit)),
+		BDIRQ("bd71815-chg-state-change", BD_ISR_NAME(chg_state_changed)),
+		BDIRQ("bd71815-bat-temp-normal", bd71828_temp_bat_hi_res),
+		BDIRQ("bd71815-bat-temp-erange", bd71828_temp_bat_hi_det),
+		BDIRQ("bd71815-bat-rmv", BD_ISR_NAME(bat_removed)),
+		BDIRQ("bd71815-bat-det", BD_ISR_NAME(bat_det)),
+
+		/* Add ISRs for these */
+		BDIRQ("bd71815-therm-rmv", BD_ISR_NAME(therm_rmv)),
+		BDIRQ("bd71815-therm-det", BD_ISR_NAME(therm_det)),
+		BDIRQ("bd71815-bat-dead", BD_ISR_NAME(bat_dead)),
+		BDIRQ("bd71815-bat-short-res", BD_ISR_NAME(bat_short_res)),
+		BDIRQ("bd71815-bat-short-det", BD_ISR_NAME(bat_short)),
+		BDIRQ("bd71815-bat-low-res", BD_ISR_NAME(bat_low_res)),
+		BDIRQ("bd71815-bat-low-det", BD_ISR_NAME(bat_low)),
+		BDIRQ("bd71815-bat-over-res", BD_ISR_NAME(bat_ov_res)),
+		BDIRQ("bd71815-bat-over-det", BD_ISR_NAME(bat_ov)),
+		BDIRQ("bd71815-bat-mon-res", BD_ISR_NAME(bat_mon_res)),
+		BDIRQ("bd71815-bat-mon-det", BD_ISR_NAME(bat_mon)),
+		/* cc-mon 1 & 3 ? */
+		BDIRQ("bd71815-bat-cc-mon2", BD_ISR_NAME(bat_cc_mon)),
+		BDIRQ("bd71815-bat-oc1-res", BD_ISR_NAME(bat_oc1_res)),
+		BDIRQ("bd71815-bat-oc1-det", BD_ISR_NAME(bat_oc1)),
+		BDIRQ("bd71815-bat-oc2-res", BD_ISR_NAME(bat_oc2_res)),
+		BDIRQ("bd71815-bat-oc2-det", BD_ISR_NAME(bat_oc2)),
+		BDIRQ("bd71815-bat-oc3-res", BD_ISR_NAME(bat_oc3_res)),
+		BDIRQ("bd71815-bat-oc3-det", BD_ISR_NAME(bat_oc3)),
+		BDIRQ("bd71815-temp-bat-low-res", BD_ISR_NAME(temp_bat_low_res)),
+		BDIRQ("bd71815-temp-bat-low-det", BD_ISR_NAME(temp_bat_low)),
+		BDIRQ("bd71815-temp-bat-hi-res", BD_ISR_NAME(temp_bat_hi_res)),
+		BDIRQ("bd71815-temp-bat-hi-det", BD_ISR_NAME(temp_bat_hi)),
+		/*
+		 * TODO: add rest of the IRQs and re-check the handling.
+		 * Check the bd71815-bat-cc-mon1, bd71815-bat-cc-mon3,
+		 * bd71815-bat-low-res, bd71815-bat-low-det,
+		 * bd71815-bat-hi-res, bd71815-bat-hi-det.
+		 */
+	};
+	static const struct bd7182x_irq_res bd71828_irqs[] = {
+		BDIRQ("bd71828-chg-done", bd718x7_chg_done),
+		BDIRQ("bd71828-pwr-dcin-in", bd7182x_dcin_detected),
+		BDIRQ("bd71828-pwr-dcin-out", bd7182x_dcin_removed),
+		BDIRQ("bd71828-vbat-normal", bd71828_vbat_low_res),
+		BDIRQ("bd71828-vbat-low", bd71828_vbat_low_det),
+		BDIRQ("bd71828-btemp-hi", bd71828_temp_bat_hi_det),
+		BDIRQ("bd71828-btemp-cool", bd71828_temp_bat_hi_res),
+		BDIRQ("bd71828-btemp-lo", bd71828_temp_bat_low_det),
+		BDIRQ("bd71828-btemp-warm", bd71828_temp_bat_low_res),
+		BDIRQ("bd71828-temp-hi", bd71828_temp_vf_det),
+		BDIRQ("bd71828-temp-norm", bd71828_temp_vf_res),
+		BDIRQ("bd71828-temp-125-over", bd71828_temp_vf125_det),
+		BDIRQ("bd71828-temp-125-under", bd71828_temp_vf125_res),
+	};
+	int num_irqs;
+	const struct bd7182x_irq_res *irqs;
+
+	switch (pwr->chip_type) {
+	case ROHM_CHIP_TYPE_BD71828:
+		irqs = &bd71828_irqs[0];
+		num_irqs = ARRAY_SIZE(bd71828_irqs);
+		break;
+	case ROHM_CHIP_TYPE_BD71815:
+		irqs = &bd71815_irqs[0];
+		num_irqs = ARRAY_SIZE(bd71815_irqs);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_irqs; i++) {
+		irq = platform_get_irq_byname(pdev, irqs[i].name);
+
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+						irqs[i].handler, 0,
+						irqs[i].name, pwr);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+#define RSENS_DEFAULT_30MOHM 30000 /* 30 mOhm in uOhms*/
+
+static int bd7182x_get_rsens(struct bd71828_power *pwr)
+{
+	u64 tmp = RSENS_CURR;
+	int rsens_ohm = RSENS_DEFAULT_30MOHM;
+	struct fwnode_handle *node = NULL;
+
+	if (pwr->dev->parent)
+		node = dev_fwnode(pwr->dev->parent);
+
+	if (node) {
+		int ret;
+		u32 rs;
+
+		ret = fwnode_property_read_u32(node,
+					       "rohm,charger-sense-resistor-micro-ohms",
+					       &rs);
+		if (ret) {
+			if (ret == -EINVAL) {
+				rs = RSENS_DEFAULT_30MOHM;
+			} else {
+				dev_err(pwr->dev, "Bad RSENS dt property\n");
+				return ret;
+			}
+		}
+		if (!rs) {
+			dev_err(pwr->dev, "Bad RSENS value\n");
+			return -EINVAL;
+		}
+
+		rsens_ohm = (int)rs;
+	}
+
+	/* Reg val to uA */
+	do_div(tmp, rsens_ohm);
+
+	pwr->curr_factor = tmp;
+	pwr->rsens = rsens_ohm;
+	dev_dbg(pwr->dev, "Setting rsens to %u micro ohm\n", pwr->rsens);
+	dev_dbg(pwr->dev, "Setting curr-factor to %u\n", pwr->curr_factor);
+
+	return 0;
+}
+
+static int bd71828_power_probe(struct platform_device *pdev)
+{
+	struct bd71828_power *pwr;
+	struct power_supply_config ac_cfg = {};
+	struct power_supply_config bat_cfg = {};
+	int ret;
+	struct regmap *regmap;
+
+	regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!regmap) {
+		dev_err(&pdev->dev, "No parent regmap\n");
+		return -EINVAL;
+	}
+
+	pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL);
+	if (!pwr)
+		return -ENOMEM;
+
+	pwr->regmap = regmap;
+	pwr->dev = &pdev->dev;
+	pwr->chip_type = platform_get_device_id(pdev)->driver_data;
+
+	switch (pwr->chip_type) {
+	case ROHM_CHIP_TYPE_BD71828:
+		pwr->bat_inserted = bd71828_bat_inserted;
+		pwr->get_temp = bd71828_get_temp;
+		pwr->regs = &pwr_regs_bd71828;
+		break;
+	case ROHM_CHIP_TYPE_BD71815:
+		pwr->bat_inserted = bd71815_bat_inserted;
+		pwr->get_temp = bd71815_get_temp;
+		pwr->regs = &pwr_regs_bd71815;
+		break;
+	default:
+		dev_err(pwr->dev, "Unknown PMIC\n");
+		return -EINVAL;
+	}
+
+	ret = bd7182x_get_rsens(pwr);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "sense resistor missing\n");
+
+	dev_set_drvdata(&pdev->dev, pwr);
+	bd71828_init_hardware(pwr);
+
+	bat_cfg.drv_data	= pwr;
+	bat_cfg.fwnode		= dev_fwnode(&pdev->dev);
+
+	ac_cfg.supplied_to	= bd71828_ac_supplied_to;
+	ac_cfg.num_supplicants	= ARRAY_SIZE(bd71828_ac_supplied_to);
+	ac_cfg.drv_data		= pwr;
+
+	pwr->ac = devm_power_supply_register(&pdev->dev, &bd71828_ac_desc,
+					     &ac_cfg);
+	if (IS_ERR(pwr->ac))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pwr->ac),
+				     "failed to register ac\n");
+
+	pwr->bat = devm_power_supply_register(&pdev->dev, &bd71828_bat_desc,
+					      &bat_cfg);
+	if (IS_ERR(pwr->bat))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pwr->bat),
+				     "failed to register bat\n");
+
+	ret = bd7182x_get_irqs(pdev, pwr);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to request IRQs");
+
+	/* Configure wakeup capable */
+	device_set_wakeup_capable(pwr->dev, 1);
+	device_set_wakeup_enable(pwr->dev, 1);
+
+	return 0;
+}
+
+static const struct platform_device_id bd71828_charger_id[] = {
+	{ "bd71815-power", ROHM_CHIP_TYPE_BD71815 },
+	{ "bd71828-power", ROHM_CHIP_TYPE_BD71828 },
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, bd71828_charger_id);
+
+static struct platform_driver bd71828_power_driver = {
+	.driver = {
+		.name = "bd718xx-power",
+	},
+	.probe = bd71828_power_probe,
+	.id_table = bd71828_charger_id,
+};
+
+module_platform_driver(bd71828_power_driver);
+
+MODULE_AUTHOR("Cong Pham <cpham2403@gmail.com>");
+MODULE_DESCRIPTION("ROHM BD718(15/28/78) PMIC Battery Charger driver");
+MODULE_LICENSE("GPL");

-- 
2.39.5


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

* [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger
  2025-08-21 18:23 [PATCH v3 0/3] power: supply: add charger for BD71828 Andreas Kemnade
  2025-08-21 18:23 ` [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support Andreas Kemnade
  2025-08-21 18:23 ` [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver Andreas Kemnade
@ 2025-08-21 18:23 ` Andreas Kemnade
  2025-08-22  5:15   ` Matti Vaittinen
  2025-08-22  5:17   ` Matti Vaittinen
  2 siblings, 2 replies; 13+ messages in thread
From: Andreas Kemnade @ 2025-08-21 18:23 UTC (permalink / raw)
  To: Matti Vaittinen, Lee Jones, Sebastian Reichel
  Cc: linux-kernel, linux-pm, Krzysztof Kozlowski, Andreas Kemnade

Add an entry for BD71828 charger driver.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Suggested-by: Matti Vaittinen <mazziesaccount@gmail.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fe168477caa45..044eb41ba4797 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21848,6 +21848,12 @@ L:	linux-serial@vger.kernel.org
 S:	Odd Fixes
 F:	drivers/tty/serial/rp2.*
 
+ROHM BD71828 CHARGER
+M:	Andreas Kemnade <andreas@kemnade.info>
+M:	Matti Vaittinen <mazziesaccount@gmail.com>
+S:	Maintained
+F:	drivers/power/supply/bd71828-charger.c
+
 ROHM BD79703 DAC
 M:	Matti Vaittinen <mazziesaccount@gmail.com>
 S:	Supported

-- 
2.39.5


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

* Re: [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger
  2025-08-21 18:23 ` [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger Andreas Kemnade
@ 2025-08-22  5:15   ` Matti Vaittinen
  2025-08-22  5:17   ` Matti Vaittinen
  1 sibling, 0 replies; 13+ messages in thread
From: Matti Vaittinen @ 2025-08-22  5:15 UTC (permalink / raw)
  To: Andreas Kemnade, Lee Jones, Sebastian Reichel
  Cc: linux-kernel, linux-pm, Krzysztof Kozlowski

On 21/08/2025 21:23, Andreas Kemnade wrote:
> Add an entry for BD71828 charger driver.
> 
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> Suggested-by: Matti Vaittinen <mazziesaccount@gmail.com>

Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>

> ---
>   MAINTAINERS | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe168477caa45..044eb41ba4797 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -21848,6 +21848,12 @@ L:	linux-serial@vger.kernel.org
>   S:	Odd Fixes
>   F:	drivers/tty/serial/rp2.*
>   
> +ROHM BD71828 CHARGER
> +M:	Andreas Kemnade <andreas@kemnade.info>
> +M:	Matti Vaittinen <mazziesaccount@gmail.com>
> +S:	Maintained
> +F:	drivers/power/supply/bd71828-charger.c
> +
>   ROHM BD79703 DAC
>   M:	Matti Vaittinen <mazziesaccount@gmail.com>
>   S:	Supported
> 


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

* Re: [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger
  2025-08-21 18:23 ` [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger Andreas Kemnade
  2025-08-22  5:15   ` Matti Vaittinen
@ 2025-08-22  5:17   ` Matti Vaittinen
  1 sibling, 0 replies; 13+ messages in thread
From: Matti Vaittinen @ 2025-08-22  5:17 UTC (permalink / raw)
  To: Andreas Kemnade, Lee Jones, Sebastian Reichel
  Cc: linux-kernel, linux-pm, Krzysztof Kozlowski

On 21/08/2025 21:23, Andreas Kemnade wrote:
> Add an entry for BD71828 charger driver.
> 
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> Suggested-by: Matti Vaittinen <mazziesaccount@gmail.com>

Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>

> ---
>   MAINTAINERS | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe168477caa45..044eb41ba4797 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -21848,6 +21848,12 @@ L:	linux-serial@vger.kernel.org
>   S:	Odd Fixes
>   F:	drivers/tty/serial/rp2.*
>   
> +ROHM BD71828 CHARGER
> +M:	Andreas Kemnade <andreas@kemnade.info>
> +M:	Matti Vaittinen <mazziesaccount@gmail.com>
> +S:	Maintained
> +F:	drivers/power/supply/bd71828-charger.c
> +
>   ROHM BD79703 DAC
>   M:	Matti Vaittinen <mazziesaccount@gmail.com>
>   S:	Supported
> 


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

* Re: [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver
  2025-08-21 18:23 ` [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver Andreas Kemnade
@ 2025-08-28  7:45   ` Linus Walleij
  2025-08-28 13:01     ` Matti Vaittinen
  2025-08-29  6:35     ` Matti Vaittinen
  0 siblings, 2 replies; 13+ messages in thread
From: Linus Walleij @ 2025-08-28  7:45 UTC (permalink / raw)
  To: Andreas Kemnade
  Cc: Matti Vaittinen, Lee Jones, Sebastian Reichel, linux-kernel,
	linux-pm, Krzysztof Kozlowski

Hi Andreas / Cong,

On Thu, Aug 21, 2025 at 8:25 PM Andreas Kemnade <andreas@kemnade.info> wrote:

> Add charger driver for ROHM BD718(15/28/78) PMIC charger block.
> It is a stripped down version of the driver here:
> https://lore.kernel.org/lkml/dbd97c1b0d715aa35a8b4d79741e433d97c562aa.1637061794.git.matti.vaittinen@fi.rohmeurope.com/
>
> For the ease of review and to do a step-by-step approach remove all the
> coloumb counter related stuff and do not sneak in BD71827 support. That
> also avoids non-trivial rebasing of the above series.
>
> Changes besides that:
> Replace the custom property by a standard one and do not use megaohms
> for the current sense resistor.
>
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>

I think it looks good to merge:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

It contains some interesting pointers for future work:

> +/* TODO: Verify the meaning of these interrupts */
> +BD_ISR_BAT(rechg_det, "Recharging", true)
> +BD_ISR_BAT(rechg_res, "Recharge ending", true)
> +BD_ISR_DUMMY(temp_transit, "Temperature transition")
> +BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false)
> +BD_ISR_BAT(therm_det, "bd71815-therm-det", true)
> +BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false)
> +BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true)
> +BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false)
> +BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true)
> +BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true)
> +BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true)

Some of these look like they should immediately shut down the
system, I suppose the battery charger does this autonomously
but it should probably also trigger an emergency shutdown
of Linux, right?

> +/* What should we do here? */
> +BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false)

At overvoltage all charging should stop, I guess the hardware
does that autonomouslyd and this is just to inform us that
this has happened.

> +BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true)
> +BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true)
> +BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false)
> +BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true)
> +BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false)
> +BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true)
> +BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false)
> +BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true)
> +BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false)
> +BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true)
> +BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true)
> +BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true)
> +BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true)

The "oc" stuff is "open circuit" and probably different interrupts
to indicate that a measurement of the open circuit voltage
is available in some register, which enables you do do more
precise capacity estimation, right?

If it is useful depends on if the device is e.g. flashed with
capacity tables vs OC voltage in the factory, and the charger
then has "deep knowledge" of the battery it is handling, I guess
this is how it works? Then this again is just informational, it
informs you of what the device-internal charging algorithm
is doing.

As for the temperature these are probably also just informational
if all these states are already handled by the hardware itself.

They all seem to be intended so that you can essentially put
these into custom sysfs or debugfs entries and then get out
a graphical state machine of the battery charger. That requires
deep knowledge of how the charger works (a datasheet)
and has limited use for a normal user.

Yours,
Linus Walleij

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

* Re: [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver
  2025-08-28  7:45   ` Linus Walleij
@ 2025-08-28 13:01     ` Matti Vaittinen
  2025-08-29  6:35     ` Matti Vaittinen
  1 sibling, 0 replies; 13+ messages in thread
From: Matti Vaittinen @ 2025-08-28 13:01 UTC (permalink / raw)
  To: Linus Walleij, Andreas Kemnade
  Cc: Lee Jones, Sebastian Reichel, linux-kernel, linux-pm,
	Krzysztof Kozlowski

On 28/08/2025 10:45, Linus Walleij wrote:
> Hi Andreas / Cong,
> 
> On Thu, Aug 21, 2025 at 8:25 PM Andreas Kemnade <andreas@kemnade.info> wrote:
> 
>> Add charger driver for ROHM BD718(15/28/78) PMIC charger block.
>> It is a stripped down version of the driver here:
>> https://lore.kernel.org/lkml/dbd97c1b0d715aa35a8b4d79741e433d97c562aa.1637061794.git.matti.vaittinen@fi.rohmeurope.com/
>>
>> For the ease of review and to do a step-by-step approach remove all the
>> coloumb counter related stuff and do not sneak in BD71827 support. That
>> also avoids non-trivial rebasing of the above series.
>>
>> Changes besides that:
>> Replace the custom property by a standard one and do not use megaohms
>> for the current sense resistor.
>>
>> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
>> Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
> 
> I think it looks good to merge:
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> It contains some interesting pointers for future work:
> 
>> +/* TODO: Verify the meaning of these interrupts */
>> +BD_ISR_BAT(rechg_det, "Recharging", true)
>> +BD_ISR_BAT(rechg_res, "Recharge ending", true)
>> +BD_ISR_DUMMY(temp_transit, "Temperature transition")
>> +BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false)
>> +BD_ISR_BAT(therm_det, "bd71815-therm-det", true)
>> +BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false)
>> +BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true)
>> +BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false)
>> +BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true)
>> +BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true)
>> +BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true)
> 
> Some of these look like they should immediately shut down the
> system, I suppose the battery charger does this autonomously
> but it should probably also trigger an emergency shutdown
> of Linux, right?
> 
>> +/* What should we do here? */
>> +BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false)
> 
> At overvoltage all charging should stop, I guess the hardware
> does that autonomouslyd and this is just to inform us that
> this has happened.
> 
>> +BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true)
>> +BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true)
>> +BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false)
>> +BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true)
>> +BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false)
>> +BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true)
>> +BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false)
>> +BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true)
>> +BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false)
>> +BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true)
>> +BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true)
>> +BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true)
>> +BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true)
> 
> The "oc" stuff is "open circuit" and probably different interrupts
> to indicate that a measurement of the open circuit voltage
> is available in some register, which enables you do do more
> precise capacity estimation, right?

I'll try to clarify this. No promises though ;)

> If it is useful depends on if the device is e.g. flashed with
> capacity tables vs OC voltage in the factory, and the charger
> then has "deep knowledge" of the battery it is handling, I guess
> this is how it works?

I am not 100% sure as I never had the whole setup with me. AFAICS, the 
used battery (at least in Kobo project) was a dummy one, and the device 
driver did fuel-gauge computation(s) based on the battery parameters and 
the CC.

The OCV and VDR tables were indeed measured (but AFAICS, not during 
manufacturing for each independent device. It was instead done during 
the R&D phase, for the type of battery that was used in these devices. 
Or, at least this is how I think it was done - based on discussion with 
HQ colleagues). Anyways, I think Andreas had these extracted from the 
downstream driver.

> Then this again is just informational, it
> informs you of what the device-internal charging algorithm
> is doing.
> 
> As for the temperature these are probably also just informational
> if all these states are already handled by the hardware itself.
> 
> They all seem to be intended so that you can essentially put
> these into custom sysfs or debugfs entries and then get out
> a graphical state machine of the battery charger. That requires
> deep knowledge of how the charger works (a datasheet)
> and has limited use for a normal user.

Thanks for sharing your insight Linus! It's always great to gain a bit 
more understanding :)

Yours,
	-- Matti


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

* Re: [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver
  2025-08-28  7:45   ` Linus Walleij
  2025-08-28 13:01     ` Matti Vaittinen
@ 2025-08-29  6:35     ` Matti Vaittinen
  2025-08-29 11:15       ` Andreas Kemnade
  2025-08-29 12:27       ` Matti Vaittinen
  1 sibling, 2 replies; 13+ messages in thread
From: Matti Vaittinen @ 2025-08-29  6:35 UTC (permalink / raw)
  To: Linus Walleij, Andreas Kemnade
  Cc: Lee Jones, Sebastian Reichel, linux-kernel, linux-pm,
	Krzysztof Kozlowski

Hi deee Ho again peeps!

I'm back home from Amsterdam, and found the datasheets :)

On 28/08/2025 10:45, Linus Walleij wrote:
> Hi Andreas / Cong,
> 
> On Thu, Aug 21, 2025 at 8:25 PM Andreas Kemnade <andreas@kemnade.info> wrote:
> 
>> Add charger driver for ROHM BD718(15/28/78) PMIC charger block.
>> It is a stripped down version of the driver here:
>> https://lore.kernel.org/lkml/dbd97c1b0d715aa35a8b4d79741e433d97c562aa.1637061794.git.matti.vaittinen@fi.rohmeurope.com/
>>
>> For the ease of review and to do a step-by-step approach remove all the
>> coloumb counter related stuff and do not sneak in BD71827 support. That
>> also avoids non-trivial rebasing of the above series.
>>
>> Changes besides that:
>> Replace the custom property by a standard one and do not use megaohms
>> for the current sense resistor.
>>
>> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
>> Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
> 
> I think it looks good to merge:
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> It contains some interesting pointers for future work:
> 
>> +/* TODO: Verify the meaning of these interrupts */
>> +BD_ISR_BAT(rechg_det, "Recharging", true)
>> +BD_ISR_BAT(rechg_res, "Recharge ending", true)
>> +BD_ISR_DUMMY(temp_transit, "Temperature transition")
>> +BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false)
>> +BD_ISR_BAT(therm_det, "bd71815-therm-det", true)
>> +BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false)
>> +BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true)
>> +BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false)
>> +BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true)
>> +BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true)
>> +BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true)
> 
> Some of these look like they should immediately shut down the
> system, I suppose the battery charger does this autonomously
> but it should probably also trigger an emergency shutdown
> of Linux, right?

Yes. The shutdown for charging, or, in some cases for all power outputs, 
is automatically handled by the PMIC hardware. (Well, I am not sure 
about the 'over-current' IRQ, will see if I can find out more about it).

>> +/* What should we do here? */
>> +BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false)
> 
> At overvoltage all charging should stop, I guess the hardware
> does that autonomouslyd and this is just to inform us that
> this has happened.

Yes. That's my understanding.

>> +BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true)
>> +BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true)
>> +BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false)
>> +BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true)
>> +BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false)
>> +BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true)
>> +BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false)
>> +BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true)
>> +BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false)
>> +BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true)
>> +BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true)
>> +BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true)
>> +BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true)
> 
> The "oc" stuff is "open circuit" and probably different interrupts

I see I chose a confusing prefix, 'oc', sorry. In this case it doesn't 
come from "open circuit" but "over current" - and yes, I had to look it 
up from the MFD driver / data-sheet - which is a clear indication naming 
isn't as good as it could be. Anyways, it seems these over-current 
limits for the IRQ can be set by the software. I'm not sure if exceeding 
these limits causes hardware to do anything else but an IRQ though.

> to indicate that a measurement of the open circuit voltage
> is available in some register, which enables you do do more
> precise capacity estimation, right?

AFAIR, the ROHM fuel-gauge algorithm used OCV tables when battery was 
not really open, but 'relaxed', to adjust the coulomb counter based on 
the SOC estimated from the OCV. The 'relaxed' condition was met when the 
current consumption had been 'small', and battery had not been charged 
'recently'. I have a vague memory the BD71828 had some hardware support 
for knowing battery was 'relaxed', the BD71815 and BD71827 might have 
used coulomb counter 'history' for this. I can try to remember all this 
a bit better if Andreas continues to upstream also the fuel-gauging 
logic from the original RFC. But yeah, these interrupts were for over 
current.

> If it is useful depends on if the device is e.g. flashed with
> capacity tables vs OC voltage in the factory, and the charger
> then has "deep knowledge" of the battery it is handling, I guess
> this is how it works? Then this again is just informational, it
> informs you of what the device-internal charging algorithm
> is doing.
> 
> As for the temperature these are probably also just informational
> if all these states are already handled by the hardware itself.

Yes. AFAIR, the boundaries for the thermal areas can be adjusted by 
software though. [There are also the "thermal shutdown" limits when also 
the PMIC's other power outputs (not just charging) will be disabled. 
AFAIR, the TSD limit can't be configured though.] On certain temperature 
areas the charging is reduced, and the "amount of reduction" can also be 
set by the software.

State transitions are still handled by the hardware so these interrupts 
are indeed only informative.

> They all seem to be intended so that you can essentially put
> these into custom sysfs or debugfs entries and then get out
> a graphical state machine of the battery charger. That requires
> deep knowledge of how the charger works (a datasheet)
> and has limited use for a normal user.

Yours,
	-- Matti

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

* Re: [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver
  2025-08-29  6:35     ` Matti Vaittinen
@ 2025-08-29 11:15       ` Andreas Kemnade
  2025-08-29 12:27       ` Matti Vaittinen
  1 sibling, 0 replies; 13+ messages in thread
From: Andreas Kemnade @ 2025-08-29 11:15 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: Linus Walleij, Lee Jones, Sebastian Reichel, linux-kernel,
	linux-pm, Krzysztof Kozlowski

Am Fri, 29 Aug 2025 09:35:00 +0300
schrieb Matti Vaittinen <mazziesaccount@gmail.com>:

> > to indicate that a measurement of the open circuit voltage
> > is available in some register, which enables you do do more
> > precise capacity estimation, right?  
> 
> AFAIR, the ROHM fuel-gauge algorithm used OCV tables when battery was 
> not really open, but 'relaxed', to adjust the coulomb counter based on 
> the SOC estimated from the OCV. The 'relaxed' condition was met when the 
> current consumption had been 'small', and battery had not been charged 
> 'recently'. I have a vague memory the BD71828 had some hardware support 
> for knowing battery was 'relaxed', the BD71815 and BD71827 might have 
> used coulomb counter 'history' for this. I can try to remember all this 
> a bit better if Andreas continues to upstream also the fuel-gauging 
> logic from the original RFC. But yeah, these interrupts were for over 
> current.

78 at least has. But then the question is how often the relaxed state
really is reached. Current limit is around 3mA per default
(REX_CURCD_TH). So if your
power management is suboptimal, you will not reach that state on
discharing. So, regarding charging, at least when I am on vacation,
the limit on available energy is also my protection against spending
too much time with my electronics (esp. on the smartphone). But that
also means that I will not always charge the device fully. Lowering
current may also mis-indicated that the battery is full.
So the scene is set for any mess with fuel gauges, not limited to the
BD71878.

Regards,
Andreas

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

* Re: [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver
  2025-08-29  6:35     ` Matti Vaittinen
  2025-08-29 11:15       ` Andreas Kemnade
@ 2025-08-29 12:27       ` Matti Vaittinen
  1 sibling, 0 replies; 13+ messages in thread
From: Matti Vaittinen @ 2025-08-29 12:27 UTC (permalink / raw)
  To: Linus Walleij, Andreas Kemnade
  Cc: Lee Jones, Sebastian Reichel, linux-kernel, linux-pm,
	Krzysztof Kozlowski

On 29/08/2025 09:35, Matti Vaittinen wrote:

>> Some of these look like they should immediately shut down the
>> system, I suppose the battery charger does this autonomously
>> but it should probably also trigger an emergency shutdown
>> of Linux, right?
> 
> Yes. The shutdown for charging, or, in some cases for all power outputs, 
> is automatically handled by the PMIC hardware. (Well, I am not sure 
> about the 'over-current' IRQ, will see if I can find out more about it).

Just to conclude this - I got a confirmation from the ROHM hardware 
engineers that exceeding the set limit and causing the over-current and 
the coulomb counter monitoring interrupts do not change the hardware 
charging state. [CC_MON and OCUR events in the data sheet, if someone 
has that ;) ].

The CC_MON1 will however cause a change in the charging LED state. Eg, 
exceeding this limit will turn off the AMBLED and turn on the GRNLED - 
when the LEDs are controlled by the HW state machine. (I have some very 
faint memory that the LEDs could also be forced ON by software). I 
suppose the reason for this is that the CC_MON1 was designed to be used 
as a "coulomb counter near full capacity" alarm.

Yours,
	-- Matti

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

* Re: [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support
  2025-08-21 18:23 ` [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support Andreas Kemnade
@ 2025-09-03 12:23   ` Lee Jones
  2025-09-03 21:04     ` Andreas Kemnade
  0 siblings, 1 reply; 13+ messages in thread
From: Lee Jones @ 2025-09-03 12:23 UTC (permalink / raw)
  To: Andreas Kemnade
  Cc: Matti Vaittinen, Sebastian Reichel, linux-kernel, linux-pm,
	Krzysztof Kozlowski

On Thu, 21 Aug 2025, Andreas Kemnade wrote:

> From: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> 
> Add core support for ROHM BD718(15/28/78) PMIC's charger blocks.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> ---
>  drivers/mfd/rohm-bd71828.c       | 44 ++++++++++++++++++++++------
>  include/linux/mfd/rohm-bd71828.h | 63 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 98 insertions(+), 9 deletions(-)

Looks okay.

I'm guessing the Power patch depends on this one?

Would this break anything if taken on its own?

> diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
> index a14b7aa69c3c6..84a64c3b9c9f5 100644
> --- a/drivers/mfd/rohm-bd71828.c
> +++ b/drivers/mfd/rohm-bd71828.c
> @@ -45,8 +45,8 @@ static const struct resource bd71828_rtc_irqs[] = {
>  
>  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-clps-out"),
> -	DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-clps-in"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-dcin-clps-out"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-dcin-clps-in"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_RES, "bd71815-dcin-ovp-res"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_DET, "bd71815-dcin-ovp-det"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_RES, "bd71815-dcin-mon-res"),
> @@ -56,7 +56,7 @@ static const struct resource bd71815_power_irqs[] = {
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_RES, "bd71815-vsys-low-res"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_DET, "bd71815-vsys-low-det"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-res"),
> -	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-det"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_DET, "bd71815-vsys-mon-det"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TEMP, "bd71815-chg-wdg-temp"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TIME, "bd71815-chg-wdg"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_RES, "bd71815-rechg-res"),
> @@ -87,10 +87,10 @@ static const struct resource bd71815_power_irqs[] = {
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_DET, "bd71815-bat-oc2-det"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_RES, "bd71815-bat-oc3-res"),
>  	DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_DET, "bd71815-bat-oc3-det"),
> -	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-bat-low-res"),
> -	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-bat-low-det"),
> -	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-bat-hi-res"),
> -	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-bat-hi-det"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-temp-bat-low-res"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-temp-bat-low-det"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-temp-bat-hi-res"),
> +	DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-temp-bat-hi-det"),
>  };
>  
>  static const struct mfd_cell bd71815_mfd_cells[] = {
> @@ -109,7 +109,30 @@ static const struct mfd_cell bd71815_mfd_cells[] = {
>  	},
>  };
>  
> -static const struct mfd_cell bd71828_mfd_cells[] = {
> +static const struct resource bd71828_power_irqs[] = {
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_CHG_TOPOFF_TO_DONE,
> +			     "bd71828-chg-done"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_DCIN_DET, "bd71828-pwr-dcin-in"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_DCIN_RMV, "bd71828-pwr-dcin-out"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_BAT_LOW_VOLT_RES,
> +			     "bd71828-vbat-normal"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_BAT_LOW_VOLT_DET, "bd71828-vbat-low"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_HI_DET, "bd71828-btemp-hi"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_HI_RES, "bd71828-btemp-cool"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_LOW_DET, "bd71828-btemp-lo"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_BAT_LOW_RES,
> +			     "bd71828-btemp-warm"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_VF_DET,
> +			     "bd71828-temp-hi"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_VF_RES,
> +			     "bd71828-temp-norm"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_125_DET,
> +			     "bd71828-temp-125-over"),
> +	DEFINE_RES_IRQ_NAMED(BD71828_INT_TEMP_CHIP_OVER_125_RES,
> +			     "bd71828-temp-125-under"),
> +};
> +
> +static struct mfd_cell bd71828_mfd_cells[] = {
>  	{ .name = "bd71828-pmic", },
>  	{ .name = "bd71828-gpio", },
>  	{ .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" },
> @@ -118,8 +141,11 @@ static const struct mfd_cell bd71828_mfd_cells[] = {
>  	 * BD70528 clock gate are the register address and mask.
>  	 */
>  	{ .name = "bd71828-clk", },
> -	{ .name = "bd71827-power", },
>  	{
> +		.name = "bd71828-power",
> +		.resources = bd71828_power_irqs,
> +		.num_resources = ARRAY_SIZE(bd71828_power_irqs),
> +	}, {
>  		.name = "bd71828-rtc",
>  		.resources = bd71828_rtc_irqs,
>  		.num_resources = ARRAY_SIZE(bd71828_rtc_irqs),
> diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
> index ce786c96404a3..73a71ef691525 100644
> --- a/include/linux/mfd/rohm-bd71828.h
> +++ b/include/linux/mfd/rohm-bd71828.h
> @@ -189,6 +189,69 @@ enum {
>  /* Charger/Battey */
>  #define BD71828_REG_CHG_STATE		0x65
>  #define BD71828_REG_CHG_FULL		0xd2
> +#define BD71828_REG_CHG_EN		0x6F
> +#define BD71828_REG_DCIN_STAT		0x68
> +#define BD71828_MASK_DCIN_DET		0x01
> +#define BD71828_REG_VDCIN_U		0x9c
> +#define BD71828_MASK_CHG_EN		0x01
> +#define BD71828_CHG_MASK_DCIN_U		0x0f
> +#define BD71828_REG_BAT_STAT		0x67
> +#define BD71828_REG_BAT_TEMP		0x6c
> +#define BD71828_MASK_BAT_TEMP		0x07
> +#define BD71828_BAT_TEMP_OPEN		0x07
> +#define BD71828_MASK_BAT_DET		0x20
> +#define BD71828_MASK_BAT_DET_DONE	0x10
> +#define BD71828_REG_CHG_STATE		0x65
> +#define BD71828_REG_VBAT_U		0x8c
> +#define BD71828_MASK_VBAT_U		0x0f
> +#define BD71828_REG_VBAT_REX_AVG_U	0x92
> +
> +#define BD71828_REG_OCV_PWRON_U		0x8A
> +
> +#define BD71828_REG_VBAT_MIN_AVG_U	0x8e
> +#define BD71828_REG_VBAT_MIN_AVG_L	0x8f
> +
> +#define BD71828_REG_CC_CNT3		0xb5
> +#define BD71828_REG_CC_CNT2		0xb6
> +#define BD71828_REG_CC_CNT1		0xb7
> +#define BD71828_REG_CC_CNT0		0xb8
> +#define BD71828_REG_CC_CURCD_AVG_U	0xb2
> +#define BD71828_MASK_CC_CURCD_AVG_U	0x3f
> +#define BD71828_MASK_CC_CUR_DIR		0x80
> +#define BD71828_REG_VM_BTMP_U		0xa1
> +#define BD71828_REG_VM_BTMP_L		0xa2
> +#define BD71828_MASK_VM_BTMP_U		0x0f
> +#define BD71828_REG_COULOMB_CTRL	0xc4
> +#define BD71828_REG_COULOMB_CTRL2	0xd2
> +#define BD71828_MASK_REX_CC_CLR		0x01
> +#define BD71828_MASK_FULL_CC_CLR	0x10
> +#define BD71828_REG_CC_CNT_FULL3	0xbd
> +#define BD71828_REG_CC_CNT_CHG3		0xc1
> +
> +#define BD71828_REG_VBAT_INITIAL1_U	0x86
> +#define BD71828_REG_VBAT_INITIAL1_L	0x87
> +
> +#define BD71828_REG_VBAT_INITIAL2_U	0x88
> +#define BD71828_REG_VBAT_INITIAL2_L	0x89
> +
> +#define BD71828_REG_IBAT_U		0xb0
> +#define BD71828_REG_IBAT_L		0xb1
> +
> +#define BD71828_REG_IBAT_AVG_U		0xb2
> +#define BD71828_REG_IBAT_AVG_L		0xb3
> +
> +#define BD71828_REG_VSYS_AVG_U		0x96
> +#define BD71828_REG_VSYS_AVG_L		0x97
> +#define BD71828_REG_VSYS_MIN_AVG_U	0x98
> +#define BD71828_REG_VSYS_MIN_AVG_L	0x99
> +#define BD71828_REG_CHG_SET1		0x75
> +#define BD71828_REG_ALM_VBAT_LIMIT_U	0xaa
> +#define BD71828_REG_BATCAP_MON_LIMIT_U	0xcc
> +#define BD71828_REG_CONF		0x64
> +
> +#define BD71828_REG_DCIN_CLPS		0x71
> +
> +#define BD71828_REG_MEAS_CLEAR		0xaf
>  
>  /* LEDs */
>  #define BD71828_REG_LED_CTRL		0x4A
> 
> -- 
> 2.39.5
> 

-- 
Lee Jones [李琼斯]

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

* Re: [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support
  2025-09-03 12:23   ` Lee Jones
@ 2025-09-03 21:04     ` Andreas Kemnade
  0 siblings, 0 replies; 13+ messages in thread
From: Andreas Kemnade @ 2025-09-03 21:04 UTC (permalink / raw)
  To: Lee Jones
  Cc: Matti Vaittinen, Sebastian Reichel, linux-kernel, linux-pm,
	Krzysztof Kozlowski

Am Wed, 3 Sep 2025 13:23:11 +0100
schrieb Lee Jones <lee@kernel.org>:

> On Thu, 21 Aug 2025, Andreas Kemnade wrote:
> 
> > From: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > 
> > Add core support for ROHM BD718(15/28/78) PMIC's charger blocks.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> > ---
> >  drivers/mfd/rohm-bd71828.c       | 44 ++++++++++++++++++++++------
> >  include/linux/mfd/rohm-bd71828.h | 63 ++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 98 insertions(+), 9 deletions(-)  
> 
> Looks okay.
> 
> I'm guessing the Power patch depends on this one?
> 
yes,

> Would this break anything if taken on its own?
> 
no, so feel free to take it on its own, if we reach your deadline for
immutable branches before Sebastian adds his Reviewed-by/Acked-by.

Most discussions are about future ideas anyways.

Regards,
Andreas

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

end of thread, other threads:[~2025-09-03 21:04 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-21 18:23 [PATCH v3 0/3] power: supply: add charger for BD71828 Andreas Kemnade
2025-08-21 18:23 ` [PATCH v3 1/3] mfd: bd71828, bd71815 prepare for power-supply support Andreas Kemnade
2025-09-03 12:23   ` Lee Jones
2025-09-03 21:04     ` Andreas Kemnade
2025-08-21 18:23 ` [PATCH v3 2/3] power: supply: Add bd718(15/28/78) charger driver Andreas Kemnade
2025-08-28  7:45   ` Linus Walleij
2025-08-28 13:01     ` Matti Vaittinen
2025-08-29  6:35     ` Matti Vaittinen
2025-08-29 11:15       ` Andreas Kemnade
2025-08-29 12:27       ` Matti Vaittinen
2025-08-21 18:23 ` [PATCH v3 3/3] MAINTAINERS: Add entry for BD71828 charger Andreas Kemnade
2025-08-22  5:15   ` Matti Vaittinen
2025-08-22  5:17   ` Matti Vaittinen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).