Linux-Clk Archive on lore.kernel.org
 help / color / Atom feed
* [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC
@ 2019-11-01 11:28 Matti Vaittinen
  2019-11-01 11:29 ` [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core Matti Vaittinen
                   ` (15 more replies)
  0 siblings, 16 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:28 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Patch series introducing support for ROHM BD71828 PMIC

ROHM BD71828 is a power management IC containing 7 bucks and 7 LDOs. All
regulators can either be controlled individually via I2C. Bucks 1,2,6 and
7 can also be assigned to a "regulator group" controlled by run-levels.
Eg. Run level specific voltages and enable/disable statuses for each of
these bucks can be set via register interface. The buck run-level group
assignment (selection if buck is to be controlled individually or via
run-levels) can be changed at run-time via I2C.

Run level changes can then be initiated wither via I2C writes or GPIO.
and when run-level is changed, state of all bucks which are set to be
controlled via run-levels are changed accrdingly.

This control mechanism selection (I2C or GPIO) is selected by data in
one time programmable PMIC memory area (during production) and can't be
changed later.

In addition to the bucks and LDOs there are:

- The usual clk gate
- 4 IO pins (mostly usable as GPO or tied to specific purpose)
- power button support
- RTC
- two LEDs
- battery charger
- HALL sensor input

This patch series adds support to regulators, clk, RTC, and GPIOs. LED
support will be added later when fate of RFC "Add DT node finding and
parsing to core" is known.

https://lore.kernel.org/lkml/cover.1572351774.git.matti.vaittinen@fi.rohmeurope.com/

Power-supply driver for charger is "under construction" and not included
in this RFC series.

Reason for RFC status is the regulator grouping to run-levels.

Patches 8 and 9 bring more or less the usual regulator support.

Patches 10, 11, 12 add run-level control which I am not entirely happy
with. I don't like sysfs interface for run-level control. I am not
entirely happy with the in-kernel APIs either as those provide run-level
control via one *regulator pointer - but change impacts to more than one
regulator.

All suggestions are appreciated and welcome.

Rest of the patches should be business as usual.

Changelog v3:
  DT-Bindings:
    - yamlify
    - add LED binding doc
  CLK:
    - Move clk register definitions from MFD headers to clk driver
  GPIO:
    - Add generic direction define and use it.
  LED:
    - Drop LED driver from the series (for now).

Changelog v2: Mainly RTC and GPIO fixes suggested by Alexandre and Bartosz

  General:
    -Patch ordering changed to provide dt binding documents right after the
     MFD core.
  DT-Bindings for regulators (Patch 3)
    -Fix typo in PMIC model number
  RTC (patch 11)
    -Reverted renaming in order to reduce patch size.
    -Reworded commit message
  BD71828 regulator (patch 7)
    -Add MODULE_ALIAS
  GPIO (patch 12)
    -Remove file-name from comment
    -prefix IN and OUT defines with chip type
    -improved documentation for the INPUT only pin.
    -removed empty left-over function
    -removed unnecessary #ifdef CONFIG_OF_GPIO
    -removed unnecessary error print
    -Add MODULE_ALIAS

Patch 1:
        BD71828 MFD core.
Patch 2:
	dt-bindings for BD71828 PMIC
Patch 3:
        dt-bindings for regulators on BD71828 PMIC
Patch 4:
        dt-bindings for LEDs on BD71828 PMIC
Patch 5:
	Power button support using GPIO keys.
Patch 6:
        CLK gate support using existing clk-bd718x7
Patch 7:
        Move clk register definitions from headers to driver
Patch 8:
        Split existing bd718x7 regulator driver to generic ROHM dt
        parsing portion (used by more than one ROHM drivers) and
        bd718x8 specific parts
Patch 9:
        Basic regulator support (individual control via I2C). This
        should be pretty standard stuff.
Patch 10:
        Add support for getting regulator voltages when GPIO controlled
        run-levels are used. Allow specifying voltages for run-levels
        via DT. Allow controlling run-levels via sysfs entries (I am not
        happy about this. Probably should only provide in-kernel API for
        this or is there better ideas? Showing can be done vis sysfs?
        Debugfs?)
Patch 11:
        Support setting/getting run-levels when they are controlled via
        I2C instead of GPIO. Add in-kernel API for settin run-level
        voltages for regulators at run-time.
Patch 12:
        Add in-kernel APIs for changing the RUN-level. Safer than sysfs
        I guess. But is there some better method for controlling this
        kind of dynamic group of regulators?
Patch 13:
        Support BD71828 RTC block using BD70528 RTC driver
Patch 14:
        Add generic GPIO direction defines
Patch 15:
        Allow control of GP(I)O pins on BD71828 via GPIO subsystem
Patch 16:
        Support toggling the LEDs

This patch series is based on v5.4-rc5

---

Matti Vaittinen (15):
  mfd: bd71828: Support ROHM BD71828 PMIC - core
  dt-bindings: mfd: Document ROHM BD71828 bindings
  dt-bindings: regulator: Document ROHM BD71282 regulator bindings
  dt-bindings: leds: ROHM BD71282 PMIC LED driver
  mfd: input: bd71828: Add power-key support
  clk: bd718x7: Support ROHM BD71828 clk block
  clk: bd718x7: simplify header dependencies
  regulator: bd718x7: Split driver to common and bd718x7 specific parts
  regulator: bd71828: Basic support for ROHM bd71828 PMIC regulators
  regulator: bd71828: Add GPIO based run-level control for regulators
  regulator: bd71828: enhanced run-level support
  regulator: bd71828: Support in-kernel APIs to change run-level
  rtc: bd70528 add BD71828 support
  gpio: Add definition for GPIO direction
  gpio: bd71828: Initial support for ROHM BD71828 PMIC GPIOs

 .../bindings/leds/rohm,leds-bd71828.yaml      |   46 +
 .../bindings/mfd/rohm,bd71828-pmic.yaml       |  249 +++
 .../regulator/rohm,bd71828-regulator.yaml     |  123 ++
 drivers/clk/Kconfig                           |    6 +-
 drivers/clk/clk-bd718x7.c                     |   37 +-
 drivers/gpio/Kconfig                          |   12 +
 drivers/gpio/Makefile                         |    1 +
 drivers/gpio/gpio-bd71828.c                   |  149 ++
 drivers/mfd/Kconfig                           |   15 +
 drivers/mfd/Makefile                          |    2 +-
 drivers/mfd/rohm-bd71828.c                    |  350 ++++
 drivers/regulator/Kconfig                     |   16 +
 drivers/regulator/Makefile                    |    2 +
 drivers/regulator/bd71828-regulator.c         | 1443 +++++++++++++++++
 drivers/regulator/bd718x7-regulator.c         |  183 +--
 drivers/regulator/rohm-regulator.c            |   95 ++
 drivers/rtc/Kconfig                           |    3 +-
 drivers/rtc/rtc-bd70528.c                     |  150 +-
 include/linux/gpio/driver.h                   |    3 +
 include/linux/mfd/rohm-bd70528.h              |   19 +-
 include/linux/mfd/rohm-bd71828.h              |  428 +++++
 include/linux/mfd/rohm-bd718x7.h              |    6 -
 include/linux/mfd/rohm-generic.h              |   45 +
 include/linux/mfd/rohm-shared.h               |   27 +
 24 files changed, 3230 insertions(+), 180 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
 create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
 create mode 100644 Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
 create mode 100644 drivers/gpio/gpio-bd71828.c
 create mode 100644 drivers/mfd/rohm-bd71828.c
 create mode 100644 drivers/regulator/bd71828-regulator.c
 create mode 100644 drivers/regulator/rohm-regulator.c
 create mode 100644 include/linux/mfd/rohm-bd71828.h
 create mode 100644 include/linux/mfd/rohm-shared.h

-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
@ 2019-11-01 11:29 ` Matti Vaittinen
  2019-11-11 10:57   ` Lee Jones
  2019-11-01 11:31 ` [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings Matti Vaittinen
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:29 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

BD71828GW is a single-chip power management IC for battery-powered portable
devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA
single-cell linear charger. Also included is a Coulomb counter, a real-time
clock (RTC), 3 GPO/regulator control pins, HALL input and a 32.768 kHz
clock gate.

Add MFD core driver providing interrupt controller facilities and i2c
access to sub device drivers.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

No changes compared to v2

 drivers/mfd/Kconfig              |  15 ++
 drivers/mfd/Makefile             |   2 +-
 drivers/mfd/rohm-bd71828.c       | 322 +++++++++++++++++++++++
 include/linux/mfd/rohm-bd71828.h | 425 +++++++++++++++++++++++++++++++
 include/linux/mfd/rohm-generic.h |   1 +
 5 files changed, 764 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/rohm-bd71828.c
 create mode 100644 include/linux/mfd/rohm-bd71828.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ae24d3ea68ea..ff06e853f799 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1913,6 +1913,21 @@ config MFD_ROHM_BD70528
 	  10 bits SAR ADC for battery temperature monitor and 1S battery
 	  charger.
 
+config MFD_ROHM_BD71828
+	tristate "ROHM BD71828 Power Management IC"
+	depends on I2C=y
+	depends on OF
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	select MFD_CORE
+	help
+	  Select this option to get support for the ROHM BD71828 Power
+	  Management IC. BD71828GW is a single-chip power management IC for
+	  battery-powered portable devices. The IC integrates 7 buck
+	  converters, 7 LDOs, and a 1500 mA single-cell linear charger.
+	  Also included is a Coulomb counter, a real-time clock (RTC), and
+	  a 32.768 kHz clock gate.
+
 config MFD_STM32_LPTIMER
 	tristate "Support for STM32 Low-Power Timer"
 	depends on (ARCH_STM32 && OF) || COMPILE_TEST
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c1067ea46204..437c47ffd315 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -253,6 +253,6 @@ obj-$(CONFIG_MFD_MXS_LRADC)     += mxs-lradc.o
 obj-$(CONFIG_MFD_SC27XX_PMIC)	+= sprd-sc27xx-spi.o
 obj-$(CONFIG_RAVE_SP_CORE)	+= rave-sp.o
 obj-$(CONFIG_MFD_ROHM_BD70528)	+= rohm-bd70528.o
+obj-$(CONFIG_MFD_ROHM_BD71828)	+= rohm-bd71828.o
 obj-$(CONFIG_MFD_ROHM_BD718XX)	+= rohm-bd718x7.o
 obj-$(CONFIG_MFD_STMFX) 	+= stmfx.o
-
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
new file mode 100644
index 000000000000..b7de79e1fcdb
--- /dev/null
+++ b/drivers/mfd/rohm-bd71828.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// Copyright (C) 2019 ROHM Semiconductors
+//
+// ROHM BD71828 PMIC driver
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rohm-bd71828.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+static const struct resource rtc_irqs[] = {
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"),
+	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd71828-rtc-alm-2"),
+};
+
+static struct mfd_cell bd71828_mfd_cells[] = {
+	{ .name = "bd71828-pmic", },
+	{ .name = "bd71828-gpio", },
+	{ .name = "bd71828-led", },
+	/*
+	 * We use BD71837 driver to drive the clock block. Only differences to
+	 * BD70528 clock gate are the register address and mask.
+	 */
+	{ .name = "bd718xx-clk", },
+	{
+		.name = "bd71827-power",
+	}, {
+		.name = "bd70528-rtc",
+		.resources = rtc_irqs,
+		.num_resources = ARRAY_SIZE(rtc_irqs),
+	},
+};
+
+static const struct regmap_range volatile_ranges[] = {
+	{
+		.range_min = BD71828_REG_PS_CTRL_1,
+		.range_max = BD71828_REG_PS_CTRL_1,
+	}, {
+		.range_min = BD71828_REG_PS_CTRL_3,
+		.range_max = BD71828_REG_PS_CTRL_3,
+	}, {
+		.range_min = BD71828_REG_RTC_SEC,
+		.range_max = BD71828_REG_RTC_YEAR,
+	}, {
+		/*
+		 * For now make all charger registers volatile because many
+		 * needs to be and because the charger block is not that
+		 * performance critical. TBD: Check which charger registers
+		 * could be cached
+		 */
+		.range_min = BD71828_REG_CHG_STATE,
+		.range_max = BD71828_REG_CHG_FULL,
+	}, {
+		.range_min = BD71828_REG_INT_MAIN,
+		.range_max = BD71828_REG_IO_STAT,
+	},
+};
+
+static const struct regmap_access_table volatile_regs = {
+	.yes_ranges = &volatile_ranges[0],
+	.n_yes_ranges = ARRAY_SIZE(volatile_ranges),
+};
+
+static struct regmap_config bd71828_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &volatile_regs,
+	.max_register = BD71828_MAX_REGISTER,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+/*
+ * 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
+ * register.
+ */
+
+unsigned int bit0_offsets[] = {11};		/* RTC IRQ register */
+unsigned int bit1_offsets[] = {10};		/* TEMP IRQ register */
+unsigned int bit2_offsets[] = {6, 7, 8, 9};	/* BAT MON IRQ registers */
+unsigned int bit3_offsets[] = {5};		/* BAT IRQ register */
+unsigned int bit4_offsets[] = {4};		/* CHG IRQ register */
+unsigned int bit5_offsets[] = {3};		/* VSYS IRQ register */
+unsigned int bit6_offsets[] = {1, 2};		/* DCIN IRQ registers */
+unsigned int bit7_offsets[] = {0};		/* BUCK IRQ register */
+
+static struct regmap_irq_sub_irq_map bd71828_sub_irq_offsets[] = {
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
+};
+
+static struct regmap_irq bd71828_irqs[] = {
+	REGMAP_IRQ_REG(BD71828_INT_BUCK1_OCP, 0, BD71828_INT_BUCK1_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BUCK2_OCP, 0, BD71828_INT_BUCK2_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BUCK3_OCP, 0, BD71828_INT_BUCK3_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BUCK4_OCP, 0, BD71828_INT_BUCK4_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BUCK5_OCP, 0, BD71828_INT_BUCK5_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BUCK6_OCP, 0, BD71828_INT_BUCK6_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BUCK7_OCP, 0, BD71828_INT_BUCK7_OCP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_PGFAULT, 0, BD71828_INT_PGFAULT_MASK),
+	/* DCIN1 interrupts */
+	REGMAP_IRQ_REG(BD71828_INT_DCIN_DET, 1, BD71828_INT_DCIN_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_DCIN_RMV, 1, BD71828_INT_DCIN_RMV_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CLPS_OUT, 1, BD71828_INT_CLPS_OUT_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CLPS_IN, 1, BD71828_INT_CLPS_IN_MASK),
+	/* DCIN2 interrupts */
+	REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2,
+		       BD71828_INT_DCIN_MON_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2,
+		       BD71828_INT_DCIN_MON_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_LONGPUSH, 2, BD71828_INT_LONGPUSH_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_MIDPUSH, 2, BD71828_INT_MIDPUSH_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_SHORTPUSH, 2, BD71828_INT_SHORTPUSH_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_PUSH, 2, BD71828_INT_PUSH_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_WDOG, 2, BD71828_INT_WDOG_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_SWRESET, 2, BD71828_INT_SWRESET_MASK),
+	/* Vsys */
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3,
+		       BD71828_INT_VSYS_UV_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3,
+		       BD71828_INT_VSYS_UV_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3,
+		       BD71828_INT_VSYS_LOW_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3,
+		       BD71828_INT_VSYS_LOW_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3,
+		       BD71828_INT_VSYS_HALL_IN_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3,
+		       BD71828_INT_VSYS_HALL_TOGGLE_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3,
+		       BD71828_INT_VSYS_MON_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3,
+		       BD71828_INT_VSYS_MON_DET_MASK),
+	/* Charger */
+	REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4,
+		       BD71828_INT_CHG_DCIN_ILIM_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4,
+		       BD71828_INT_CHG_TOPOFF_TO_DONE_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4,
+		       BD71828_INT_CHG_WDG_TEMP_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4,
+		       BD71828_INT_CHG_WDG_TIME_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4,
+		       BD71828_INT_CHG_RECHARGE_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4,
+		       BD71828_INT_CHG_RECHARGE_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 4,
+		       BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4,
+		       BD71828_INT_CHG_STATE_TRANSITION_MASK),
+	/* Battery */
+	REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5,
+		       BD71828_INT_BAT_TEMP_NORMAL_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5,
+		       BD71828_INT_BAT_TEMP_ERANGE_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5,
+		       BD71828_INT_BAT_TEMP_WARN_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5,
+		       BD71828_INT_BAT_REMOVED_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5,
+		       BD71828_INT_BAT_DETECTED_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5,
+		       BD71828_INT_THERM_REMOVED_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5,
+		       BD71828_INT_THERM_DETECTED_MASK),
+	/* Battery Mon 1 */
+	REGMAP_IRQ_REG(BD71828_INT_BAT_DEAD, 6, BD71828_INT_BAT_DEAD_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6,
+		       BD71828_INT_BAT_SHORTC_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6,
+		       BD71828_INT_BAT_SHORTC_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6,
+		       BD71828_INT_BAT_LOW_VOLT_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6,
+		       BD71828_INT_BAT_LOW_VOLT_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6,
+		       BD71828_INT_BAT_OVER_VOLT_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6,
+		       BD71828_INT_BAT_OVER_VOLT_DET_MASK),
+	/* Battery Mon 2 */
+	REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7,
+		       BD71828_INT_BAT_MON_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7,
+		       BD71828_INT_BAT_MON_DET_MASK),
+	/* Battery Mon 3 (Coulomb counter) */
+	REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8,
+		       BD71828_INT_BAT_CC_MON1_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8,
+		       BD71828_INT_BAT_CC_MON2_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8,
+		       BD71828_INT_BAT_CC_MON3_MASK),
+	/* Battery Mon 4 */
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9,
+		       BD71828_INT_BAT_OVER_CURR_1_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9,
+		       BD71828_INT_BAT_OVER_CURR_1_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9,
+		       BD71828_INT_BAT_OVER_CURR_2_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9,
+		       BD71828_INT_BAT_OVER_CURR_2_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9,
+		       BD71828_INT_BAT_OVER_CURR_3_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9,
+		       BD71828_INT_BAT_OVER_CURR_3_DET_MASK),
+	/* Temperature */
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10,
+		       BD71828_INT_TEMP_BAT_LOW_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10,
+		       BD71828_INT_TEMP_BAT_LOW_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10,
+		       BD71828_INT_TEMP_BAT_HI_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10,
+		       BD71828_INT_TEMP_BAT_HI_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_RES, 10,
+		       BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_DET, 10,
+		       BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_DET, 10,
+		       BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_RES, 10,
+		       BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK),
+	/* RTC Alarm */
+	REGMAP_IRQ_REG(BD71828_INT_RTC0, 11, BD71828_INT_RTC0_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_RTC1, 11, BD71828_INT_RTC1_MASK),
+	REGMAP_IRQ_REG(BD71828_INT_RTC2, 11, BD71828_INT_RTC2_MASK),
+};
+
+static struct regmap_irq_chip bd71828_irq_chip = {
+	.name = "bd71828_irq",
+	.main_status = BD71828_REG_INT_MAIN,
+	.irqs = &bd71828_irqs[0],
+	.num_irqs = ARRAY_SIZE(bd71828_irqs),
+	.status_base = BD71828_REG_INT_BUCK,
+	.mask_base = BD71828_REG_INT_MASK_BUCK,
+	.ack_base = BD71828_REG_INT_BUCK,
+	.mask_invert = true,
+	.init_ack_masked = true,
+	.num_regs = 12,
+	.num_main_regs = 1,
+	.sub_reg_offsets = &bd71828_sub_irq_offsets[0],
+	.num_main_status_bits = 8,
+	.irq_reg_stride = 1,
+};
+
+static int bd71828_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
+{
+	struct rohm_regmap_dev *chip;
+	struct regmap_irq_chip_data *irq_data;
+	int ret;
+
+	if (!i2c->irq) {
+		dev_err(&i2c->dev, "No IRQ configured\n");
+		return -EINVAL;
+	}
+
+	chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	dev_set_drvdata(&i2c->dev, chip);
+
+	chip->chip_type = ROHM_CHIP_TYPE_BD71828;
+	chip->regmap = devm_regmap_init_i2c(i2c, &bd71828_regmap);
+	if (IS_ERR(chip->regmap)) {
+		dev_err(&i2c->dev, "Failed to initialize Regmap\n");
+		return PTR_ERR(chip->regmap);
+	}
+
+	ret = devm_regmap_add_irq_chip(&i2c->dev, chip->regmap,
+				       i2c->irq, IRQF_ONESHOT, 0,
+				       &bd71828_irq_chip, &irq_data);
+	if (ret) {
+		dev_err(&i2c->dev, "Failed to add IRQ chip\n");
+		return ret;
+	}
+	dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
+		bd71828_irq_chip.num_irqs);
+
+	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
+				   bd71828_mfd_cells,
+				   ARRAY_SIZE(bd71828_mfd_cells), NULL, 0,
+				   regmap_irq_get_domain(irq_data));
+	if (ret)
+		dev_err(&i2c->dev, "Failed to create subdevices\n");
+
+	return ret;
+}
+
+static const struct of_device_id bd71828_of_match[] = {
+	{ .compatible = "rohm,bd71828", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, bd71828_of_match);
+
+static struct i2c_driver bd71828_drv = {
+	.driver = {
+		.name = "rohm-bd71828",
+		.of_match_table = bd71828_of_match,
+	},
+	.probe = &bd71828_i2c_probe,
+};
+
+module_i2c_driver(bd71828_drv);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("ROHM BD71828 Power Management IC driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
new file mode 100644
index 000000000000..eb0557eb5314
--- /dev/null
+++ b/include/linux/mfd/rohm-bd71828.h
@@ -0,0 +1,425 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2019 ROHM Semiconductors */
+
+#ifndef __LINUX_MFD_BD71828_H__
+#define __LINUX_MFD_BD71828_H__
+
+#include <linux/mfd/rohm-generic.h>
+
+/* Regulator IDs */
+enum {
+	BD71828_BUCK1,
+	BD71828_BUCK2,
+	BD71828_BUCK3,
+	BD71828_BUCK4,
+	BD71828_BUCK5,
+	BD71828_BUCK6,
+	BD71828_BUCK7,
+	BD71828_LDO1,
+	BD71828_LDO2,
+	BD71828_LDO3,
+	BD71828_LDO4,
+	BD71828_LDO5,
+	BD71828_LDO6,
+	BD71828_LDO_SNVS,
+	BD71828_REGULATOR_AMOUNT,
+};
+
+#define BD71828_BUCK1267_VOLTS		0xEF
+#define BD71828_BUCK3_VOLTS		0x10
+#define BD71828_BUCK4_VOLTS		0x20
+#define BD71828_BUCK5_VOLTS		0x10
+#define BD71828_LDO_VOLTS		0x32
+/* LDO6 is fixed 1.8V voltage */
+#define BD71828_LDO_6_VOLTAGE		1800000
+
+/* Registers and masks*/
+
+/* MODE control */
+#define BD71828_REG_PS_CTRL_1		0x04
+#define BD71828_REG_PS_CTRL_2		0x05
+#define BD71828_REG_PS_CTRL_3		0x06
+
+//#define BD71828_REG_SWRESET		0x06
+#define BD71828_MASK_RUN_LVL_CTRL	0x30
+
+/* Regulator control masks */
+
+#define BD71828_MASK_RAMP_DELAY		0x6
+
+#define BD71828_MASK_RUN_EN		0x08
+#define BD71828_MASK_SUSP_EN		0x04
+#define BD71828_MASK_IDLE_EN		0x02
+#define BD71828_MASK_LPSR_EN		0x01
+
+#define BD71828_MASK_RUN0_EN		0x01
+#define BD71828_MASK_RUN1_EN		0x02
+#define BD71828_MASK_RUN2_EN		0x04
+#define BD71828_MASK_RUN3_EN		0x08
+
+#define BD71828_MASK_DVS_BUCK1_CTRL	0x10
+#define BD71828_DVS_BUCK1_CTRL_I2C	0
+#define BD71828_DVS_BUCK1_USE_RUNLVL	0x10
+
+#define BD71828_MASK_DVS_BUCK2_CTRL	0x20
+#define BD71828_DVS_BUCK2_CTRL_I2C	0
+#define BD71828_DVS_BUCK2_USE_RUNLVL	0x20
+
+#define BD71828_MASK_DVS_BUCK6_CTRL	0x40
+#define BD71828_DVS_BUCK6_CTRL_I2C	0
+#define BD71828_DVS_BUCK6_USE_RUNLVL	0x40
+
+#define BD71828_MASK_DVS_BUCK7_CTRL	0x80
+#define BD71828_DVS_BUCK7_CTRL_I2C	0
+#define BD71828_DVS_BUCK7_USE_RUNLVL	0x80
+
+#define BD71828_MASK_BUCK1267_VOLT	0xff
+#define BD71828_MASK_BUCK3_VOLT		0x1f
+#define BD71828_MASK_BUCK4_VOLT		0x3f
+#define BD71828_MASK_BUCK5_VOLT		0x1f
+#define BD71828_MASK_LDO_VOLT		0x3f
+
+/* Regulator control regs */
+#define BD71828_REG_BUCK1_EN		0x08
+#define BD71828_REG_BUCK1_CTRL		0x09
+#define BD71828_REG_BUCK1_MODE		0x0a
+#define BD71828_REG_BUCK1_IDLE_VOLT	0x0b
+#define BD71828_REG_BUCK1_SUSP_VOLT	0x0c
+#define BD71828_REG_BUCK1_VOLT		0x0d
+
+#define BD71828_REG_BUCK2_EN		0x12
+#define BD71828_REG_BUCK2_CTRL		0x13
+#define BD71828_REG_BUCK2_MODE		0x14
+#define BD71828_REG_BUCK2_IDLE_VOLT	0x15
+#define BD71828_REG_BUCK2_SUSP_VOLT	0x16
+#define BD71828_REG_BUCK2_VOLT		0x17
+
+#define BD71828_REG_BUCK3_EN		0x1c
+#define BD71828_REG_BUCK3_MODE		0x1d
+#define BD71828_REG_BUCK3_VOLT		0x1e
+
+#define BD71828_REG_BUCK4_EN		0x1f
+#define BD71828_REG_BUCK4_MODE		0x20
+#define BD71828_REG_BUCK4_VOLT		0x21
+
+#define BD71828_REG_BUCK5_EN		0x22
+#define BD71828_REG_BUCK5_MODE		0x23
+#define BD71828_REG_BUCK5_VOLT		0x24
+
+#define BD71828_REG_BUCK6_EN		0x25
+#define BD71828_REG_BUCK6_CTRL		0x26
+#define BD71828_REG_BUCK6_MODE		0x27
+#define BD71828_REG_BUCK6_IDLE_VOLT	0x28
+#define BD71828_REG_BUCK6_SUSP_VOLT	0x29
+#define BD71828_REG_BUCK6_VOLT		0x2a
+
+#define BD71828_REG_BUCK7_EN		0x2f
+#define BD71828_REG_BUCK7_CTRL		0x30
+#define BD71828_REG_BUCK7_MODE		0x31
+#define BD71828_REG_BUCK7_IDLE_VOLT	0x32
+#define BD71828_REG_BUCK7_SUSP_VOLT	0x33
+#define BD71828_REG_BUCK7_VOLT		0x34
+
+#define BD71828_REG_LDO1_EN		0x39
+#define BD71828_REG_LDO1_VOLT		0x3a
+#define BD71828_REG_LDO2_EN		0x3b
+#define BD71828_REG_LDO2_VOLT		0x3c
+#define BD71828_REG_LDO3_EN		0x3d
+#define BD71828_REG_LDO3_VOLT		0x3e
+#define BD71828_REG_LDO4_EN		0x3f
+#define BD71828_REG_LDO4_VOLT		0x40
+#define BD71828_REG_LDO5_EN		0x41
+#define BD71828_REG_LDO5_VOLT		0x43
+#define BD71828_REG_LDO5_VOLT_OPT	0x42
+#define BD71828_REG_LDO6_EN		0x44
+//#define BD71828_REG_LDO6_VOLT		0x4
+#define BD71828_REG_LDO7_EN		0x45
+#define BD71828_REG_LDO7_VOLT		0x46
+
+/* GPIO */
+
+#define BD71828_GPIO_DRIVE_MASK		0x2
+#define BD71828_GPIO_OPEN_DRAIN		0x0
+#define BD71828_GPIO_PUSH_PULL		0x2
+#define BD71828_GPIO_OUT_HI		0x1
+#define BD71828_GPIO_OUT_LO		0x0
+#define BD71828_GPIO_OUT_MASK		0x1
+
+#define BD71828_REG_GPIO_CTRL1		0x47
+#define BD71828_REG_GPIO_CTRL2		0x48
+#define BD71828_REG_GPIO_CTRL3		0x49
+#define BD71828_REG_IO_STAT		0xed
+
+/* RTC */
+#define BD71828_REG_RTC_SEC		0x4c
+#define BD71828_REG_RTC_MINUTE		0x4d
+#define BD71828_REG_RTC_HOUR		0x4e
+#define BD71828_REG_RTC_WEEK		0x4f
+#define BD71828_REG_RTC_DAY		0x50
+#define BD71828_REG_RTC_MONTH		0x51
+#define BD71828_REG_RTC_YEAR		0x52
+
+#define BD71828_REG_RTC_ALM0_SEC	0x53
+#define BD71828_REG_RTC_ALM0_MINUTE	0x54
+#define BD71828_REG_RTC_ALM0_HOUR	0x55
+#define BD71828_REG_RTC_ALM0_WEEK	0x56
+#define BD71828_REG_RTC_ALM0_DAY	0x57
+#define BD71828_REG_RTC_ALM0_MONTH	0x58
+#define BD71828_REG_RTC_ALM0_YEAR	0x59
+#define BD71828_REG_RTC_ALM0_MASK	0x61
+
+#define BD71828_REG_RTC_ALM1_SEC	0x5a
+#define BD71828_REG_RTC_ALM1_MINUTE	0x5b
+#define BD71828_REG_RTC_ALM1_HOUR	0x5c
+#define BD71828_REG_RTC_ALM1_WEEK	0x5d
+#define BD71828_REG_RTC_ALM1_DAY	0x5e
+#define BD71828_REG_RTC_ALM1_MONTH	0x5f
+#define BD71828_REG_RTC_ALM1_YEAR	0x60
+#define BD71828_REG_RTC_ALM1_MASK	0x62
+
+#define BD71828_REG_RTC_ALM2		0x63
+
+/* Charger/Battey */
+#define BD71828_REG_CHG_STATE		0x65
+#define BD71828_REG_CHG_FULL		0xd2
+
+/* CLK */
+#define BD71828_REG_OUT32K		0x4B
+
+/* LEDs */
+#define BD71828_REG_LED_CTRL		0x4A
+#define BD71828_MASK_LED_AMBER		0x80
+#define BD71828_MASK_LED_GREEN		0x40
+#define BD71828_LED_ON			0xff
+#define BD71828_LED_OFF			0x0
+
+/* IRQ registers */
+#define BD71828_REG_INT_MASK_BUCK	0xd3
+#define BD71828_REG_INT_MASK_DCIN1	0xd4
+#define BD71828_REG_INT_MASK_DCIN2	0xd5
+#define BD71828_REG_INT_MASK_VSYS	0xd6
+#define BD71828_REG_INT_MASK_CHG	0xd7
+#define BD71828_REG_INT_MASK_BAT	0xd8
+#define BD71828_REG_INT_MASK_BAT_MON1	0xd9
+#define BD71828_REG_INT_MASK_BAT_MON2	0xda
+#define BD71828_REG_INT_MASK_BAT_MON3	0xdb
+#define BD71828_REG_INT_MASK_BAT_MON4	0xdc
+#define BD71828_REG_INT_MASK_TEMP	0xdd
+#define BD71828_REG_INT_MASK_RTC	0xde
+
+
+#define BD71828_REG_INT_MAIN		0xdf
+#define BD71828_REG_INT_BUCK		0xe0
+#define BD71828_REG_INT_DCIN1		0xe1
+#define BD71828_REG_INT_DCIN2		0xe2
+#define BD71828_REG_INT_VSYS		0xe3
+#define BD71828_REG_INT_CHG		0xe4
+#define BD71828_REG_INT_BAT		0xe5
+#define BD71828_REG_INT_BAT_MON1	0xe6
+#define BD71828_REG_INT_BAT_MON2	0xe7
+#define BD71828_REG_INT_BAT_MON3	0xe8
+#define BD71828_REG_INT_BAT_MON4	0xe9
+#define BD71828_REG_INT_TEMP		0xea
+#define BD71828_REG_INT_RTC		0xeb
+#define BD71828_REG_INT_UPDATE		0xec
+
+#define BD71828_MAX_REGISTER BD71828_REG_IO_STAT
+
+/* Masks for main IRQ register bits */
+enum {
+	BD71828_INT_BUCK,
+#define BD71828_INT_BUCK_MASK BIT(BD71828_INT_BUCK)
+	BD71828_INT_DCIN,
+#define BD71828_INT_DCIN_MASK BIT(BD71828_INT_DCIN)
+	BD71828_INT_VSYS,
+#define BD71828_INT_VSYS_MASK BIT(BD71828_INT_VSYS)
+	BD71828_INT_CHG,
+#define BD71828_INT_CHG_MASK BIT(BD71828_INT_CHG)
+	BD71828_INT_BAT,
+#define BD71828_INT_BAT_MASK BIT(BD71828_INT_BAT)
+	BD71828_INT_BAT_MON,
+#define BD71828_INT_BAT_MON_MASK BIT(BD71828_INT_BAT_MON)
+	BD71828_INT_TEMP,
+#define BD71828_INT_TEMP_MASK BIT(BD71828_INT_TEMP)
+	BD71828_INT_RTC,
+#define BD71828_INT_RTC_MASK BIT(BD71828_INT_RTC)
+};
+
+/* Interrupts */
+enum {
+	/* BUCK reg interrupts */
+	BD71828_INT_BUCK1_OCP,
+	BD71828_INT_BUCK2_OCP,
+	BD71828_INT_BUCK3_OCP,
+	BD71828_INT_BUCK4_OCP,
+	BD71828_INT_BUCK5_OCP,
+	BD71828_INT_BUCK6_OCP,
+	BD71828_INT_BUCK7_OCP,
+	BD71828_INT_PGFAULT,
+	/* DCIN1 interrupts */
+	BD71828_INT_DCIN_DET,
+	BD71828_INT_DCIN_RMV,
+	BD71828_INT_CLPS_OUT,
+	BD71828_INT_CLPS_IN,
+	/* DCIN2 interrupts */
+	BD71828_INT_DCIN_MON_RES,
+	BD71828_INT_DCIN_MON_DET,
+	BD71828_INT_LONGPUSH,
+	BD71828_INT_MIDPUSH,
+	BD71828_INT_SHORTPUSH,
+	BD71828_INT_PUSH,
+	BD71828_INT_WDOG,
+	BD71828_INT_SWRESET,
+	/* Vsys */
+	BD71828_INT_VSYS_UV_RES,
+	BD71828_INT_VSYS_UV_DET,
+	BD71828_INT_VSYS_LOW_RES,
+	BD71828_INT_VSYS_LOW_DET,
+	BD71828_INT_VSYS_HALL_IN,
+	BD71828_INT_VSYS_HALL_TOGGLE,
+	BD71828_INT_VSYS_MON_RES,
+	BD71828_INT_VSYS_MON_DET,
+	/* Charger */
+	BD71828_INT_CHG_DCIN_ILIM,
+	BD71828_INT_CHG_TOPOFF_TO_DONE,
+	BD71828_INT_CHG_WDG_TEMP,
+	BD71828_INT_CHG_WDG_TIME,
+	BD71828_INT_CHG_RECHARGE_RES,
+	BD71828_INT_CHG_RECHARGE_DET,
+	BD71828_INT_CHG_RANGED_TEMP_TRANSITION,
+	BD71828_INT_CHG_STATE_TRANSITION,
+	/* Battery */
+	BD71828_INT_BAT_TEMP_NORMAL,
+	BD71828_INT_BAT_TEMP_ERANGE,
+	BD71828_INT_BAT_TEMP_WARN,
+	BD71828_INT_BAT_REMOVED,
+	BD71828_INT_BAT_DETECTED,
+	BD71828_INT_THERM_REMOVED,
+	BD71828_INT_THERM_DETECTED,
+	/* Battery Mon 1 */
+	BD71828_INT_BAT_DEAD,
+	BD71828_INT_BAT_SHORTC_RES,
+	BD71828_INT_BAT_SHORTC_DET,
+	BD71828_INT_BAT_LOW_VOLT_RES,
+	BD71828_INT_BAT_LOW_VOLT_DET,
+	BD71828_INT_BAT_OVER_VOLT_RES,
+	BD71828_INT_BAT_OVER_VOLT_DET,
+	/* Battery Mon 2 */
+	BD71828_INT_BAT_MON_RES,
+	BD71828_INT_BAT_MON_DET,
+	/* Battery Mon 3 (Coulomb counter) */
+	BD71828_INT_BAT_CC_MON1,
+	BD71828_INT_BAT_CC_MON2,
+	BD71828_INT_BAT_CC_MON3,
+	/* Battery Mon 4 */
+	BD71828_INT_BAT_OVER_CURR_1_RES,
+	BD71828_INT_BAT_OVER_CURR_1_DET,
+	BD71828_INT_BAT_OVER_CURR_2_RES,
+	BD71828_INT_BAT_OVER_CURR_2_DET,
+	BD71828_INT_BAT_OVER_CURR_3_RES,
+	BD71828_INT_BAT_OVER_CURR_3_DET,
+	/* Temperature */
+	BD71828_INT_TEMP_BAT_LOW_RES,
+	BD71828_INT_TEMP_BAT_LOW_DET,
+	BD71828_INT_TEMP_BAT_HI_RES,
+	BD71828_INT_TEMP_BAT_HI_DET,
+	BD71828_INT_TEMP_CHIP_OVER_125_RES,
+	BD71828_INT_TEMP_CHIP_OVER_125_DET,
+	BD71828_INT_TEMP_CHIP_OVER_VF_DET,
+	BD71828_INT_TEMP_CHIP_OVER_VF_RES,
+	/* RTC Alarm */
+	BD71828_INT_RTC0,
+	BD71828_INT_RTC1,
+	BD71828_INT_RTC2,
+};
+
+#define BD71828_INT_BUCK1_OCP_MASK			0x1
+#define BD71828_INT_BUCK2_OCP_MASK			0x2
+#define BD71828_INT_BUCK3_OCP_MASK			0x4
+#define BD71828_INT_BUCK4_OCP_MASK			0x8
+#define BD71828_INT_BUCK5_OCP_MASK			0x10
+#define BD71828_INT_BUCK6_OCP_MASK			0x20
+#define BD71828_INT_BUCK7_OCP_MASK			0x40
+#define BD71828_INT_PGFAULT_MASK			0x80
+
+#define BD71828_INT_DCIN_DET_MASK			0x1
+#define BD71828_INT_DCIN_RMV_MASK			0x2
+#define BD71828_INT_CLPS_OUT_MASK			0x4
+#define BD71828_INT_CLPS_IN_MASK			0x8
+	/* DCIN2 interrupts */
+#define BD71828_INT_DCIN_MON_RES_MASK			0x1
+#define BD71828_INT_DCIN_MON_DET_MASK			0x2
+#define BD71828_INT_LONGPUSH_MASK			0x4
+#define BD71828_INT_MIDPUSH_MASK			0x8
+#define BD71828_INT_SHORTPUSH_MASK			0x10
+#define BD71828_INT_PUSH_MASK				0x20
+#define BD71828_INT_WDOG_MASK				0x40
+#define BD71828_INT_SWRESET_MASK			0x80
+	/* Vsys */
+#define BD71828_INT_VSYS_UV_RES_MASK			0x1
+#define BD71828_INT_VSYS_UV_DET_MASK			0x2
+#define BD71828_INT_VSYS_LOW_RES_MASK			0x4
+#define BD71828_INT_VSYS_LOW_DET_MASK			0x8
+#define BD71828_INT_VSYS_HALL_IN_MASK			0x10
+#define BD71828_INT_VSYS_HALL_TOGGLE_MASK		0x20
+#define BD71828_INT_VSYS_MON_RES_MASK			0x40
+#define BD71828_INT_VSYS_MON_DET_MASK			0x80
+	/* Charger */
+#define BD71828_INT_CHG_DCIN_ILIM_MASK			0x1
+#define BD71828_INT_CHG_TOPOFF_TO_DONE_MASK		0x2
+#define BD71828_INT_CHG_WDG_TEMP_MASK			0x4
+#define BD71828_INT_CHG_WDG_TIME_MASK			0x8
+#define BD71828_INT_CHG_RECHARGE_RES_MASK		0x10
+#define BD71828_INT_CHG_RECHARGE_DET_MASK		0x20
+#define BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK	0x40
+#define BD71828_INT_CHG_STATE_TRANSITION_MASK		0x80
+	/* Battery */
+#define BD71828_INT_BAT_TEMP_NORMAL_MASK		0x1
+#define BD71828_INT_BAT_TEMP_ERANGE_MASK		0x2
+#define BD71828_INT_BAT_TEMP_WARN_MASK			0x4
+#define BD71828_INT_BAT_REMOVED_MASK			0x10
+#define BD71828_INT_BAT_DETECTED_MASK			0x20
+#define BD71828_INT_THERM_REMOVED_MASK			0x40
+#define BD71828_INT_THERM_DETECTED_MASK			0x80
+	/* Battery Mon 1 */
+#define BD71828_INT_BAT_DEAD_MASK			0x2
+#define BD71828_INT_BAT_SHORTC_RES_MASK			0x4
+#define BD71828_INT_BAT_SHORTC_DET_MASK			0x8
+#define BD71828_INT_BAT_LOW_VOLT_RES_MASK		0x10
+#define BD71828_INT_BAT_LOW_VOLT_DET_MASK		0x20
+#define BD71828_INT_BAT_OVER_VOLT_RES_MASK		0x40
+#define BD71828_INT_BAT_OVER_VOLT_DET_MASK		0x80
+	/* Battery Mon 2 */
+#define BD71828_INT_BAT_MON_RES_MASK			0x1
+#define BD71828_INT_BAT_MON_DET_MASK			0x2
+	/* Battery Mon 3 (Coulomb counter) */
+#define BD71828_INT_BAT_CC_MON1_MASK			0x1
+#define BD71828_INT_BAT_CC_MON2_MASK			0x2
+#define BD71828_INT_BAT_CC_MON3_MASK			0x4
+	/* Battery Mon 4 */
+#define BD71828_INT_BAT_OVER_CURR_1_RES_MASK		0x1
+#define BD71828_INT_BAT_OVER_CURR_1_DET_MASK		0x2
+#define BD71828_INT_BAT_OVER_CURR_2_RES_MASK		0x4
+#define BD71828_INT_BAT_OVER_CURR_2_DET_MASK		0x8
+#define BD71828_INT_BAT_OVER_CURR_3_RES_MASK		0x10
+#define BD71828_INT_BAT_OVER_CURR_3_DET_MASK		0x20
+	/* Temperature */
+#define BD71828_INT_TEMP_BAT_LOW_RES_MASK		0x1
+#define BD71828_INT_TEMP_BAT_LOW_DET_MASK		0x2
+#define BD71828_INT_TEMP_BAT_HI_RES_MASK		0x4
+#define BD71828_INT_TEMP_BAT_HI_DET_MASK		0x8
+#define BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK		0x10
+#define BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK		0x20
+#define BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK		0x40
+#define BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK		0x80
+	/* RTC Alarm */
+#define BD71828_INT_RTC0_MASK				0x1
+#define BD71828_INT_RTC1_MASK				0x2
+#define BD71828_INT_RTC2_MASK				0x4
+
+#define BD71828_OUT32K_EN				0x1
+#define BD71828_OUT_TYPE_MASK				0x2
+#define BD71828_OUT_TYPE_OPEN_DRAIN			0x0
+#define BD71828_OUT_TYPE_CMOS				0x2
+
+#endif /* __LINUX_MFD_BD71828_H__ */
diff --git a/include/linux/mfd/rohm-generic.h b/include/linux/mfd/rohm-generic.h
index bff15ac26f2c..b280f3100d6c 100644
--- a/include/linux/mfd/rohm-generic.h
+++ b/include/linux/mfd/rohm-generic.h
@@ -8,6 +8,7 @@ enum {
 	ROHM_CHIP_TYPE_BD71837 = 0,
 	ROHM_CHIP_TYPE_BD71847,
 	ROHM_CHIP_TYPE_BD70528,
+	ROHM_CHIP_TYPE_BD71828,
 	ROHM_CHIP_TYPE_AMOUNT
 };
 
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
  2019-11-01 11:29 ` [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core Matti Vaittinen
@ 2019-11-01 11:31 ` Matti Vaittinen
  2019-11-05 20:43   ` Rob Herring
  2019-11-01 11:31 ` [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings Matti Vaittinen
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:31 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

ROHM BD71828 Power management IC integrates 7 buck converters, 7 LDOs,
a real-time clock (RTC), 3 GPO/regulator control pins, HALL input
and a 32.768 kHz clock gate.

Document the dt bindings drivers are using.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - my first encounter with yaml :/

 .../bindings/mfd/rohm,bd71828-pmic.yaml       | 249 ++++++++++++++++++
 1 file changed, 249 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml

diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
new file mode 100644
index 000000000000..b2a88f6e1bb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
@@ -0,0 +1,249 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/rohm,bd71828-pmic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ROHM BD71828 Power Management Integrated Circuit bindings
+
+maintainers:
+  - Lee Jones <lee.jones@linaro.org>
+  - Rob Herring <robh@kernel.org>
+  - Mark Rutland <mark.rutland@arm.com>
+
+description: |
+  BD71828GW is a single-chip power management IC for battery-powered portable
+  devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA
+  single-cell linear charger. Also included is a Coulomb counter, a real-time
+  clock (RTC), and a 32.768 kHz clock gate.
+
+  The BD71828 RUN state is divided into 4 configurable run-levels named RUN0,
+  RUN1, RUN2 and RUN3. Bucks 1, 2, 6 and 7 can be either controlled individually
+  via I2C, or some/all of them can be bound to run-levels and controlled as a
+  group. If bucks are controlled individually these run-levels are ignored. See
+  ../regulator/rohm,bd71828-regulator.yaml for how to define regulator voltages
+  for run-levels. Run-levels can be changed by I2C or GPIO depending on PMIC's
+  OTP configuration.
+
+properties:
+  compatible:
+    const: rohm,bd71828
+  reg:
+    description:
+      I2C slave address.
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+    description:
+      The interrupt line the device is connected to.
+
+  gpio-controller: true
+      # Indicate BD71828 acts as a GPIO controller.
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      The first cell is the pin number and the second cell is used to specify
+      flags. See ../gpio/gpio.txt for more information.
+
+  clocks:
+    description:
+      The parent clock connected to PMIC.
+
+  "#clock-cells":
+    const: 0
+
+  rohm,charger-sense-resistor:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description: |
+      BD71827 and BD71828 have SAR ADC for measuring charging currents.
+      External sense resistor (RSENSE in data sheet) should be used. If some
+      other but 30MOhm resistor is used the resistance value should be given
+      here in Ohms.
+
+  regulators:
+    $ref: ../regulator/rohm,bd71828-regulator.yaml
+    description:
+      List of child nodes that specify the regulators.
+
+  leds:
+    $ref: ../leds/rohm,leds-bd71828.yaml
+
+  clock-output-names:
+    description:
+      Should contain name for output clock.
+
+  rohm,dvs-vsel-gpios:
+    description: |
+      GPIOs used to control PMIC run-levels. Should describe two GPIOs.
+      (See run-level control in data-sheet). If this property is omitted but
+      some bucks are marked to be controlled by run-levels - then OTP option
+      allowing run-level control via I2C is assumed.
+
+  gpio-reserved-ranges:
+    description: |
+      Usage of BD71828 GPIO pins can be changed via OTP. This property can be
+      used to mark the pins which should not be configured for GPIO. Please see
+      the ../gpio/gpio.txt for more information.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - "#clock-cells"
+  - regulators
+  - gpio-controller
+  - "#gpio-cells"
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/leds/common.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pmic: pmic@4b {
+            compatible = "rohm,bd71828";
+            reg = <0x4b>;
+
+            interrupt-parent = <&gpio1>;
+            interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+
+            clocks = <&osc 0>;
+            #clock-cells = <0>;
+            clock-output-names = "bd71828-32k-out";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            gpio-reserved-ranges = <0 1 2 1>;
+
+            rohm,dvs-vsel-gpios = <&gpio1 12 0>, <&gpio1 13 0>;
+            rohm,charger-sense-resistor = <10000000>;
+
+            regulators {
+                buck1: BUCK1 {
+                    regulator-name = "buck1";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                    rohm,dvs-runlvl-ctrl;
+                    rohm,dvs-runlevel0-voltage = <500000>;
+                    rohm,dvs-runlevel1-voltage = <506250>;
+                    rohm,dvs-runlevel2-voltage = <512500>;
+                    rohm,dvs-runlevel3-voltage = <518750>;
+                    regulator-boot-on;
+                };
+                buck2: BUCK2 {
+                    regulator-name = "buck2";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                    rohm,dvs-runlvl-ctrl;
+                    rohm,dvs-runlevel0-voltage = <500000>;
+                    rohm,dvs-runlevel1-voltage = <506250>;
+                    rohm,dvs-runlevel2-voltage = <512500>;
+                    rohm,dvs-runlevel3-voltage = <518750>;
+                    regulator-boot-on;
+                };
+                buck3: BUCK3 {
+                    regulator-name = "buck3";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-boot-on;
+                };
+                buck4: BUCK4 {
+                    regulator-name = "buck4";
+                    regulator-min-microvolt = <1000000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-boot-on;
+                };
+                buck5: BUCK5 {
+                    regulator-name = "buck5";
+                    regulator-min-microvolt = <2500000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+                buck6: BUCK6 {
+                    regulator-name = "buck6";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                    rohm,dvs-runlvl-ctrl;
+                    rohm,dvs-runlevel0-voltage = <500000>;
+                    rohm,dvs-runlevel1-voltage = <506250>;
+                    rohm,dvs-runlevel2-voltage = <512500>;
+                    rohm,dvs-runlevel3-voltage = <518750>;
+                    regulator-boot-on;
+                };
+                buck7: BUCK7 {
+                    regulator-name = "buck7";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                    rohm,dvs-runlvl-ctrl;
+                    rohm,dvs-runlevel0-voltage = <500000>;
+                    rohm,dvs-runlevel1-voltage = <506250>;
+                    rohm,dvs-runlevel2-voltage = <512500>;
+                    rohm,dvs-runlevel3-voltage = <518750>;
+                    regulator-boot-on;
+                };
+                ldo1: LDO1 {
+                    regulator-name = "ldo1";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+                ldo2: LDO2 {
+                    regulator-name = "ldo2";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+                ldo3: LDO3 {
+                    regulator-name = "ldo3";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+                ldo4: LDO4 {
+                    regulator-name = "ldo4";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+                ldo5: LDO5 {
+                    regulator-name = "ldo5";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+                ldo6: LDO6 {
+                    regulator-name = "ldo6";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-boot-on;
+                };
+                ldo7_reg: LDO7 {
+                    regulator-name = "ldo7";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                };
+            };
+
+            leds {
+                compatible = "rohm,bd71828-led";
+
+                led-1 {
+                    function = LED_FUNCTION_INDICATOR;
+                    color = <LED_COLOR_ID_GREEN>;
+                };
+                led-2 {
+                    function = LED_FUNCTION_CHARGING;
+                    color = <LED_COLOR_ID_AMBER>;
+                };
+            };
+        };
+    };
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
  2019-11-01 11:29 ` [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core Matti Vaittinen
  2019-11-01 11:31 ` [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings Matti Vaittinen
@ 2019-11-01 11:31 ` Matti Vaittinen
  2019-11-05 20:52   ` Rob Herring
  2019-11-01 11:32 ` [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver Matti Vaittinen
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:31 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Document ROHM BD71828 PMIC regulator device tree bindings.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - my first encounter with yaml :/

 .../regulator/rohm,bd71828-regulator.yaml     | 123 ++++++++++++++++++
 1 file changed, 123 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml

diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
new file mode 100644
index 000000000000..60715d8b92df
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/rohm,bd71828-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ROHM BD71828 Power Management Integrated Circuit regulators
+
+maintainers:
+  - Liam Girdwood <lgirdwood@gmail.com>
+  - Mark Brown <broonie@kernel.org>
+  - Rob Herring <robh+dt@kernel.org>
+  - Mark Rutland <mark.rutland@arm.com>
+
+description: |
+  This module is part of the ROHM BD71828 MFD device. For more details
+  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
+
+  The regulator controller is represented as a sub-node of the PMIC node
+  on the device tree.
+
+  Regulator nodes should be named to BUCK_<number> and LDO_<number>.
+  The valid names for BD71828 regulator nodes are
+  BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7
+  LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
+
+patternProperties:
+  "^LDO[1-7]$":
+    type: object
+    allOf:
+      - $ref: regulator.yaml#
+    description:
+      Properties for single LDO regulator.
+
+    properties:
+      #Is there a nice way to check the name is same as node name but lower case
+      regulator-name:
+        description:
+          should be "ldo1", ..., "ldo7"
+
+  "^BUCK[1-7]$":
+    type: object
+    allOf:
+      - $ref: regulator.yaml#
+    description:
+      Properties for single BUCK regulator.
+
+    properties:
+      #Is there a nice way to check the name is same as node name but lower case
+      regulator-name:
+        description:
+          should be "buck1", ..., "buck7"
+
+      rohm,dvs-run-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          PMIC default "RUN" state voltage in uV. See below table for
+          bucks which support this.
+
+      rohm,dvs-idle-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          PMIC default "IDLE" state voltage in uV. See below table for
+          bucks which support this.
+
+      rohm,dvs-suspend-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          PMIC default "SUSPEND" state voltage in uV. See below table for
+          bucks which support this.
+
+      rohm,dvs-lpsr-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          PMIC default "LPSR" state voltage in uV. See below table for
+          bucks which support this.
+
+#Supported default DVS states:
+#buck		| run		| idle		| suspend	| lpsr
+#----------------------------------------------------------------------------
+#1, 2, 6, and 7	| supported	| supported	| 	supported (*)
+#----------------------------------------------------------------------------
+#3, 4, and 5	| 			supported (**)
+#----------------------------------------------------------------------------
+#(*)  LPSR and SUSPEND states use same voltage but both states have own enable /
+#     disable settings. Voltage 0 can be specified for a state to make regulator
+#     disabled on that state.
+#(**) All states use same voltage but have own enable / disable settings.
+#     Voltage 0 can be specified for a state to make regulator disabled on that
+#     state.
+
+      rohm,dvs-runlvl-ctrl:
+        description: |
+          buck control is done based on run-level. Regulator is not
+          individually controllable. See ../mfd/rohm,bd71828-pmic.yaml for
+          how to specify run-level control mechanism. Only bucks 1, 2, 6
+          and 7 support this.
+        type: boolean
+
+      rohm,dvs-runlevel0-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          voltage for run-level 0. Microvolts.
+
+      rohm,dvs-runlevel1-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          voltage for run-level 1. Microvolts.
+
+      rohm,dvs-runlevel2-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          voltage for run-level 2. Microvolts.
+
+      rohm,dvs-runlevel3-voltage:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description:
+          voltage for run-level 3. Microvolts.
+
+    required:
+      - regulator-name
+  additionalProperties: false
+additionalProperties: false
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (2 preceding siblings ...)
  2019-11-01 11:31 ` [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings Matti Vaittinen
@ 2019-11-01 11:32 ` Matti Vaittinen
  2019-11-05 19:14   ` Dan Murphy
  2019-11-05 20:57   ` Rob Herring
  2019-11-01 11:33 ` [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support Matti Vaittinen
                   ` (11 subsequent siblings)
  15 siblings, 2 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:32 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Document ROHM BD71828 PMIC LED driver device tree bindings.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - new patch

 .../bindings/leds/rohm,leds-bd71828.yaml      | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml

diff --git a/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
new file mode 100644
index 000000000000..d8aeac9911ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/rohm,leds-bd71828.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ROHM BD71828 Power Management Integrated Circuit LED driver
+
+maintainers:
+  - Jacek Anaszewski <jacek.anaszewski@gmail.com>
+  - Pavel Machek <pavel@ucw.cz>
+  - Dan Murphy <dmurphy@ti.com>
+  - Rob Herring <robh+dt@kernel.org>
+  - Mark Rutland <mark.rutland@arm.com>
+
+description: |
+  This module is part of the ROHM BD71828 MFD device. For more details
+  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
+
+  The LED controller is represented as a sub-node of the PMIC node on the device
+  tree.
+
+  The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.
+
+properties:
+  compatible:
+    const: rohm,bd71828-led
+
+patternProperties:
+  "^led-[1-2]$":
+    type: object
+    description:
+      Properties for a single LED. Nodes must be named as led-1 and led-2.
+    properties:
+      #$ref: "common.yaml#"
+      function:
+        description:
+          Purpose of LED as defined in dt-bindings/leds/common.h
+        $ref: "/schemas/types.yaml#/definitions/string"
+      color:
+        description:
+          LED colour as defined in dt-bindings/leds/common.h
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+
+required:
+  - compatible
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (3 preceding siblings ...)
  2019-11-01 11:32 ` [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver Matti Vaittinen
@ 2019-11-01 11:33 ` Matti Vaittinen
  2019-11-11 10:59   ` Lee Jones
  2019-11-01 11:38 ` [RFC PATCH v3 06/15] clk: bd718x7: Support ROHM BD71828 clk block Matti Vaittinen
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:33 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Use gpio_keys to send power input-event to user-space when power
button (short) press is detected.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - No changes

 drivers/mfd/rohm-bd71828.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index b7de79e1fcdb..f77ba1ec3e99 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -4,7 +4,9 @@
 //
 // ROHM BD71828 PMIC driver
 
+#include <linux/gpio_keys.h>
 #include <linux/i2c.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -15,6 +17,18 @@
 #include <linux/regmap.h>
 #include <linux/types.h>
 
+static struct gpio_keys_button button = {
+	.code = KEY_POWER,
+	.gpio = -1,
+	.type = EV_KEY,
+};
+
+static struct gpio_keys_platform_data bd71828_powerkey_data = {
+	.buttons = &button,
+	.nbuttons = 1,
+	.name = "bd71828-pwrkey",
+};
+
 static const struct resource rtc_irqs[] = {
 	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"),
 	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"),
@@ -36,6 +50,10 @@ static struct mfd_cell bd71828_mfd_cells[] = {
 		.name = "bd70528-rtc",
 		.resources = rtc_irqs,
 		.num_resources = ARRAY_SIZE(rtc_irqs),
+	}, {
+		.name = "gpio-keys",
+		.platform_data = &bd71828_powerkey_data,
+		.pdata_size = sizeof(bd71828_powerkey_data),
 	},
 };
 
@@ -288,9 +306,19 @@ static int bd71828_i2c_probe(struct i2c_client *i2c,
 		dev_err(&i2c->dev, "Failed to add IRQ chip\n");
 		return ret;
 	}
+
 	dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
 		bd71828_irq_chip.num_irqs);
 
+	ret = regmap_irq_get_virq(irq_data, BD71828_INT_SHORTPUSH);
+
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to get the power-key IRQ\n");
+		return ret;
+	}
+
+	button.irq = ret;
+
 	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
 				   bd71828_mfd_cells,
 				   ARRAY_SIZE(bd71828_mfd_cells), NULL, 0,
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 06/15] clk: bd718x7: Support ROHM BD71828 clk block
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (4 preceding siblings ...)
  2019-11-01 11:33 ` [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support Matti Vaittinen
@ 2019-11-01 11:38 ` Matti Vaittinen
  2019-11-01 11:39 ` [RFC PATCH v3 07/15] clk: bd718x7: simplify header dependencies Matti Vaittinen
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:38 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

BD71828GW is a single-chip power management IC for battery-powered portable
devices. Add support for controlling BD71828 clk using bd718x7 driver.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - use unsigned int for clk_set

 drivers/clk/Kconfig       |  6 +++---
 drivers/clk/clk-bd718x7.c | 15 ++++++++++-----
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c44247d0b83e..71c5dfdc78f4 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -293,10 +293,10 @@ config COMMON_CLK_STM32H7
 	  Support for stm32h7 SoC family clocks
 
 config COMMON_CLK_BD718XX
-	tristate "Clock driver for ROHM BD718x7 PMIC"
-	depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528
+	tristate "Clock driver for 32K clk gates on ROHM PMICs"
+	depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828
 	help
-	  This driver supports ROHM BD71837, ROHM BD71847 and
+	  This driver supports ROHM BD71837, ROHM BD71847, ROHM BD71828 and
 	  ROHM BD70528 PMICs clock gates.
 
 config COMMON_CLK_FIXED_MMIO
diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c
index ae6e5baee330..ca627e1d0ef9 100644
--- a/drivers/clk/clk-bd718x7.c
+++ b/drivers/clk/clk-bd718x7.c
@@ -8,6 +8,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/mfd/rohm-bd718x7.h>
+#include <linux/mfd/rohm-bd71828.h>
 #include <linux/mfd/rohm-bd70528.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
@@ -21,10 +22,8 @@ struct bd718xx_clk {
 	struct rohm_regmap_dev *mfd;
 };
 
-static int bd71837_clk_set(struct clk_hw *hw, int status)
+static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status)
 {
-	struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
-
 	return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status);
 }
 
@@ -33,14 +32,16 @@ static void bd71837_clk_disable(struct clk_hw *hw)
 	int rv;
 	struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
 
-	rv = bd71837_clk_set(hw, 0);
+	rv = bd71837_clk_set(c, 0);
 	if (rv)
 		dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv);
 }
 
 static int bd71837_clk_enable(struct clk_hw *hw)
 {
-	return bd71837_clk_set(hw, 1);
+	struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
+
+	return bd71837_clk_set(c, 0xffffffff);
 }
 
 static int bd71837_clk_is_enabled(struct clk_hw *hw)
@@ -93,6 +94,10 @@ static int bd71837_clk_probe(struct platform_device *pdev)
 		c->reg = BD718XX_REG_OUT32K;
 		c->mask = BD718XX_OUT32K_EN;
 		break;
+	case ROHM_CHIP_TYPE_BD71828:
+		c->reg = BD71828_REG_OUT32K;
+		c->mask = BD71828_OUT32K_EN;
+		break;
 	case ROHM_CHIP_TYPE_BD70528:
 		c->reg = BD70528_REG_CLK_OUT;
 		c->mask = BD70528_CLK_OUT_EN_MASK;
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 07/15] clk: bd718x7: simplify header dependencies
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (5 preceding siblings ...)
  2019-11-01 11:38 ` [RFC PATCH v3 06/15] clk: bd718x7: Support ROHM BD71828 clk block Matti Vaittinen
@ 2019-11-01 11:39 ` Matti Vaittinen
  2019-11-01 11:41 ` [RFC PATCH v3 08/15] regulator: bd718x7: Split driver to common and bd718x7 specific parts Matti Vaittinen
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:39 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

The clk control on ROHM BD71837, BD71847, BD70528 and BD71828 is
really simple. Only one register is accessed. Furthermore no other
drivers but the clk driver needs access to those registers. It's a
bit of an overkill to include all of the PMIC register information
in clk driver.

Define clk control register addresses and mask in the clk driver
and drop the unnecessary PMIC header includes.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - new patch.

 drivers/clk/clk-bd718x7.c        | 26 +++++++++++++++++++-------
 include/linux/mfd/rohm-bd70528.h |  6 ------
 include/linux/mfd/rohm-bd71828.h |  4 ----
 include/linux/mfd/rohm-bd718x7.h |  6 ------
 4 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c
index ca627e1d0ef9..75190d6d3672 100644
--- a/drivers/clk/clk-bd718x7.c
+++ b/drivers/clk/clk-bd718x7.c
@@ -7,13 +7,25 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/mfd/rohm-bd718x7.h>
-#include <linux/mfd/rohm-bd71828.h>
-#include <linux/mfd/rohm-bd70528.h>
+#include <linux/mfd/rohm-generic.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/regmap.h>
 
+/* clk control registers */
+/* BD70528 */
+#define BD70528_REG_OUT32K	0x2c
+/* BD71828 */
+#define BD71828_REG_OUT32K	0x4B
+/* BD71837 and BD71847 */
+#define BD718XX_REG_OUT32K	0x2E
+
+/*
+ * BD71837, BD71847, BD70528 and BD71828 all use bit [0] to clk output control
+ */
+#define CLK_OUT_EN_MASK		BIT(0)
+
+
 struct bd718xx_clk {
 	struct clk_hw hw;
 	u8 reg;
@@ -92,15 +104,15 @@ static int bd71837_clk_probe(struct platform_device *pdev)
 	case ROHM_CHIP_TYPE_BD71837:
 	case ROHM_CHIP_TYPE_BD71847:
 		c->reg = BD718XX_REG_OUT32K;
-		c->mask = BD718XX_OUT32K_EN;
+		c->mask = CLK_OUT_EN_MASK;
 		break;
 	case ROHM_CHIP_TYPE_BD71828:
 		c->reg = BD71828_REG_OUT32K;
-		c->mask = BD71828_OUT32K_EN;
+		c->mask = CLK_OUT_EN_MASK;
 		break;
 	case ROHM_CHIP_TYPE_BD70528:
-		c->reg = BD70528_REG_CLK_OUT;
-		c->mask = BD70528_CLK_OUT_EN_MASK;
+		c->reg = BD70528_REG_OUT32K;
+		c->mask = CLK_OUT_EN_MASK;
 		break;
 	default:
 		dev_err(&pdev->dev, "Unknown clk chip\n");
diff --git a/include/linux/mfd/rohm-bd70528.h b/include/linux/mfd/rohm-bd70528.h
index 1013e60c5b25..2ad2320d0a96 100644
--- a/include/linux/mfd/rohm-bd70528.h
+++ b/include/linux/mfd/rohm-bd70528.h
@@ -89,10 +89,6 @@ struct bd70528_data {
 #define BD70528_REG_GPIO3_OUT	0x52
 #define BD70528_REG_GPIO4_OUT	0x54
 
-/* clk control */
-
-#define BD70528_REG_CLK_OUT	0x2c
-
 /* RTC */
 
 #define BD70528_REG_RTC_COUNT_H		0x2d
@@ -309,8 +305,6 @@ enum {
 
 #define BD70528_GPIO_IN_STATE_BASE 1
 
-#define BD70528_CLK_OUT_EN_MASK 0x1
-
 /* RTC masks to mask out reserved bits */
 
 #define BD70528_MASK_RTC_SEC		0x7f
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
index eb0557eb5314..d013e03f742d 100644
--- a/include/linux/mfd/rohm-bd71828.h
+++ b/include/linux/mfd/rohm-bd71828.h
@@ -183,9 +183,6 @@ enum {
 #define BD71828_REG_CHG_STATE		0x65
 #define BD71828_REG_CHG_FULL		0xd2
 
-/* CLK */
-#define BD71828_REG_OUT32K		0x4B
-
 /* LEDs */
 #define BD71828_REG_LED_CTRL		0x4A
 #define BD71828_MASK_LED_AMBER		0x80
@@ -417,7 +414,6 @@ enum {
 #define BD71828_INT_RTC1_MASK				0x2
 #define BD71828_INT_RTC2_MASK				0x4
 
-#define BD71828_OUT32K_EN				0x1
 #define BD71828_OUT_TYPE_MASK				0x2
 #define BD71828_OUT_TYPE_OPEN_DRAIN			0x0
 #define BD71828_OUT_TYPE_CMOS				0x2
diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
index 7f2dbde402a1..bee2474a8f9f 100644
--- a/include/linux/mfd/rohm-bd718x7.h
+++ b/include/linux/mfd/rohm-bd718x7.h
@@ -191,12 +191,6 @@ enum {
 #define IRQ_ON_REQ		0x02
 #define IRQ_STBY_REQ		0x01
 
-/* BD718XX_REG_OUT32K bits */
-#define BD718XX_OUT32K_EN	0x01
-
-/* BD7183XX gated clock rate */
-#define BD718XX_CLK_RATE 32768
-
 /* ROHM BD718XX irqs */
 enum {
 	BD718XX_INT_STBY_REQ,
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 08/15] regulator: bd718x7: Split driver to common and bd718x7 specific parts
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (6 preceding siblings ...)
  2019-11-01 11:39 ` [RFC PATCH v3 07/15] clk: bd718x7: simplify header dependencies Matti Vaittinen
@ 2019-11-01 11:41 ` Matti Vaittinen
  2019-11-01 11:42 ` [RFC PATCH v3 09/15] regulator: bd71828: Basic support for ROHM bd71828 PMIC regulators Matti Vaittinen
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:41 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Few ROHM PMICs allow setting the voltage states for different system states
like RUN, IDLE, SUSPEND and LPSR. States are then changed via SoC specific
mechanisms. bd718x7 driver implemented device-tree parsing functions for
these state specific voltages. The parsing functions can be re-used by
other ROHM chip drivers like bd71828. Split the generic functions from
bd718x7-regulator.c to rohm-regulator.c and export them for other modules
to use.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes since v2 - no changes.

 drivers/regulator/Kconfig             |   4 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/bd718x7-regulator.c | 183 ++++++++------------------
 drivers/regulator/rohm-regulator.c    |  95 +++++++++++++
 include/linux/mfd/rohm-generic.h      |  44 +++++++
 5 files changed, 199 insertions(+), 128 deletions(-)
 create mode 100644 drivers/regulator/rohm-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 3ee63531f6d5..5182a3d5660c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -197,6 +197,7 @@ config REGULATOR_BD70528
 config REGULATOR_BD718XX
 	tristate "ROHM BD71837 Power Regulator"
 	depends on MFD_ROHM_BD718XX
+	select REGULATOR_ROHM
 	help
 	  This driver supports voltage regulators on ROHM BD71837 PMIC.
 	  This will enable support for the software controllable buck
@@ -790,6 +791,9 @@ config REGULATOR_RN5T618
 	  Say y here to support the regulators found on Ricoh RN5T567,
 	  RN5T618 or RC5T619 PMIC.
 
+config REGULATOR_ROHM
+	tristate
+
 config REGULATOR_RT5033
 	tristate "Richtek RT5033 Regulators"
 	depends on MFD_RT5033
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 2210ba56f9bd..6bcab72c1fc7 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
+obj-$(CONFIG_REGULATOR_ROHM)	+= rohm-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033)	+= rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c
index bdab46a5c461..2dcb010a626c 100644
--- a/drivers/regulator/bd718x7-regulator.c
+++ b/drivers/regulator/bd718x7-regulator.c
@@ -318,6 +318,7 @@ struct reg_init {
 };
 struct bd718xx_regulator_data {
 	struct regulator_desc desc;
+	const struct rohm_dvs_config dvs;
 	const struct reg_init init;
 	const struct reg_init *additional_inits;
 	int additional_init_amnt;
@@ -349,133 +350,15 @@ static const struct reg_init bd71837_ldo6_inits[] = {
 	},
 };
 
-#define NUM_DVS_BUCKS 4
-
-struct of_dvs_setting {
-	const char *prop;
-	unsigned int reg;
-};
-
-static int set_dvs_levels(const struct of_dvs_setting *dvs,
-			  struct device_node *np,
-			  const struct regulator_desc *desc,
-			  struct regmap *regmap)
-{
-	int ret, i;
-	unsigned int uv;
-
-	ret = of_property_read_u32(np, dvs->prop, &uv);
-	if (ret) {
-		if (ret != -EINVAL)
-			return ret;
-		return 0;
-	}
-
-	for (i = 0; i < desc->n_voltages; i++) {
-		ret = regulator_desc_list_voltage_linear_range(desc, i);
-		if (ret < 0)
-			continue;
-		if (ret == uv) {
-			i <<= ffs(desc->vsel_mask) - 1;
-			ret = regmap_update_bits(regmap, dvs->reg,
-						 DVS_BUCK_RUN_MASK, i);
-			break;
-		}
-	}
-	return ret;
-}
-
-static int buck4_set_hw_dvs_levels(struct device_node *np,
+static int buck_set_hw_dvs_levels(struct device_node *np,
 			    const struct regulator_desc *desc,
 			    struct regulator_config *cfg)
 {
-	int ret, i;
-	const struct of_dvs_setting dvs[] = {
-		{
-			.prop = "rohm,dvs-run-voltage",
-			.reg = BD71837_REG_BUCK4_VOLT_RUN,
-		},
-	};
+	struct bd718xx_regulator_data *data;
 
-	for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-		ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-		if (ret)
-			break;
-	}
-	return ret;
-}
-static int buck3_set_hw_dvs_levels(struct device_node *np,
-			    const struct regulator_desc *desc,
-			    struct regulator_config *cfg)
-{
-	int ret, i;
-	const struct of_dvs_setting dvs[] = {
-		{
-			.prop = "rohm,dvs-run-voltage",
-			.reg = BD71837_REG_BUCK3_VOLT_RUN,
-		},
-	};
+	data = container_of(desc, struct bd718xx_regulator_data, desc);
 
-	for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-		ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-		if (ret)
-			break;
-	}
-	return ret;
-}
-
-static int buck2_set_hw_dvs_levels(struct device_node *np,
-			    const struct regulator_desc *desc,
-			    struct regulator_config *cfg)
-{
-	int ret, i;
-	const struct of_dvs_setting dvs[] = {
-		{
-			.prop = "rohm,dvs-run-voltage",
-			.reg = BD718XX_REG_BUCK2_VOLT_RUN,
-		},
-		{
-			.prop = "rohm,dvs-idle-voltage",
-			.reg = BD718XX_REG_BUCK2_VOLT_IDLE,
-		},
-	};
-
-
-
-	for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-		ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-		if (ret)
-			break;
-	}
-	return ret;
-}
-
-static int buck1_set_hw_dvs_levels(struct device_node *np,
-			    const struct regulator_desc *desc,
-			    struct regulator_config *cfg)
-{
-	int ret, i;
-	const struct of_dvs_setting dvs[] = {
-		{
-			.prop = "rohm,dvs-run-voltage",
-			.reg = BD718XX_REG_BUCK1_VOLT_RUN,
-		},
-		{
-			.prop = "rohm,dvs-idle-voltage",
-			.reg = BD718XX_REG_BUCK1_VOLT_IDLE,
-		},
-		{
-			.prop = "rohm,dvs-suspend-voltage",
-			.reg = BD718XX_REG_BUCK1_VOLT_SUSP,
-		},
-	};
-
-	for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-		ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-		if (ret)
-			break;
-	}
-	return ret;
+	return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
 }
 
 static const struct bd718xx_regulator_data bd71847_regulators[] = {
@@ -496,7 +379,17 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.enable_reg = BD718XX_REG_BUCK1_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
-			.of_parse_cb = buck1_set_hw_dvs_levels,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND,
+			.run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
+			.run_mask = DVS_BUCK_RUN_MASK,
+			.idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
+			.idle_mask = DVS_BUCK_RUN_MASK,
+			.suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
+			.suspend_mask = DVS_BUCK_RUN_MASK,
 		},
 		.init = {
 			.reg = BD718XX_REG_BUCK1_CTRL,
@@ -520,7 +413,14 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.enable_reg = BD718XX_REG_BUCK2_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
-			.of_parse_cb = buck2_set_hw_dvs_levels,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
+			.run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
+			.run_mask = DVS_BUCK_RUN_MASK,
+			.idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
+			.idle_mask = DVS_BUCK_RUN_MASK,
 		},
 		.init = {
 			.reg = BD718XX_REG_BUCK2_CTRL,
@@ -792,7 +692,17 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.enable_reg = BD718XX_REG_BUCK1_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
-			.of_parse_cb = buck1_set_hw_dvs_levels,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND,
+			.run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
+			.run_mask = DVS_BUCK_RUN_MASK,
+			.idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
+			.idle_mask = DVS_BUCK_RUN_MASK,
+			.suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
+			.suspend_mask = DVS_BUCK_RUN_MASK,
 		},
 		.init = {
 			.reg = BD718XX_REG_BUCK1_CTRL,
@@ -816,7 +726,14 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.enable_reg = BD718XX_REG_BUCK2_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
-			.of_parse_cb = buck2_set_hw_dvs_levels,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
+			.run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
+			.run_mask = DVS_BUCK_RUN_MASK,
+			.idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
+			.idle_mask = DVS_BUCK_RUN_MASK,
 		},
 		.init = {
 			.reg = BD718XX_REG_BUCK2_CTRL,
@@ -840,7 +757,12 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.enable_reg = BD71837_REG_BUCK3_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
-			.of_parse_cb = buck3_set_hw_dvs_levels,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN,
+			.run_reg = BD71837_REG_BUCK3_VOLT_RUN,
+			.run_mask = DVS_BUCK_RUN_MASK,
 		},
 		.init = {
 			.reg = BD71837_REG_BUCK3_CTRL,
@@ -864,7 +786,12 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.enable_reg = BD71837_REG_BUCK4_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
-			.of_parse_cb = buck4_set_hw_dvs_levels,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN,
+			.run_reg = BD71837_REG_BUCK4_VOLT_RUN,
+			.run_mask = DVS_BUCK_RUN_MASK,
 		},
 		.init = {
 			.reg = BD71837_REG_BUCK4_CTRL,
diff --git a/drivers/regulator/rohm-regulator.c b/drivers/regulator/rohm-regulator.c
new file mode 100644
index 000000000000..ca368ada53c6
--- /dev/null
+++ b/drivers/regulator/rohm-regulator.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+
+#include <linux/errno.h>
+#include <linux/mfd/rohm-generic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+static int set_dvs_level(const struct regulator_desc *desc,
+			 struct device_node *np, struct regmap *regmap,
+			 char *prop, unsigned int reg, unsigned int mask,
+			 unsigned int omask, unsigned int oreg)
+{
+	int ret, i;
+	uint32_t uv;
+
+	ret = of_property_read_u32(np, prop, &uv);
+	if (ret) {
+		if (ret != -EINVAL)
+			return ret;
+		return 0;
+	}
+
+	if (uv == 0) {
+		if (omask)
+			return regmap_update_bits(regmap, oreg, omask, 0);
+	}
+	for (i = 0; i < desc->n_voltages; i++) {
+		ret = regulator_desc_list_voltage_linear_range(desc, i);
+		if (ret < 0)
+			continue;
+		if (ret == uv) {
+			i <<= ffs(desc->vsel_mask) - 1;
+			ret = regmap_update_bits(regmap, reg, mask, i);
+			if (omask && !ret)
+				ret = regmap_update_bits(regmap, oreg, omask,
+							 omask);
+			break;
+		}
+	}
+	return ret;
+}
+
+int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
+			  struct device_node *np,
+			  const struct regulator_desc *desc,
+			  struct regmap *regmap)
+{
+	int i, ret = 0;
+	char *prop;
+	unsigned int reg, mask, omask, oreg = desc->enable_reg;
+
+	for (i = 0; i < ROHM_DVS_LEVEL_MAX && !ret; i++) {
+		if (dvs->level_map & (1 << i)) {
+			switch (i + 1) {
+			case ROHM_DVS_LEVEL_RUN:
+				prop = "rohm,dvs-run-voltage";
+				reg = dvs->run_reg;
+				mask = dvs->run_mask;
+				omask = dvs->run_on_mask;
+				break;
+			case ROHM_DVS_LEVEL_IDLE:
+				prop = "rohm,dvs-idle-voltage";
+				reg = dvs->idle_reg;
+				mask = dvs->idle_mask;
+				omask = dvs->idle_on_mask;
+				break;
+			case ROHM_DVS_LEVEL_SUSPEND:
+				prop = "rohm,dvs-suspend-voltage";
+				reg = dvs->suspend_reg;
+				mask = dvs->suspend_mask;
+				omask = dvs->suspend_on_mask;
+				break;
+			case ROHM_DVS_LEVEL_LPSR:
+				prop = "rohm,dvs-lpsr-voltage";
+				reg = dvs->lpsr_reg;
+				mask = dvs->lpsr_mask;
+				omask = dvs->lpsr_on_mask;
+				break;
+			default:
+				return -EINVAL;
+			}
+			ret = set_dvs_level(desc, np, regmap, prop, reg, mask,
+					    omask, oreg);
+		}
+	}
+	return ret;
+}
+EXPORT_SYMBOL(rohm_regulator_set_dvs_levels);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");
diff --git a/include/linux/mfd/rohm-generic.h b/include/linux/mfd/rohm-generic.h
index b280f3100d6c..86397b42e9bf 100644
--- a/include/linux/mfd/rohm-generic.h
+++ b/include/linux/mfd/rohm-generic.h
@@ -4,6 +4,9 @@
 #ifndef __LINUX_MFD_ROHM_H__
 #define __LINUX_MFD_ROHM_H__
 
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
 enum {
 	ROHM_CHIP_TYPE_BD71837 = 0,
 	ROHM_CHIP_TYPE_BD71847,
@@ -18,4 +21,45 @@ struct rohm_regmap_dev {
 	struct regmap *regmap;
 };
 
+enum {
+	ROHM_DVS_LEVEL_UNKNOWN,
+	ROHM_DVS_LEVEL_RUN,
+	ROHM_DVS_LEVEL_IDLE,
+	ROHM_DVS_LEVEL_SUSPEND,
+	ROHM_DVS_LEVEL_LPSR,
+#define ROHM_DVS_LEVEL_MAX ROHM_DVS_LEVEL_LPSR
+};
+
+struct rohm_dvs_config {
+	uint64_t level_map;
+	unsigned int run_reg;
+	unsigned int run_mask;
+	unsigned int run_on_mask;
+	unsigned int idle_reg;
+	unsigned int idle_mask;
+	unsigned int idle_on_mask;
+	unsigned int suspend_reg;
+	unsigned int suspend_mask;
+	unsigned int suspend_on_mask;
+	unsigned int lpsr_reg;
+	unsigned int lpsr_mask;
+	unsigned int lpsr_on_mask;
+};
+
+#if IS_ENABLED(CONFIG_REGULATOR_ROHM)
+int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
+				  struct device_node *np,
+				  const struct regulator_desc *desc,
+				  struct regmap *regmap);
+
+#else
+static inline int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
+						struct device_node *np,
+						const struct regulator_desc *desc,
+						struct regmap *regmap)
+{
+	return 0;
+}
+#endif //IS_ENABLED(CONFIG_REGULATOR_ROHM)
+
 #endif
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 09/15] regulator: bd71828: Basic support for ROHM bd71828 PMIC regulators
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (7 preceding siblings ...)
  2019-11-01 11:41 ` [RFC PATCH v3 08/15] regulator: bd718x7: Split driver to common and bd718x7 specific parts Matti Vaittinen
@ 2019-11-01 11:42 ` Matti Vaittinen
  2019-11-01 11:43 ` [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators Matti Vaittinen
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:42 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

ROHM BD71828 is a power management IC containing 7 bucks and 7 LDOs. Bucks
1,2,6 and 7 can be assigned to a regulator group controlled by run-levels.
Eg. Voltages and enable/disable statuses for specific run-levels (run0 to
run3) can be set via register interface and run level changes can then be
done either via I2C or GPIO.

This initial commit does not support assigning bucks to be controlled via
run-levels but only allows them to be individually controlled.

LDO5 voltage can also be controlled by GPIO2 pin and register interfaces
but this driver only supports the control via register.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes since v2 - no changes.

 drivers/regulator/Kconfig             |  12 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/bd71828-regulator.c | 833 ++++++++++++++++++++++++++
 3 files changed, 846 insertions(+)
 create mode 100644 drivers/regulator/bd71828-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5182a3d5660c..838bbfcf11ea 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -194,6 +194,18 @@ config REGULATOR_BD70528
 	  This driver can also be built as a module. If so, the module
 	  will be called bd70528-regulator.
 
+config REGULATOR_BD71828
+	tristate "ROHM BD71828 Power Regulator"
+	depends on MFD_ROHM_BD71828
+	select REGULATOR_ROHM
+	help
+	  This driver supports voltage regulators on ROHM BD71828 PMIC.
+	  This will enable support for the software controllable buck
+	  and LDO regulators.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called bd71828-regulator.
+
 config REGULATOR_BD718XX
 	tristate "ROHM BD71837 Power Regulator"
 	depends on MFD_ROHM_BD718XX
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 6bcab72c1fc7..cf0e08c5f3cd 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
 obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
 obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
 obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
+obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
 obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
 obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
new file mode 100644
index 000000000000..3f46658280be
--- /dev/null
+++ b/drivers/regulator/bd71828-regulator.c
@@ -0,0 +1,833 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2019 ROHM Semiconductors
+// bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver
+//
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/rohm-bd71828.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+struct reg_init {
+	unsigned int reg;
+	unsigned int mask;
+	unsigned int val;
+};
+struct bd71828_regulator_data {
+	struct regulator_desc desc;
+	const struct rohm_dvs_config dvs;
+	const struct reg_init *reg_inits;
+	int reg_init_amnt;
+};
+
+static const struct reg_init buck1_inits[] = {
+	/*
+	 * DVS Buck voltages can be changed by register values or via GPIO.
+	 * Use register accesses by default.
+	 */
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK1_CTRL,
+		.val = BD71828_DVS_BUCK1_CTRL_I2C,
+	},
+};
+
+static const struct reg_init buck2_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK2_CTRL,
+		.val = BD71828_DVS_BUCK2_CTRL_I2C,
+	},
+};
+
+static const struct reg_init buck6_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK6_CTRL,
+		.val = BD71828_DVS_BUCK6_CTRL_I2C,
+	},
+};
+
+static const struct reg_init buck7_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK7_CTRL,
+		.val = BD71828_DVS_BUCK7_CTRL_I2C,
+	},
+};
+
+static const struct regulator_linear_range bd71828_buck1267_volts[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250),
+	REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0),
+};
+
+static const struct regulator_linear_range bd71828_buck3_volts[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x0f, 50000),
+	REGULATOR_LINEAR_RANGE(2000000, 0x10, 0x1f, 0),
+};
+
+static const struct regulator_linear_range bd71828_buck4_volts[] = {
+	REGULATOR_LINEAR_RANGE(1000000, 0x00, 0x1f, 25000),
+	REGULATOR_LINEAR_RANGE(1800000, 0x20, 0x3f, 0),
+};
+
+static const struct regulator_linear_range bd71828_buck5_volts[] = {
+	REGULATOR_LINEAR_RANGE(2500000, 0x00, 0x0f, 50000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x10, 0x1f, 0),
+};
+
+static const struct regulator_linear_range bd71828_ldo_volts[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0),
+};
+
+static int ramp_delay_supported(struct regulator_dev *rdev)
+{
+	switch (rdev->desc->id) {
+	case BD71828_BUCK1:
+	case BD71828_BUCK2:
+	case BD71828_BUCK6:
+	case BD71828_BUCK7:
+		return 1;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int bd71828_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+	unsigned int val;
+
+	if (!ramp_delay_supported(rdev)) {
+		dev_err(&rdev->dev, "%s: can't set ramp-delay\n",
+			rdev->desc->name);
+		return -EINVAL;
+	}
+
+	switch (ramp_delay) {
+	case 1 ... 2500:
+		val = 0;
+		break;
+	case 2501 ... 5000:
+		val = 1;
+		break;
+	case 5001 ... 10000:
+		val = 2;
+		break;
+	case 10001 ... 20000:
+		val = 3;
+		break;
+	default:
+		val = 3;
+		dev_err(&rdev->dev,
+			"ramp_delay: %d not supported, setting 20mV/uS",
+			 ramp_delay);
+	}
+
+	/*
+	 * On BD71828 the ramp delay level control reg is at offset +2 to
+	 * enable reg
+	 */
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg + 2,
+				  BD71828_MASK_RAMP_DELAY,
+				  val << (ffs(BD71828_MASK_RAMP_DELAY) - 1));
+
+}
+
+static int buck_set_hw_dvs_levels(struct device_node *np,
+				  const struct regulator_desc *desc,
+				  struct regulator_config *cfg)
+{
+	struct bd71828_regulator_data *data;
+
+	data = container_of(desc, struct bd71828_regulator_data, desc);
+
+	return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
+}
+
+static int ldo6_parse_dt(struct device_node *np,
+			 const struct regulator_desc *desc,
+			 struct regulator_config *cfg)
+{
+	int ret, i;
+	uint32_t uv = 0;
+	unsigned int en;
+	struct regmap *regmap = cfg->regmap;
+	static const char * const props[] = { "rohm,dvs-run-voltage",
+					      "rohm,dvs-idle-voltage",
+					      "rohm,dvs-suspend-voltage",
+					      "rohm,dvs-lpsr-voltage" };
+	unsigned int mask[] = { BD71828_MASK_RUN_EN, BD71828_MASK_IDLE_EN,
+			       BD71828_MASK_SUSP_EN, BD71828_MASK_LPSR_EN };
+
+	for (i = 0; i < ARRAY_SIZE(props); i++) {
+		ret = of_property_read_u32(np, props[i], &uv);
+		if (ret) {
+			if (ret != -EINVAL)
+				return ret;
+			continue;
+		}
+		if (uv)
+			en = 0xffffffff;
+		else
+			en = 0;
+
+		ret = regmap_update_bits(regmap, desc->enable_reg, mask[i], en);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static const struct regulator_ops bd71828_buck_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static const struct regulator_ops bd71828_dvs_buck_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.set_ramp_delay = bd71828_set_ramp_delay,
+};
+
+static const struct regulator_ops bd71828_ldo_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static int bd71828_ldo6_get_voltage(struct regulator_dev *rdev)
+{
+	return BD71828_LDO_6_VOLTAGE;
+}
+
+static const struct regulator_ops bd71828_ldo6_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.get_voltage = bd71828_ldo6_get_voltage,
+	.is_enabled = regulator_is_enabled_regmap,
+};
+
+static const struct bd71828_regulator_data bd71828_rdata[] = {
+	{
+		.desc = {
+			.name = "buck1",
+			.of_match = of_match_ptr("BUCK1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK1,
+			.ops = &bd71828_dvs_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck1267_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
+			.n_voltages = BD71828_BUCK1267_VOLTS,
+			.enable_reg = BD71828_REG_BUCK1_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK1_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK1_VOLT,
+			.run_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_reg = BD71828_REG_BUCK1_IDLE_VOLT,
+			.idle_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+			/*
+			 * LPSR voltage is same as SUSPEND voltage. Allow
+			 * setting it so that regulator can be set enabled at
+			 * LPSR state
+			 */
+			.lpsr_reg = BD71828_REG_BUCK1_SUSP_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
+		},
+		.reg_inits = buck1_inits,
+		.reg_init_amnt = ARRAY_SIZE(buck1_inits),
+	},
+	{
+		.desc = {
+			.name = "buck2",
+			.of_match = of_match_ptr("BUCK2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK2,
+			.ops = &bd71828_dvs_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck1267_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
+			.n_voltages = BD71828_BUCK1267_VOLTS,
+			.enable_reg = BD71828_REG_BUCK2_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK2_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK2_VOLT,
+			.run_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_reg = BD71828_REG_BUCK2_IDLE_VOLT,
+			.idle_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_reg = BD71828_REG_BUCK2_SUSP_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+			.lpsr_reg = BD71828_REG_BUCK2_SUSP_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
+		},
+		.reg_inits = buck2_inits,
+		.reg_init_amnt = ARRAY_SIZE(buck2_inits),
+	},
+	{
+		.desc = {
+			.name = "buck3",
+			.of_match = of_match_ptr("BUCK3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK3,
+			.ops = &bd71828_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck3_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck3_volts),
+			.n_voltages = BD71828_BUCK3_VOLTS,
+			.enable_reg = BD71828_REG_BUCK3_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK3_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK3_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * BUCK3 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK3_VOLT,
+			.idle_reg = BD71828_REG_BUCK3_VOLT,
+			.suspend_reg = BD71828_REG_BUCK3_VOLT,
+			.lpsr_reg = BD71828_REG_BUCK3_VOLT,
+			.run_mask = BD71828_MASK_BUCK3_VOLT,
+			.idle_mask = BD71828_MASK_BUCK3_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK3_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK3_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck4",
+			.of_match = of_match_ptr("BUCK4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK4,
+			.ops = &bd71828_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck4_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck4_volts),
+			.n_voltages = BD71828_BUCK4_VOLTS,
+			.enable_reg = BD71828_REG_BUCK4_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK4_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK4_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * BUCK4 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK4_VOLT,
+			.idle_reg = BD71828_REG_BUCK4_VOLT,
+			.suspend_reg = BD71828_REG_BUCK4_VOLT,
+			.lpsr_reg = BD71828_REG_BUCK4_VOLT,
+			.run_mask = BD71828_MASK_BUCK4_VOLT,
+			.idle_mask = BD71828_MASK_BUCK4_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK4_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK4_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck5",
+			.of_match = of_match_ptr("BUCK5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK5,
+			.ops = &bd71828_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck5_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck5_volts),
+			.n_voltages = BD71828_BUCK5_VOLTS,
+			.enable_reg = BD71828_REG_BUCK5_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK5_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK5_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * BUCK5 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK5_VOLT,
+			.idle_reg = BD71828_REG_BUCK5_VOLT,
+			.suspend_reg = BD71828_REG_BUCK5_VOLT,
+			.lpsr_reg = BD71828_REG_BUCK5_VOLT,
+			.run_mask = BD71828_MASK_BUCK5_VOLT,
+			.idle_mask = BD71828_MASK_BUCK5_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK5_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK5_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck6",
+			.of_match = of_match_ptr("BUCK6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK6,
+			.ops = &bd71828_dvs_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck1267_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
+			.n_voltages = BD71828_BUCK1267_VOLTS,
+			.enable_reg = BD71828_REG_BUCK6_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK6_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK6_VOLT,
+			.run_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_reg = BD71828_REG_BUCK6_IDLE_VOLT,
+			.idle_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_reg = BD71828_REG_BUCK6_SUSP_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+			.lpsr_reg = BD71828_REG_BUCK6_SUSP_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
+		},
+		.reg_inits = buck6_inits,
+		.reg_init_amnt = ARRAY_SIZE(buck6_inits),
+	},
+	{
+		.desc = {
+			.name = "buck7",
+			.of_match = of_match_ptr("BUCK7"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_BUCK7,
+			.ops = &bd71828_dvs_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_buck1267_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
+			.n_voltages = BD71828_BUCK1267_VOLTS,
+			.enable_reg = BD71828_REG_BUCK7_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_BUCK7_VOLT,
+			.vsel_mask = BD71828_MASK_BUCK1267_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_BUCK7_VOLT,
+			.run_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_reg = BD71828_REG_BUCK7_IDLE_VOLT,
+			.idle_mask = BD71828_MASK_BUCK1267_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_reg = BD71828_REG_BUCK7_SUSP_VOLT,
+			.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+			.lpsr_reg = BD71828_REG_BUCK7_SUSP_VOLT,
+			.lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
+		},
+		.reg_inits = buck7_inits,
+		.reg_init_amnt = ARRAY_SIZE(buck7_inits),
+	},
+	{
+		.desc = {
+			.name = "ldo1",
+			.of_match = of_match_ptr("LDO1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO1,
+			.ops = &bd71828_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_ldo_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
+			.n_voltages = BD71828_LDO_VOLTS,
+			.enable_reg = BD71828_REG_LDO1_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_LDO1_VOLT,
+			.vsel_mask = BD71828_MASK_LDO_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * LDO1 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_LDO1_VOLT,
+			.idle_reg = BD71828_REG_LDO1_VOLT,
+			.suspend_reg = BD71828_REG_LDO1_VOLT,
+			.lpsr_reg = BD71828_REG_LDO1_VOLT,
+			.run_mask = BD71828_MASK_LDO_VOLT,
+			.idle_mask = BD71828_MASK_LDO_VOLT,
+			.suspend_mask = BD71828_MASK_LDO_VOLT,
+			.lpsr_mask = BD71828_MASK_LDO_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+	}, {
+		.desc = {
+			.name = "ldo2",
+			.of_match = of_match_ptr("LDO2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO2,
+			.ops = &bd71828_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_ldo_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
+			.n_voltages = BD71828_LDO_VOLTS,
+			.enable_reg = BD71828_REG_LDO2_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_LDO2_VOLT,
+			.vsel_mask = BD71828_MASK_LDO_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * LDO2 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_LDO2_VOLT,
+			.idle_reg = BD71828_REG_LDO2_VOLT,
+			.suspend_reg = BD71828_REG_LDO2_VOLT,
+			.lpsr_reg = BD71828_REG_LDO2_VOLT,
+			.run_mask = BD71828_MASK_LDO_VOLT,
+			.idle_mask = BD71828_MASK_LDO_VOLT,
+			.suspend_mask = BD71828_MASK_LDO_VOLT,
+			.lpsr_mask = BD71828_MASK_LDO_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+	}, {
+		.desc = {
+			.name = "ldo3",
+			.of_match = of_match_ptr("LDO3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO3,
+			.ops = &bd71828_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_ldo_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
+			.n_voltages = BD71828_LDO_VOLTS,
+			.enable_reg = BD71828_REG_LDO3_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_LDO3_VOLT,
+			.vsel_mask = BD71828_MASK_LDO_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * LDO3 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_LDO3_VOLT,
+			.idle_reg = BD71828_REG_LDO3_VOLT,
+			.suspend_reg = BD71828_REG_LDO3_VOLT,
+			.lpsr_reg = BD71828_REG_LDO3_VOLT,
+			.run_mask = BD71828_MASK_LDO_VOLT,
+			.idle_mask = BD71828_MASK_LDO_VOLT,
+			.suspend_mask = BD71828_MASK_LDO_VOLT,
+			.lpsr_mask = BD71828_MASK_LDO_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+
+	}, {
+		.desc = {
+			.name = "ldo4",
+			.of_match = of_match_ptr("LDO4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO4,
+			.ops = &bd71828_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_ldo_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
+			.n_voltages = BD71828_LDO_VOLTS,
+			.enable_reg = BD71828_REG_LDO4_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_LDO4_VOLT,
+			.vsel_mask = BD71828_MASK_LDO_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * LDO1 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_LDO4_VOLT,
+			.idle_reg = BD71828_REG_LDO4_VOLT,
+			.suspend_reg = BD71828_REG_LDO4_VOLT,
+			.lpsr_reg = BD71828_REG_LDO4_VOLT,
+			.run_mask = BD71828_MASK_LDO_VOLT,
+			.idle_mask = BD71828_MASK_LDO_VOLT,
+			.suspend_mask = BD71828_MASK_LDO_VOLT,
+			.lpsr_mask = BD71828_MASK_LDO_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+	}, {
+		.desc = {
+			.name = "ldo5",
+			.of_match = of_match_ptr("LDO5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO5,
+			.ops = &bd71828_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_ldo_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
+			.n_voltages = BD71828_LDO_VOLTS,
+			.enable_reg = BD71828_REG_LDO5_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_LDO5_VOLT,
+			.vsel_mask = BD71828_MASK_LDO_VOLT,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+			.owner = THIS_MODULE,
+		},
+		/*
+		 * LDO5 is special. It can choose vsel settings to be configured
+		 * from 2 different registers (by GPIO).
+		 *
+		 * This driver supports only configuration where
+		 * BD71828_REG_LDO5_VOLT_L is used.
+		 */
+		.dvs = {
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_LDO5_VOLT,
+			.idle_reg = BD71828_REG_LDO5_VOLT,
+			.suspend_reg = BD71828_REG_LDO5_VOLT,
+			.lpsr_reg = BD71828_REG_LDO5_VOLT,
+			.run_mask = BD71828_MASK_LDO_VOLT,
+			.idle_mask = BD71828_MASK_LDO_VOLT,
+			.suspend_mask = BD71828_MASK_LDO_VOLT,
+			.lpsr_mask = BD71828_MASK_LDO_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+
+	}, {
+		.desc = {
+			.name = "ldo6",
+			.of_match = of_match_ptr("LDO6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO6,
+			.ops = &bd71828_ldo6_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = 1,
+			.enable_reg = BD71828_REG_LDO6_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.owner = THIS_MODULE,
+			/*
+			 * LDO6 only supports enable/disable for all states.
+			 * Voltage for LDO6 is fixed.
+			 */
+			.of_parse_cb = ldo6_parse_dt,
+		},
+	}, {
+		.desc = {
+			/* SNVS LDO in data-sheet */
+			.name = "ldo7",
+			.of_match = of_match_ptr("LDO7"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD71828_LDO_SNVS,
+			.ops = &bd71828_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.linear_ranges = bd71828_ldo_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
+			.n_voltages = BD71828_LDO_VOLTS,
+			.enable_reg = BD71828_REG_LDO7_EN,
+			.enable_mask = BD71828_MASK_RUN_EN,
+			.vsel_reg = BD71828_REG_LDO7_VOLT,
+			.vsel_mask = BD71828_MASK_LDO_VOLT,
+			.owner = THIS_MODULE,
+			.of_parse_cb = buck_set_hw_dvs_levels,
+		},
+		.dvs = {
+			/*
+			 * LDO7 only supports single voltage for all states.
+			 * voltage can be individually enabled for each state
+			 * though => allow setting all states to support
+			 * enabling power rail on different states.
+			 */
+			.level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+				     ROHM_DVS_LEVEL_SUSPEND |
+				     ROHM_DVS_LEVEL_LPSR,
+			.run_reg = BD71828_REG_LDO7_VOLT,
+			.idle_reg = BD71828_REG_LDO7_VOLT,
+			.suspend_reg = BD71828_REG_LDO7_VOLT,
+			.lpsr_reg = BD71828_REG_LDO7_VOLT,
+			.run_mask = BD71828_MASK_LDO_VOLT,
+			.idle_mask = BD71828_MASK_LDO_VOLT,
+			.suspend_mask = BD71828_MASK_LDO_VOLT,
+			.lpsr_mask = BD71828_MASK_LDO_VOLT,
+			.idle_on_mask = BD71828_MASK_IDLE_EN,
+			.suspend_on_mask = BD71828_MASK_SUSP_EN,
+			.lpsr_on_mask = BD71828_MASK_LPSR_EN,
+		},
+
+	},
+};
+
+static int bd71828_probe(struct platform_device *pdev)
+{
+	struct rohm_regmap_dev *bd71828;
+	int i, j, ret;
+	struct regulator_config config = {
+		.dev = pdev->dev.parent,
+	};
+
+	bd71828 = dev_get_drvdata(pdev->dev.parent);
+	if (!bd71828) {
+		dev_err(&pdev->dev, "No MFD driver data\n");
+		return -EINVAL;
+	}
+
+	config.regmap = bd71828->regmap;
+
+	for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
+		struct regulator_dev *rdev;
+		const struct bd71828_regulator_data *rd;
+
+		rd = &bd71828_rdata[i];
+		rdev = devm_regulator_register(&pdev->dev,
+					       &rd->desc, &config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev,
+				"failed to register %s regulator\n",
+				rd->desc.name);
+			return PTR_ERR(rdev);
+		}
+		for (j = 0; j < rd->reg_init_amnt; j++) {
+			ret = regmap_update_bits(bd71828->regmap,
+						 rd->reg_inits[j].reg,
+						 rd->reg_inits[j].mask,
+						 rd->reg_inits[j].val);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"regulator %s init failed\n",
+					rd->desc.name);
+				return ret;
+			}
+		}
+	}
+	return 0;
+}
+
+static struct platform_driver bd71828_regulator = {
+	.driver = {
+		.name = "bd71828-pmic"
+	},
+	.probe = bd71828_probe,
+};
+
+module_platform_driver(bd71828_regulator);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71828 voltage regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bd71828-pmic");
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (8 preceding siblings ...)
  2019-11-01 11:42 ` [RFC PATCH v3 09/15] regulator: bd71828: Basic support for ROHM bd71828 PMIC regulators Matti Vaittinen
@ 2019-11-01 11:43 ` Matti Vaittinen
  2019-11-03 22:27   ` Linus Walleij
  2019-11-01 11:44 ` [RFC PATCH v3 11/15] regulator: bd71828: enhanced run-level support Matti Vaittinen
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:43 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Bucks 1,2,6 and 7 on ROHM BD71828 can be either controlled as
individual regulartors - or they can be grouped to a group of
regulators that are controlled by 'run levels'. This can be
done via I2C. Each regulator can be assigned a voltage and
enable/disable status for each run-level. These statuses are
also changeable via I2C.

Run-levels can then be changed either by I2C or GPIO. This
control mechanism is selected by data in one time programmable
area (during production) and can't be changed later.

Allow regulators to be controlled via run-levels and allow
getting/setting the current run-level also via GPIO.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes since v2 - fixed typo 'RPHM' => 'ROHM' from commit message

 drivers/regulator/bd71828-regulator.c | 373 +++++++++++++++++++++++++-
 1 file changed, 362 insertions(+), 11 deletions(-)

diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
index 3f46658280be..e82e94ecf747 100644
--- a/drivers/regulator/bd71828-regulator.c
+++ b/drivers/regulator/bd71828-regulator.c
@@ -4,8 +4,10 @@
 //
 
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mfd/rohm-bd71828.h>
@@ -17,16 +19,27 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 
+#define MAX_GPIO_DVS_BUCKS 4
+#define DVS_RUN_LEVELS 4
+
 struct reg_init {
 	unsigned int reg;
 	unsigned int mask;
 	unsigned int val;
 };
+
+struct run_lvl_ctrl {
+	unsigned int voltage;
+	bool enabled;
+};
+
 struct bd71828_regulator_data {
 	struct regulator_desc desc;
-	const struct rohm_dvs_config dvs;
+	struct rohm_dvs_config dvs;
 	const struct reg_init *reg_inits;
 	int reg_init_amnt;
+	struct run_lvl_ctrl run_lvl[DVS_RUN_LEVELS];
+	struct gpio_descs *gps;
 };
 
 static const struct reg_init buck1_inits[] = {
@@ -41,6 +54,14 @@ static const struct reg_init buck1_inits[] = {
 	},
 };
 
+static const struct reg_init buck1_gpio_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK1_CTRL,
+		.val = BD71828_DVS_BUCK1_USE_RUNLVL,
+	},
+};
+
 static const struct reg_init buck2_inits[] = {
 	{
 		.reg = BD71828_REG_PS_CTRL_1,
@@ -49,6 +70,14 @@ static const struct reg_init buck2_inits[] = {
 	},
 };
 
+static const struct reg_init buck2_gpio_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK2_CTRL,
+		.val = BD71828_DVS_BUCK2_USE_RUNLVL,
+	},
+};
+
 static const struct reg_init buck6_inits[] = {
 	{
 		.reg = BD71828_REG_PS_CTRL_1,
@@ -57,6 +86,14 @@ static const struct reg_init buck6_inits[] = {
 	},
 };
 
+static const struct reg_init buck6_gpio_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK6_CTRL,
+		.val = BD71828_DVS_BUCK6_USE_RUNLVL,
+	},
+};
+
 static const struct reg_init buck7_inits[] = {
 	{
 		.reg = BD71828_REG_PS_CTRL_1,
@@ -65,6 +102,14 @@ static const struct reg_init buck7_inits[] = {
 	},
 };
 
+static const struct reg_init buck7_gpio_inits[] = {
+	{
+		.reg = BD71828_REG_PS_CTRL_1,
+		.mask = BD71828_MASK_DVS_BUCK7_CTRL,
+		.val = BD71828_DVS_BUCK7_USE_RUNLVL,
+	},
+};
+
 static const struct regulator_linear_range bd71828_buck1267_volts[] = {
 	REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250),
 	REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0),
@@ -155,6 +200,80 @@ static int buck_set_hw_dvs_levels(struct device_node *np,
 	return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
 }
 
+static int set_runlevel_voltage(struct regmap *regmap,
+				const struct regulator_desc *desc,
+				unsigned int uv, unsigned int level)
+{
+	int i, ret = -EINVAL;
+	/*
+	 * RUN level registers are next to vsel_reg. RUN0 reg is next, then
+	 * is the RUN 1 reg and so on...
+	 */
+	u8 reg = desc->vsel_reg + level + 1;
+	u8 mask = BD71828_MASK_BUCK1267_VOLT;
+
+	for (i = 0; i < desc->n_voltages; i++) {
+		ret = regulator_desc_list_voltage_linear_range(desc, i);
+		if (ret < 0)
+			continue;
+		if (ret == uv) {
+			i <<= ffs(desc->vsel_mask) - 1;
+			ret = regmap_update_bits(regmap, reg, mask, i);
+			break;
+		}
+	}
+	return ret;
+}
+
+static int buck_set_gpio_hw_dvs_levels(struct device_node *np,
+				       const struct regulator_desc *desc,
+				       struct regulator_config *cfg)
+{
+	struct bd71828_regulator_data *data;
+	uint32_t uv;
+	int i, ret;
+	/* On BD71828 the RUN level control reg is next to enable reg */
+	u8 en_reg = desc->enable_reg + 1;
+	const char *props[DVS_RUN_LEVELS] = { "rohm,dvs-runlevel0-voltage",
+					      "rohm,dvs-runlevel1-voltage",
+					      "rohm,dvs-runlevel2-voltage",
+					      "rohm,dvs-runlevel3-voltage" };
+	u8 en_masks[DVS_RUN_LEVELS] = { BD71828_MASK_RUN0_EN,
+					BD71828_MASK_RUN1_EN,
+					BD71828_MASK_RUN2_EN,
+					BD71828_MASK_RUN3_EN };
+
+	data = container_of(desc, struct bd71828_regulator_data, desc);
+
+	for (i = 0; i < DVS_RUN_LEVELS; i++) {
+		ret = of_property_read_u32(np, props[i], &uv);
+		if (ret) {
+			if (ret != -EINVAL)
+				return ret;
+			uv = 0;
+		}
+		if (uv) {
+			data->run_lvl[i].voltage = uv;
+			data->run_lvl[i].enabled = true;
+
+			ret = set_runlevel_voltage(cfg->regmap, desc, uv, i);
+
+			if (ret)
+				return ret;
+
+			ret = regmap_update_bits(cfg->regmap, en_reg,
+						 en_masks[i], en_masks[i]);
+		} else {
+			ret = regmap_update_bits(cfg->regmap, en_reg,
+						 en_masks[i], 0);
+		}
+		if (ret)
+			return ret;
+	}
+
+	return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
+}
+
 static int ldo6_parse_dt(struct device_node *np,
 			 const struct regulator_desc *desc,
 			 struct regulator_config *cfg)
@@ -189,6 +308,85 @@ static int ldo6_parse_dt(struct device_node *np,
 	return 0;
 }
 
+static int bd71828_dvs_gpio_set_run_level(struct bd71828_regulator_data *rd,
+					  int val)
+{
+	DECLARE_BITMAP(values, 2);
+
+	if (rd->gps->ndescs != 2)
+		return -EINVAL;
+
+	if (val < 0 || val > 3)
+		return -EINVAL;
+
+	values[0] = val;
+
+	return gpiod_set_array_value_cansleep(rd->gps->ndescs, rd->gps->desc,
+				     rd->gps->info, values);
+}
+static int bd71828_dvs_gpio_get_run_level(struct bd71828_regulator_data *rd)
+{
+	int run_level;
+	int ret;
+
+	DECLARE_BITMAP(values, 2);
+
+	values[0] = 0;
+
+	if (rd->gps->ndescs != 2)
+		return -EINVAL;
+
+	ret = gpiod_get_array_value_cansleep(rd->gps->ndescs, rd->gps->desc,
+				     rd->gps->info, values);
+	if (ret)
+		return ret;
+
+	run_level = values[0];
+
+	return run_level;
+}
+
+static int bd71828_dvs_gpio_is_enabled(struct regulator_dev *rdev)
+{
+	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	// TODO: lock GPIO state (Is this needed)
+	ret = bd71828_dvs_gpio_get_run_level(data);
+	if (ret < 0)
+		goto unlock_out;
+
+	ret = data->run_lvl[ret].enabled;
+
+unlock_out:
+	//TODO: unlock
+
+	return ret;
+}
+
+static int bd71828_dvs_gpio_get_voltage(struct regulator_dev *rdev)
+{
+	int ret;
+	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
+
+	// TODO: lock GPIO state (Is this needed)
+	ret = bd71828_dvs_gpio_get_run_level(data);
+	if (ret < 0)
+		goto unlock_out;
+
+	ret = data->run_lvl[ret].voltage;
+
+unlock_out:
+	//TODO: unlock
+
+	return ret;
+}
+
+static const struct regulator_ops dvs_buck_gpio_ops = {
+	.is_enabled = bd71828_dvs_gpio_is_enabled,
+	.get_voltage = bd71828_dvs_gpio_get_voltage,
+};
+
 static const struct regulator_ops bd71828_buck_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
@@ -773,6 +971,132 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
 	},
 };
 
+struct bd71828_gpio_cfg {
+	unsigned int gpiobucks;
+	struct gpio_descs *gps;
+};
+
+static int check_dt_for_gpio_controls(struct device *d,
+				      struct bd71828_gpio_cfg *g)
+{
+	int ret, i;
+	struct device_node *np = d->of_node;
+	const char *prop = "rohm,dvs_gpio_bucks";
+	uint32_t bucks[MAX_GPIO_DVS_BUCKS];
+
+	g->gps = devm_gpiod_get_array(d, "rohm,dvs-vsel", GPIOD_OUT_LOW);
+
+	if (IS_ERR(g->gps)) {
+		ret = PTR_ERR(g->gps);
+		if (ret == -ENOENT)
+			return 0;
+		return ret;
+	}
+
+	if (g->gps->ndescs != 2)
+		return -ENOENT;
+
+	ret = of_property_read_variable_u32_array(np, prop, bucks, 0,
+						  ARRAY_SIZE(bucks));
+
+	if (ret < 0) {
+		if (ret == -EOVERFLOW)
+			return -EINVAL;
+	}
+	for (i = 0; i < ret; i++)
+		g->gpiobucks |= 1 << bucks[i];
+
+	return 0;
+}
+
+static void set_buck_gpio_controlled(struct rohm_regmap_dev *bd71828,
+				     struct bd71828_regulator_data *rd,
+				     struct bd71828_gpio_cfg *g)
+{
+	switch (rd->desc.id) {
+	case BD71828_BUCK1:
+		rd->reg_inits = buck1_gpio_inits;
+		break;
+	case BD71828_BUCK2:
+		rd->reg_inits = buck2_gpio_inits;
+		break;
+	case BD71828_BUCK6:
+		rd->reg_inits = buck6_gpio_inits;
+		break;
+	case BD71828_BUCK7:
+		rd->reg_inits = buck7_gpio_inits;
+		break;
+	default:
+		return;
+	}
+	/*
+	 * Disallow setters. Get voltages/enable states based
+	 * on current RUN level
+	 */
+	rd->gps = g->gps;
+	rd->desc.ops = &dvs_buck_gpio_ops;
+	rd->desc.of_parse_cb = buck_set_gpio_hw_dvs_levels;
+}
+
+static ssize_t show_runlevel(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	int runlevel;
+	struct bd71828_regulator_data *rd = dev_get_drvdata(dev);
+
+	if (!rd || !rd->gps)
+		return -ENOENT;
+
+	runlevel = bd71828_dvs_gpio_get_run_level(rd);
+	if (runlevel < 0)
+		return runlevel;
+
+	return sprintf(buf, "0x%x\n", runlevel);
+}
+
+static ssize_t set_runlevel(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct bd71828_regulator_data *rd = dev_get_drvdata(dev);
+	long val;
+
+	if (kstrtol(buf, 0, &val) != 0)
+		return -EINVAL;
+
+	val = bd71828_dvs_gpio_set_run_level(rd, val);
+	if (val)
+		return val;
+
+	return count;
+}
+
+static DEVICE_ATTR(runlevel, 0664, show_runlevel, set_runlevel);
+
+static struct attribute *runlevel_attributes[] = {
+	&dev_attr_runlevel.attr,
+	NULL
+};
+
+static const struct attribute_group bd71828_attr_group = {
+	.attrs	= runlevel_attributes,
+};
+
+static int bd71828_create_sysfs(struct platform_device *pdev)
+{
+	return sysfs_create_group(&pdev->dev.kobj, &bd71828_attr_group);
+}
+
+static int bd71828_remove_sysfs(struct platform_device *pdev)
+{
+	sysfs_remove_group(&pdev->dev.kobj, &bd71828_attr_group);
+	return 0;
+}
+
+static int bd71828_remove(struct platform_device *pdev)
+{
+	return bd71828_remove_sysfs(pdev);
+}
+
 static int bd71828_probe(struct platform_device *pdev)
 {
 	struct rohm_regmap_dev *bd71828;
@@ -780,6 +1104,8 @@ static int bd71828_probe(struct platform_device *pdev)
 	struct regulator_config config = {
 		.dev = pdev->dev.parent,
 	};
+	struct bd71828_gpio_cfg gcfg = {0};
+	struct bd71828_regulator_data *rd;
 
 	bd71828 = dev_get_drvdata(pdev->dev.parent);
 	if (!bd71828) {
@@ -787,35 +1113,59 @@ static int bd71828_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	ret = check_dt_for_gpio_controls(pdev->dev.parent, &gcfg);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get DVS gpio resources\n");
+		return ret;
+	}
+
+	/*
+	 * Allocate device data to allow controlling more than one PMICs
+	 */
+	rd = devm_kmalloc_array(&pdev->dev, ARRAY_SIZE(bd71828_rdata),
+				sizeof(*rd), GFP_KERNEL);
+	if (!rd)
+		return -ENOMEM;
+
+	dev_set_drvdata(&pdev->dev, rd);
+
+	for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
+		/* Use bd71828_rdata as template */
+		rd[i] = bd71828_rdata[i];
+
+		if (gcfg.gpiobucks & (1 << i))
+			set_buck_gpio_controlled(bd71828, &rd[i], &gcfg);
+	}
+
 	config.regmap = bd71828->regmap;
 
 	for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
 		struct regulator_dev *rdev;
-		const struct bd71828_regulator_data *rd;
 
-		rd = &bd71828_rdata[i];
+		config.driver_data = &rd[i];
+
 		rdev = devm_regulator_register(&pdev->dev,
-					       &rd->desc, &config);
+					       &rd[i].desc, &config);
 		if (IS_ERR(rdev)) {
 			dev_err(&pdev->dev,
 				"failed to register %s regulator\n",
-				rd->desc.name);
+				rd[i].desc.name);
 			return PTR_ERR(rdev);
 		}
-		for (j = 0; j < rd->reg_init_amnt; j++) {
+		for (j = 0; j < rd[i].reg_init_amnt; j++) {
 			ret = regmap_update_bits(bd71828->regmap,
-						 rd->reg_inits[j].reg,
-						 rd->reg_inits[j].mask,
-						 rd->reg_inits[j].val);
+						 rd[i].reg_inits[j].reg,
+						 rd[i].reg_inits[j].mask,
+						 rd[i].reg_inits[j].val);
 			if (ret) {
 				dev_err(&pdev->dev,
 					"regulator %s init failed\n",
-					rd->desc.name);
+					rd[i].desc.name);
 				return ret;
 			}
 		}
 	}
-	return 0;
+	return bd71828_create_sysfs(pdev);
 }
 
 static struct platform_driver bd71828_regulator = {
@@ -823,6 +1173,7 @@ static struct platform_driver bd71828_regulator = {
 		.name = "bd71828-pmic"
 	},
 	.probe = bd71828_probe,
+	.remove = bd71828_remove,
 };
 
 module_platform_driver(bd71828_regulator);
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 11/15] regulator: bd71828: enhanced run-level support
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (9 preceding siblings ...)
  2019-11-01 11:43 ` [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators Matti Vaittinen
@ 2019-11-01 11:44 ` Matti Vaittinen
  2019-11-01 11:45 ` [RFC PATCH v3 12/15] regulator: bd71828: Support in-kernel APIs to change run-level Matti Vaittinen
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:44 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Support changing run-level via I2C and add in-kernel API for allowing
run time changes of run-level voltages.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - no changes

 drivers/regulator/bd71828-regulator.c | 266 ++++++++++++++++++++++----
 include/linux/mfd/rohm-bd71828.h      |   3 +
 2 files changed, 232 insertions(+), 37 deletions(-)

diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
index e82e94ecf747..d9e1381b5964 100644
--- a/drivers/regulator/bd71828-regulator.c
+++ b/drivers/regulator/bd71828-regulator.c
@@ -19,6 +19,12 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 
+/* Drivers should not do this. But we provide this custom kernel interface
+ * for users to switch the run-level. Hence we need to get the rdev from
+ * struct regulator
+ */
+#include "internal.h"
+
 #define MAX_GPIO_DVS_BUCKS 4
 #define DVS_RUN_LEVELS 4
 
@@ -39,7 +45,10 @@ struct bd71828_regulator_data {
 	const struct reg_init *reg_inits;
 	int reg_init_amnt;
 	struct run_lvl_ctrl run_lvl[DVS_RUN_LEVELS];
+	struct mutex dvs_lock;
 	struct gpio_descs *gps;
+	struct regmap *regmap;
+	bool allow_runlvl;
 };
 
 static const struct reg_init buck1_inits[] = {
@@ -225,7 +234,7 @@ static int set_runlevel_voltage(struct regmap *regmap,
 	return ret;
 }
 
-static int buck_set_gpio_hw_dvs_levels(struct device_node *np,
+static int buck_set_runlvl_hw_dvs_levels(struct device_node *np,
 				       const struct regulator_desc *desc,
 				       struct regulator_config *cfg)
 {
@@ -245,11 +254,12 @@ static int buck_set_gpio_hw_dvs_levels(struct device_node *np,
 
 	data = container_of(desc, struct bd71828_regulator_data, desc);
 
+	mutex_lock(&data->dvs_lock);
 	for (i = 0; i < DVS_RUN_LEVELS; i++) {
 		ret = of_property_read_u32(np, props[i], &uv);
 		if (ret) {
 			if (ret != -EINVAL)
-				return ret;
+				goto unlock_out;
 			uv = 0;
 		}
 		if (uv) {
@@ -259,7 +269,7 @@ static int buck_set_gpio_hw_dvs_levels(struct device_node *np,
 			ret = set_runlevel_voltage(cfg->regmap, desc, uv, i);
 
 			if (ret)
-				return ret;
+				goto unlock_out;
 
 			ret = regmap_update_bits(cfg->regmap, en_reg,
 						 en_masks[i], en_masks[i]);
@@ -268,10 +278,15 @@ static int buck_set_gpio_hw_dvs_levels(struct device_node *np,
 						 en_masks[i], 0);
 		}
 		if (ret)
-			return ret;
+			goto unlock_out;
 	}
 
-	return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
+	ret = rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
+
+unlock_out:
+	mutex_unlock(&data->dvs_lock);
+
+	return ret;
 }
 
 static int ldo6_parse_dt(struct device_node *np,
@@ -324,11 +339,40 @@ static int bd71828_dvs_gpio_set_run_level(struct bd71828_regulator_data *rd,
 	return gpiod_set_array_value_cansleep(rd->gps->ndescs, rd->gps->desc,
 				     rd->gps->info, values);
 }
+
+/* Get current run level when RUN levels are controlled using I2C */
+static int bd71828_dvs_i2c_set_run_level(struct regmap *regmap,
+					 int lvl)
+{
+	unsigned int reg;
+
+	reg = lvl << (ffs(BD71828_MASK_RUN_LVL_CTRL) - 1);
+
+	return regmap_update_bits(regmap, BD71828_REG_PS_CTRL_3,
+				  BD71828_MASK_RUN_LVL_CTRL, reg);
+}
+/* Get current run level when RUN levels are controlled using I2C */
+static int bd71828_dvs_i2c_get_run_level(struct regmap *regmap,
+					 struct bd71828_regulator_data *rd)
+{
+	int ret;
+	unsigned int val;
+
+	ret = regmap_read(regmap, BD71828_REG_PS_CTRL_3, &val);
+	if (ret)
+		return ret;
+
+	ret = (val & BD71828_MASK_RUN_LVL_CTRL);
+	ret >>= ffs(BD71828_MASK_RUN_LVL_CTRL) - 1;
+
+	return ret;
+}
+
+/* Get current RUN level when run levels are controlled by GPIO */
 static int bd71828_dvs_gpio_get_run_level(struct bd71828_regulator_data *rd)
 {
 	int run_level;
 	int ret;
-
 	DECLARE_BITMAP(values, 2);
 
 	values[0] = 0;
@@ -346,47 +390,131 @@ static int bd71828_dvs_gpio_get_run_level(struct bd71828_regulator_data *rd)
 	return run_level;
 }
 
+/*
+ * To be used when BD71828 regulator is controlled by RUN levels
+ * via I2C instead of GPIO
+ */
+static int bd71828_dvs_i2c_is_enabled(struct regulator_dev *rdev)
+{
+	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	mutex_lock(&data->dvs_lock);
+	ret = bd71828_dvs_i2c_get_run_level(rdev->regmap, data);
+	if (ret < 0)
+		goto unlock_out;
+
+	ret = data->run_lvl[ret].enabled;
+
+unlock_out:
+	mutex_unlock(&data->dvs_lock);
+
+	return ret;
+}
+
+/*
+ * To be used when BD71828 regulator is controlled by RUN levels
+ * via GPIO
+ */
 static int bd71828_dvs_gpio_is_enabled(struct regulator_dev *rdev)
 {
 	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
 	int ret;
 
-	// TODO: lock GPIO state (Is this needed)
+	mutex_lock(&data->dvs_lock);
 	ret = bd71828_dvs_gpio_get_run_level(data);
-	if (ret < 0)
+	if (ret < 0 || ret >= DVS_RUN_LEVELS)
 		goto unlock_out;
 
 	ret = data->run_lvl[ret].enabled;
 
 unlock_out:
-	//TODO: unlock
+	mutex_unlock(&data->dvs_lock);
 
 	return ret;
 }
 
+/*
+ * To be used when BD71828 regulator is controlled by RUN levels
+ * via I2C instead of GPIO
+ */
+static int bd71828_dvs_i2c_get_voltage(struct regulator_dev *rdev)
+{
+	int ret;
+	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
+
+	mutex_lock(&data->dvs_lock);
+	ret = bd71828_dvs_i2c_get_run_level(rdev->regmap, data);
+	if (ret < 0)
+		goto unlock_out;
+
+	ret = data->run_lvl[ret].voltage;
+
+unlock_out:
+	mutex_unlock(&data->dvs_lock);
+
+	return ret;
+}
+
+/*
+ * To be used when BD71828 regulator is controlled by RUN levels
+ * via GPIO
+ */
 static int bd71828_dvs_gpio_get_voltage(struct regulator_dev *rdev)
 {
 	int ret;
 	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
 
-	// TODO: lock GPIO state (Is this needed)
+	mutex_lock(&data->dvs_lock);
 	ret = bd71828_dvs_gpio_get_run_level(data);
-	if (ret < 0)
+	if (ret < 0 || DVS_RUN_LEVELS <= ret)
 		goto unlock_out;
 
 	ret = data->run_lvl[ret].voltage;
 
 unlock_out:
-	//TODO: unlock
+	mutex_unlock(&data->dvs_lock);
+
+	return ret;
+}
+
+/**
+ * bd71828_set_runlevel_voltage - change run-level voltage
+ *
+ * @regulator:  pointer to regulator for which the run-level voltage is changed
+ * @uv:		New voltage for run-level in micro volts
+ * @level:	run-level for which the voltage is to be changed
+ *
+ * Changes the run-level voltage for given regulator
+ */
+int bd71828_set_runlevel_voltage(struct regulator *regulator, unsigned int uv,
+				 unsigned int level)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+	struct bd71828_regulator_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (!data || !data->allow_runlvl)
+		return -EINVAL;
+
+	mutex_lock(&data->dvs_lock);
+	ret = set_runlevel_voltage(rdev->regmap, rdev->desc, uv, level);
+	mutex_unlock(&data->dvs_lock);
 
 	return ret;
 }
+EXPORT_SYMBOL(bd71828_set_runlevel_voltage);
 
 static const struct regulator_ops dvs_buck_gpio_ops = {
 	.is_enabled = bd71828_dvs_gpio_is_enabled,
 	.get_voltage = bd71828_dvs_gpio_get_voltage,
 };
 
+static const struct regulator_ops dvs_buck_i2c_ops = {
+	.is_enabled = bd71828_dvs_i2c_is_enabled,
+	.get_voltage = bd71828_dvs_i2c_get_voltage,
+};
+
 static const struct regulator_ops bd71828_buck_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
@@ -972,17 +1100,72 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
 };
 
 struct bd71828_gpio_cfg {
-	unsigned int gpiobucks;
+	bool use_gpio;
+	unsigned int runlvl;
 	struct gpio_descs *gps;
 };
 
+static void mark_regulator_runlvl_controlled(struct device *dev,
+					     struct device_node *np,
+					     struct bd71828_gpio_cfg *g)
+{
+	int i;
+
+	for (i = 1; i <= ARRAY_SIZE(bd71828_rdata); i++) {
+		if (!of_node_name_eq(np, bd71828_rdata[i-1].desc.of_match))
+			continue;
+		switch (i) {
+		case 1:
+		case 2:
+		case 6:
+		case 7:
+			g->runlvl |= 1 << (i - 1);
+			dev_dbg(dev, "buck %d runlevel controlled\n", i);
+			break;
+		default:
+			dev_err(dev,
+				"Only bucks 1,2,6,7 support run-level dvs\n");
+			break;
+		}
+	}
+}
+
+static int get_runcontrolled_bucks_dt(struct device *dev,
+				      struct bd71828_gpio_cfg *g)
+{
+	struct device_node *np;
+	struct device_node *nproot = dev->of_node;
+	const char *prop = "rohm,dvs-runlvl-ctrl";
+
+	g->runlvl = 0;
+
+	nproot = of_get_child_by_name(nproot, "regulators");
+	if (!nproot) {
+		dev_err(dev, "failed to find regulators node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np)
+		if (of_property_read_bool(np, prop))
+			mark_regulator_runlvl_controlled(dev, np, g);
+
+	of_node_put(nproot);
+	return 0;
+}
+
 static int check_dt_for_gpio_controls(struct device *d,
 				      struct bd71828_gpio_cfg *g)
 {
-	int ret, i;
-	struct device_node *np = d->of_node;
-	const char *prop = "rohm,dvs_gpio_bucks";
-	uint32_t bucks[MAX_GPIO_DVS_BUCKS];
+	int ret;
+
+	ret = get_runcontrolled_bucks_dt(d, g);
+	if (ret)
+		return ret;
+
+	g->use_gpio = false;
+
+	/* If the run level control is not requested by any bucks we're done */
+	if (!g->runlvl)
+		return 0;
 
 	g->gps = devm_gpiod_get_array(d, "rohm,dvs-vsel", GPIOD_OUT_LOW);
 
@@ -996,22 +1179,14 @@ static int check_dt_for_gpio_controls(struct device *d,
 	if (g->gps->ndescs != 2)
 		return -ENOENT;
 
-	ret = of_property_read_variable_u32_array(np, prop, bucks, 0,
-						  ARRAY_SIZE(bucks));
-
-	if (ret < 0) {
-		if (ret == -EOVERFLOW)
-			return -EINVAL;
-	}
-	for (i = 0; i < ret; i++)
-		g->gpiobucks |= 1 << bucks[i];
+	g->use_gpio = true;
 
 	return 0;
 }
 
-static void set_buck_gpio_controlled(struct rohm_regmap_dev *bd71828,
-				     struct bd71828_regulator_data *rd,
-				     struct bd71828_gpio_cfg *g)
+static void set_buck_runlvl_controlled(struct rohm_regmap_dev *bd71828,
+				      struct bd71828_regulator_data *rd,
+				      struct bd71828_gpio_cfg *g)
 {
 	switch (rd->desc.id) {
 	case BD71828_BUCK1:
@@ -1033,9 +1208,16 @@ static void set_buck_gpio_controlled(struct rohm_regmap_dev *bd71828,
 	 * Disallow setters. Get voltages/enable states based
 	 * on current RUN level
 	 */
-	rd->gps = g->gps;
-	rd->desc.ops = &dvs_buck_gpio_ops;
-	rd->desc.of_parse_cb = buck_set_gpio_hw_dvs_levels;
+
+	rd->allow_runlvl = true;
+
+	if (g->use_gpio) {
+		rd->gps = g->gps;
+		rd->desc.ops = &dvs_buck_gpio_ops;
+	} else {
+		rd->desc.ops = &dvs_buck_i2c_ops;
+	}
+	rd->desc.of_parse_cb = buck_set_runlvl_hw_dvs_levels;
 }
 
 static ssize_t show_runlevel(struct device *dev,
@@ -1044,10 +1226,14 @@ static ssize_t show_runlevel(struct device *dev,
 	int runlevel;
 	struct bd71828_regulator_data *rd = dev_get_drvdata(dev);
 
-	if (!rd || !rd->gps)
+	if (!rd)
 		return -ENOENT;
 
-	runlevel = bd71828_dvs_gpio_get_run_level(rd);
+	if (!rd->gps)
+		runlevel = bd71828_dvs_i2c_get_run_level(rd->regmap, rd);
+	else
+		runlevel = bd71828_dvs_gpio_get_run_level(rd);
+
 	if (runlevel < 0)
 		return runlevel;
 
@@ -1063,7 +1249,10 @@ static ssize_t set_runlevel(struct device *dev, struct device_attribute *attr,
 	if (kstrtol(buf, 0, &val) != 0)
 		return -EINVAL;
 
-	val = bd71828_dvs_gpio_set_run_level(rd, val);
+	if (rd->gps)
+		val = bd71828_dvs_gpio_set_run_level(rd, val);
+	else
+		val = bd71828_dvs_i2c_set_run_level(rd->regmap, val);
 	if (val)
 		return val;
 
@@ -1133,8 +1322,11 @@ static int bd71828_probe(struct platform_device *pdev)
 		/* Use bd71828_rdata as template */
 		rd[i] = bd71828_rdata[i];
 
-		if (gcfg.gpiobucks & (1 << i))
-			set_buck_gpio_controlled(bd71828, &rd[i], &gcfg);
+		mutex_init(&rd[i].dvs_lock);
+		if (gcfg.runlvl & (1 << i))
+			set_buck_runlvl_controlled(bd71828, &rd[i], &gcfg);
+
+		rd[i].regmap = bd71828->regmap;
 	}
 
 	config.regmap = bd71828->regmap;
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
index d013e03f742d..d2bb78427466 100644
--- a/include/linux/mfd/rohm-bd71828.h
+++ b/include/linux/mfd/rohm-bd71828.h
@@ -418,4 +418,7 @@ enum {
 #define BD71828_OUT_TYPE_OPEN_DRAIN			0x0
 #define BD71828_OUT_TYPE_CMOS				0x2
 
+int bd71828_set_runlevel_voltage(struct regulator *regulator, unsigned int uv,
+				 unsigned int level);
+
 #endif /* __LINUX_MFD_BD71828_H__ */
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 12/15] regulator: bd71828: Support in-kernel APIs to change run-level
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (10 preceding siblings ...)
  2019-11-01 11:44 ` [RFC PATCH v3 11/15] regulator: bd71828: enhanced run-level support Matti Vaittinen
@ 2019-11-01 11:45 ` Matti Vaittinen
  2019-11-01 11:49 ` [RFC PATCH v3 13/15] rtc: bd70528 add BD71828 support Matti Vaittinen
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:45 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

Add exported functions bd71828_set_runlevel and
bd71828_get_runlevel for setting and getting the system run
level.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes from v2 - no changes

 drivers/regulator/bd71828-regulator.c | 67 +++++++++++++++++++++++++++
 include/linux/mfd/rohm-bd71828.h      |  2 +
 2 files changed, 69 insertions(+)

diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
index d9e1381b5964..eaff9b1b20f9 100644
--- a/drivers/regulator/bd71828-regulator.c
+++ b/drivers/regulator/bd71828-regulator.c
@@ -505,6 +505,73 @@ int bd71828_set_runlevel_voltage(struct regulator *regulator, unsigned int uv,
 }
 EXPORT_SYMBOL(bd71828_set_runlevel_voltage);
 
+/**
+ * bd71828_set_runlevel - change system run-level.
+ *
+ * @regulator:	pointer to one of the BD71828 regulators obtained by
+ *		call to regulator_get
+ * @level:	New run-level the system should enter
+ *
+ * Changes the system to run-level which was given as argument. This
+ * operation will change state of all regulators which are set to be
+ * controlled by run-levels. Note that 'regulator' must point to a
+ * regulator which is controlled by run-levels.
+ */
+int bd71828_set_runlevel(struct regulator *regulator, unsigned int level)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+	struct bd71828_regulator_data *rd = rdev_get_drvdata(rdev);
+
+	if (!rd)
+		return -ENOENT;
+
+	if (!rd || !rd->allow_runlvl)
+		return -EINVAL;
+
+	if (rd->gps)
+		return bd71828_dvs_gpio_set_run_level(rd, level);
+
+	return bd71828_dvs_i2c_set_run_level(rd->regmap, level);
+}
+EXPORT_SYMBOL(bd71828_set_runlevel);
+
+/**
+ * bd71828_get_runlevel - get the current system run-level.
+ *
+ * @regulator:	pointer to one of the BD71828 regulators obtained by
+ *		call to regulator_get
+ * @level:	Pointer to value where current run-level is stored
+ *
+ * Returns the current system run-level. Note that 'regulator' must
+ * point to a regulator which is controlled by run-levels.
+ */
+int bd71828_get_runlevel(struct regulator *regulator, unsigned int *level)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+	struct bd71828_regulator_data *rd = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (!rd)
+		return -ENOENT;
+
+	if (!rd || !rd->allow_runlvl)
+		return -EINVAL;
+
+	if (!rd->gps)
+		ret = bd71828_dvs_i2c_get_run_level(rd->regmap, rd);
+	else
+		ret = bd71828_dvs_gpio_get_run_level(rd);
+
+	if (ret < 0)
+		return ret;
+
+	*level = (unsigned int) ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(bd71828_get_runlevel);
+
+
 static const struct regulator_ops dvs_buck_gpio_ops = {
 	.is_enabled = bd71828_dvs_gpio_is_enabled,
 	.get_voltage = bd71828_dvs_gpio_get_voltage,
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
index d2bb78427466..fc0955f0662c 100644
--- a/include/linux/mfd/rohm-bd71828.h
+++ b/include/linux/mfd/rohm-bd71828.h
@@ -420,5 +420,7 @@ enum {
 
 int bd71828_set_runlevel_voltage(struct regulator *regulator, unsigned int uv,
 				 unsigned int level);
+int bd71828_set_runlevel(struct regulator *regulator, unsigned int level);
+int bd71828_get_runlevel(struct regulator *regulator, unsigned int *level);
 
 #endif /* __LINUX_MFD_BD71828_H__ */
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 13/15] rtc: bd70528 add BD71828 support
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (11 preceding siblings ...)
  2019-11-01 11:45 ` [RFC PATCH v3 12/15] regulator: bd71828: Support in-kernel APIs to change run-level Matti Vaittinen
@ 2019-11-01 11:49 ` Matti Vaittinen
  2019-11-01 11:49 ` [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction Matti Vaittinen
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:49 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

ROHM BD71828 PMIC RTC block is from many parts similar to one
on BD70528. Support BD71828 RTC using BD70528 RTC driver and
avoid re-inventing the wheel.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>

Changes since v2 - Rebased to v5.4-rc5

---
 drivers/rtc/Kconfig              |   3 +-
 drivers/rtc/rtc-bd70528.c        | 150 ++++++++++++++++++++++++++++---
 include/linux/mfd/rohm-bd70528.h |  13 +--
 include/linux/mfd/rohm-bd71828.h |   4 +-
 include/linux/mfd/rohm-shared.h  |  27 ++++++
 5 files changed, 170 insertions(+), 27 deletions(-)
 create mode 100644 include/linux/mfd/rohm-shared.h

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 1adf9f815652..d03636ec7311 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -509,12 +509,13 @@ config RTC_DRV_M41T80_WDT
 	help
 	  If you say Y here you will get support for the
 	  watchdog timer in the ST M41T60 and M41T80 RTC chips series.
+
 config RTC_DRV_BD70528
 	tristate "ROHM BD70528 PMIC RTC"
 	depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG)
 	help
 	  If you say Y here you will get support for the RTC
-	  on ROHM BD70528 Power Management IC.
+	  block on ROHM BD70528 and BD71828 Power Management IC.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-bd70528.
diff --git a/drivers/rtc/rtc-bd70528.c b/drivers/rtc/rtc-bd70528.c
index 7744333b0f40..fbf407fe0c6d 100644
--- a/drivers/rtc/rtc-bd70528.c
+++ b/drivers/rtc/rtc-bd70528.c
@@ -6,6 +6,7 @@
 
 #include <linux/bcd.h>
 #include <linux/mfd/rohm-bd70528.h>
+#include <linux/mfd/rohm-bd71828.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -15,7 +16,7 @@
 /*
  * We read regs RTC_SEC => RTC_YEAR
  * this struct is ordered according to chip registers.
- * Keep it u8 only to avoid padding issues.
+ * Keep it u8 only (or packed) to avoid padding issues.
  */
 struct bd70528_rtc_day {
 	u8 sec;
@@ -36,6 +37,13 @@ struct bd70528_rtc_wake {
 	u8 ctrl;
 } __packed;
 
+struct bd71828_rtc_alm {
+	struct bd70528_rtc_data alm0;
+	struct bd70528_rtc_data alm1;
+	u8 alm_mask;
+	u8 alm1_mask;
+} __packed;
+
 struct bd70528_rtc_alm {
 	struct bd70528_rtc_data data;
 	u8 alm_mask;
@@ -45,6 +53,8 @@ struct bd70528_rtc_alm {
 struct bd70528_rtc {
 	struct rohm_regmap_dev *mfd;
 	struct device *dev;
+	u8 reg_time_start;
+	bool has_rtc_timers;
 };
 
 static int bd70528_set_wake(struct rohm_regmap_dev *bd70528,
@@ -152,12 +162,18 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
 static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r,
 					      int old_state)
 {
+	if (!r->has_rtc_timers)
+		return 0;
+
 	return bd70528_set_rtc_based_timers(r, old_state, NULL);
 }
 
 static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r,
 					    int *old_state)
 {
+	if (!r->has_rtc_timers)
+		return 0;
+
 	return bd70528_set_rtc_based_timers(r, 0, old_state);
 }
 
@@ -213,6 +229,36 @@ static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t)
 	t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK);
 }
 
+static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a)
+{
+	int ret;
+	struct bd71828_rtc_alm alm;
+	struct bd70528_rtc *r = dev_get_drvdata(dev);
+	struct rohm_regmap_dev *bd71828 = r->mfd;
+
+	ret = regmap_bulk_read(bd71828->regmap, BD71828_REG_RTC_ALM_START,
+			       &alm, sizeof(alm));
+	if (ret) {
+		dev_err(dev, "Failed to read alarm regs\n");
+		return ret;
+	}
+
+	tm2rtc(&a->time, &alm.alm0);
+
+	if (!a->enabled)
+		alm.alm_mask &= ~BD70528_MASK_ALM_EN;
+	else
+		alm.alm_mask |= BD70528_MASK_ALM_EN;
+
+	ret = regmap_bulk_write(bd71828->regmap, BD71828_REG_RTC_ALM_START,
+				&alm, sizeof(alm));
+	if (ret)
+		dev_err(dev, "Failed to set alarm time\n");
+
+	return ret;
+
+}
+
 static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
 {
 	struct bd70528_rtc_wake wake;
@@ -261,6 +307,30 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
 	return ret;
 }
 
+static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a)
+{
+	int ret;
+	struct bd71828_rtc_alm alm;
+	struct bd70528_rtc *r = dev_get_drvdata(dev);
+	struct rohm_regmap_dev *bd71828 = r->mfd;
+
+	ret = regmap_bulk_read(bd71828->regmap, BD71828_REG_RTC_ALM_START,
+			       &alm, sizeof(alm));
+	if (ret) {
+		dev_err(dev, "Failed to read alarm regs\n");
+		return ret;
+	}
+
+	rtc2tm(&alm.alm0, &a->time);
+	a->time.tm_mday = -1;
+	a->time.tm_mon = -1;
+	a->time.tm_year = -1;
+	a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN);
+	a->pending = 0;
+
+	return 0;
+}
+
 static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a)
 {
 	struct bd70528_rtc_alm alm;
@@ -297,7 +367,7 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
 		return ret;
 
 	tmpret = regmap_bulk_read(bd70528->regmap,
-				  BD70528_REG_RTC_START, &rtc_data,
+				  r->reg_time_start, &rtc_data,
 				  sizeof(rtc_data));
 	if (tmpret) {
 		dev_err(dev, "Failed to read RTC time registers\n");
@@ -306,7 +376,7 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
 	tm2rtc(t, &rtc_data);
 
 	tmpret = regmap_bulk_write(bd70528->regmap,
-				   BD70528_REG_RTC_START, &rtc_data,
+				   r->reg_time_start, &rtc_data,
 				   sizeof(rtc_data));
 	if (tmpret) {
 		dev_err(dev, "Failed to set RTC time\n");
@@ -341,7 +411,7 @@ static int bd70528_get_time(struct device *dev, struct rtc_time *t)
 
 	/* read the RTC date and time registers all at once */
 	ret = regmap_bulk_read(bd70528->regmap,
-			       BD70528_REG_RTC_START, &rtc_data,
+			       r->reg_time_start, &rtc_data,
 			       sizeof(rtc_data));
 	if (ret) {
 		dev_err(dev, "Failed to read RTC time (err %d)\n", ret);
@@ -378,6 +448,23 @@ static int bd70528_alm_enable(struct device *dev, unsigned int enabled)
 	return ret;
 }
 
+static int bd71828_alm_enable(struct device *dev, unsigned int enabled)
+{
+	int ret;
+	struct bd70528_rtc *r = dev_get_drvdata(dev);
+	unsigned int enableval = BD70528_MASK_ALM_EN;
+
+	if (!enabled)
+		enableval = 0;
+
+	ret = regmap_update_bits(r->mfd->regmap, BD71828_REG_RTC_ALM0_MASK,
+				 BD70528_MASK_ALM_EN, enableval);
+	if (ret)
+		dev_err(dev, "Failed to change alarm state\n");
+
+	return ret;
+}
+
 static const struct rtc_class_ops bd70528_rtc_ops = {
 	.read_time		= bd70528_get_time,
 	.set_time		= bd70528_set_time,
@@ -386,6 +473,14 @@ static const struct rtc_class_ops bd70528_rtc_ops = {
 	.alarm_irq_enable	= bd70528_alm_enable,
 };
 
+static const struct rtc_class_ops bd71828_rtc_ops = {
+	.read_time		= bd70528_get_time,
+	.set_time		= bd70528_set_time,
+	.read_alarm		= bd71828_read_alarm,
+	.set_alarm		= bd71828_set_alarm,
+	.alarm_irq_enable	= bd71828_alm_enable,
+};
+
 static irqreturn_t alm_hndlr(int irq, void *data)
 {
 	struct rtc_device *rtc = data;
@@ -397,11 +492,15 @@ static irqreturn_t alm_hndlr(int irq, void *data)
 static int bd70528_probe(struct platform_device *pdev)
 {
 	struct bd70528_rtc *bd_rtc;
+	const struct rtc_class_ops *rtc_ops;
 	struct rohm_regmap_dev *mfd;
+	const char *irq_name;
 	int ret;
 	struct rtc_device *rtc;
 	int irq;
 	unsigned int hr;
+	bool enable_main_irq = false;
+	u8 hour_reg;
 
 	mfd = dev_get_drvdata(pdev->dev.parent);
 	if (!mfd) {
@@ -415,13 +514,36 @@ static int bd70528_probe(struct platform_device *pdev)
 	bd_rtc->mfd = mfd;
 	bd_rtc->dev = &pdev->dev;
 
-	irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm");
-	if (irq < 0)
+	switch (mfd->chip_type) {
+	case ROHM_CHIP_TYPE_BD70528:
+		irq_name = "bd70528-rtc-alm";
+		bd_rtc->has_rtc_timers = true;
+		bd_rtc->reg_time_start = BD70528_REG_RTC_START;
+		hour_reg = BD70528_REG_RTC_HOUR;
+		enable_main_irq = true;
+		rtc_ops = &bd70528_rtc_ops;
+		break;
+	case ROHM_CHIP_TYPE_BD71828:
+		irq_name = "bd71828-rtc-alm-0";
+		bd_rtc->reg_time_start = BD71828_REG_RTC_START;
+		hour_reg = BD71828_REG_RTC_HOUR;
+		rtc_ops = &bd71828_rtc_ops;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unknown chip\n");
+		return -ENOENT;
+	}
+
+	irq = platform_get_irq_byname(pdev, irq_name);
+
+	if (irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq\n");
 		return irq;
+	}
 
 	platform_set_drvdata(pdev, bd_rtc);
 
-	ret = regmap_read(mfd->regmap, BD70528_REG_RTC_HOUR, &hr);
+	ret = regmap_read(mfd->regmap, hour_reg, &hr);
 
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to reag RTC clock\n");
@@ -454,7 +576,7 @@ static int bd70528_probe(struct platform_device *pdev)
 
 	rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	rtc->range_max = RTC_TIMESTAMP_END_2099;
-	rtc->ops = &bd70528_rtc_ops;
+	rtc->ops = rtc_ops;
 
 	/* Request alarm IRQ prior to registerig the RTC */
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr,
@@ -468,12 +590,14 @@ static int bd70528_probe(struct platform_device *pdev)
 	 *  leave them enabled as irq-controller should disable irqs
 	 *  from sub-registers when IRQ is disabled or freed.
 	 */
-	ret = regmap_update_bits(mfd->regmap,
+	if (enable_main_irq) {
+		ret = regmap_update_bits(mfd->regmap,
 				 BD70528_REG_INT_MAIN_MASK,
 				 BD70528_INT_RTC_MASK, 0);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
-		return ret;
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
+			return ret;
+		}
 	}
 
 	return rtc_register_device(rtc);
@@ -489,5 +613,5 @@ static struct platform_driver bd70528_rtc = {
 module_platform_driver(bd70528_rtc);
 
 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
-MODULE_DESCRIPTION("BD70528 RTC driver");
+MODULE_DESCRIPTION("ROHM BD70528 and BD71828 PMIC RTC driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/rohm-bd70528.h b/include/linux/mfd/rohm-bd70528.h
index 2ad2320d0a96..a57af878fd0c 100644
--- a/include/linux/mfd/rohm-bd70528.h
+++ b/include/linux/mfd/rohm-bd70528.h
@@ -7,6 +7,7 @@
 #include <linux/bits.h>
 #include <linux/device.h>
 #include <linux/mfd/rohm-generic.h>
+#include <linux/mfd/rohm-shared.h>
 #include <linux/regmap.h>
 
 enum {
@@ -307,17 +308,6 @@ enum {
 
 /* RTC masks to mask out reserved bits */
 
-#define BD70528_MASK_RTC_SEC		0x7f
-#define BD70528_MASK_RTC_MINUTE		0x7f
-#define BD70528_MASK_RTC_HOUR_24H	0x80
-#define BD70528_MASK_RTC_HOUR_PM	0x20
-#define BD70528_MASK_RTC_HOUR		0x1f
-#define BD70528_MASK_RTC_DAY		0x3f
-#define BD70528_MASK_RTC_WEEK		0x07
-#define BD70528_MASK_RTC_MONTH		0x1f
-#define BD70528_MASK_RTC_YEAR		0xff
-#define BD70528_MASK_RTC_COUNT_L	0x7f
-
 #define BD70528_MASK_ELAPSED_TIMER_EN	0x1
 /* Mask second, min and hour fields
  * HW would support ALM irq for over 24h
@@ -326,7 +316,6 @@ enum {
  * wake-up we limit ALM to 24H and only
  * unmask sec, min and hour
  */
-#define BD70528_MASK_ALM_EN		0x7
 #define BD70528_MASK_WAKE_EN		0x1
 
 /* WDT masks */
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
index fc0955f0662c..093662f3e867 100644
--- a/include/linux/mfd/rohm-bd71828.h
+++ b/include/linux/mfd/rohm-bd71828.h
@@ -5,6 +5,7 @@
 #define __LINUX_MFD_BD71828_H__
 
 #include <linux/mfd/rohm-generic.h>
+#include <linux/mfd/rohm-shared.h>
 
 /* Regulator IDs */
 enum {
@@ -160,6 +161,7 @@ enum {
 #define BD71828_REG_RTC_YEAR		0x52
 
 #define BD71828_REG_RTC_ALM0_SEC	0x53
+#define BD71828_REG_RTC_ALM_START	BD71828_REG_RTC_ALM0_SEC
 #define BD71828_REG_RTC_ALM0_MINUTE	0x54
 #define BD71828_REG_RTC_ALM0_HOUR	0x55
 #define BD71828_REG_RTC_ALM0_WEEK	0x56
@@ -178,6 +180,7 @@ enum {
 #define BD71828_REG_RTC_ALM1_MASK	0x62
 
 #define BD71828_REG_RTC_ALM2		0x63
+#define BD71828_REG_RTC_START		BD71828_REG_RTC_SEC
 
 /* Charger/Battey */
 #define BD71828_REG_CHG_STATE		0x65
@@ -204,7 +207,6 @@ enum {
 #define BD71828_REG_INT_MASK_TEMP	0xdd
 #define BD71828_REG_INT_MASK_RTC	0xde
 
-
 #define BD71828_REG_INT_MAIN		0xdf
 #define BD71828_REG_INT_BUCK		0xe0
 #define BD71828_REG_INT_DCIN1		0xe1
diff --git a/include/linux/mfd/rohm-shared.h b/include/linux/mfd/rohm-shared.h
new file mode 100644
index 000000000000..f16fc3b5000e
--- /dev/null
+++ b/include/linux/mfd/rohm-shared.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2018 ROHM Semiconductors */
+
+
+#ifndef __LINUX_MFD_ROHM_SHARED_H__
+#define __LINUX_MFD_ROHM_SHARED_H__
+
+/*
+ * RTC definitions shared between
+ *
+ * BD70528
+ * and BD71828
+ */
+
+
+#define BD70528_MASK_RTC_SEC		0x7f
+#define BD70528_MASK_RTC_MINUTE	0x7f
+#define BD70528_MASK_RTC_HOUR_24H	0x80
+#define BD70528_MASK_RTC_HOUR_PM	0x20
+#define BD70528_MASK_RTC_HOUR		0x3f
+#define BD70528_MASK_RTC_DAY		0x3f
+#define BD70528_MASK_RTC_WEEK		0x07
+#define BD70528_MASK_RTC_MONTH		0x1f
+#define BD70528_MASK_RTC_YEAR		0xff
+#define BD70528_MASK_ALM_EN		0x7
+
+#endif /* __LINUX_MFD_ROHM_SHARED_H__ */
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (12 preceding siblings ...)
  2019-11-01 11:49 ` [RFC PATCH v3 13/15] rtc: bd70528 add BD71828 support Matti Vaittinen
@ 2019-11-01 11:49 ` Matti Vaittinen
  2019-11-03 22:30   ` Linus Walleij
  2019-11-01 11:51 ` [RFC PATCH v3 15/15] gpio: bd71828: Initial support for ROHM BD71828 PMIC GPIOs Matti Vaittinen
  2019-11-01 11:53 ` [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Vaittinen, Matti
  15 siblings, 1 reply; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:49 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

At least for me it is difficult to remember the meaning of GPIO
direction values. Define GPIO_IN and GPIO_OUT so that occasional
GPIO contributors would not need to always check the meaning of
hard coded values 1 and 0.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes since v2 - new patch

 include/linux/gpio/driver.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 5dd9c982e2cb..e83d3f519507 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -22,6 +22,9 @@ enum gpio_lookup_flags;
 
 struct gpio_chip;
 
+#define GPIO_IN		1
+#define GPIO_OUT	0
+
 /**
  * struct gpio_irq_chip - GPIO interrupt controller
  */
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* [RFC PATCH v3 15/15] gpio: bd71828: Initial support for ROHM BD71828 PMIC GPIOs
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (13 preceding siblings ...)
  2019-11-01 11:49 ` [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction Matti Vaittinen
@ 2019-11-01 11:51 ` Matti Vaittinen
  2019-11-01 11:53 ` [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Vaittinen, Matti
  15 siblings, 0 replies; 38+ messages in thread
From: Matti Vaittinen @ 2019-11-01 11:51 UTC (permalink / raw)
  To: matti.vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Dan Murphy, Rob Herring,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

ROHM BD71828 PMIC contains 4 pins which can be configured by OTP
to be used for general purposes. First 3 can be used as outputs
and 4.th pin can be used as input. Allow them to be controlled
via GPIO framework.

The driver assumes all of the pins are configured as GPIOs and
trusts that the reserved pins in other OTP configurations are
excluded from control using "gpio-reserved-ranges" device tree
property (or left untouched by GPIO users).

Typical use for 4.th pin (input) is to use it as HALL sensor
input so that this pin state is toggled when HALL sensor detects
LID position change (from close to open or open to close). PMIC
HW implements some extra logic which allows PMIC to power-up the
system when this pin is toggled. Please see the data sheet for
details of GPIO options which can be selected by OTP settings.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---

Changes since v2 - fixed typo from commit msg, used generic GPIO_IN
and GPIO_OUT instead of defining driver local ones.

 drivers/gpio/Kconfig        |  12 +++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-bd71828.c | 149 ++++++++++++++++++++++++++++++++++++
 3 files changed, 162 insertions(+)
 create mode 100644 drivers/gpio/gpio-bd71828.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 38e096e6925f..b4089096f7f2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -994,6 +994,18 @@ config GPIO_BD70528
 	  This driver can also be built as a module. If so, the module
 	  will be called gpio-bd70528.
 
+config GPIO_BD71828
+	tristate "ROHM BD71828 GPIO support"
+	depends on MFD_ROHM_BD71828
+	help
+	  Support for GPIOs on ROHM BD71828 PMIC. There are three GPIOs
+	  available on the ROHM PMIC in total. The GPIOs are limited to
+	  outputs only and pins must be configured to GPIO outputs by
+	  OTP. Enable this only if you want to use these pins as outputs.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called gpio-bd71828.
+
 config GPIO_BD9571MWV
 	tristate "ROHM BD9571 GPIO support"
 	depends on MFD_BD9571MWV
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d2fd19c15bae..034b38996579 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_GPIO_ASPEED)		+= gpio-aspeed.o
 obj-$(CONFIG_GPIO_ATH79)		+= gpio-ath79.o
 obj-$(CONFIG_GPIO_BCM_KONA)		+= gpio-bcm-kona.o
 obj-$(CONFIG_GPIO_BD70528)		+= gpio-bd70528.o
+obj-$(CONFIG_GPIO_BD71828)		+= gpio-bd71828.o
 obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
diff --git a/drivers/gpio/gpio-bd71828.c b/drivers/gpio/gpio-bd71828.c
new file mode 100644
index 000000000000..a8ab6085c2e8
--- /dev/null
+++ b/drivers/gpio/gpio-bd71828.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+
+#include <linux/gpio/driver.h>
+#include <linux/mfd/rohm-bd71828.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off))
+#define HALL_GPIO_OFFSET 3
+
+struct bd71828_gpio {
+	struct rohm_regmap_dev chip;
+	struct gpio_chip gpio;
+};
+
+static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			     int value)
+{
+	int ret;
+	struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
+	u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO;
+
+	/*
+	 * The HALL input pin can only be used as input. If this is the pin
+	 * we are dealing with - then we are done
+	 */
+	if (offset == HALL_GPIO_OFFSET)
+		return;
+
+	ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
+				 BD71828_GPIO_OUT_MASK, val);
+	if (ret)
+		dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value);
+}
+
+static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	int ret;
+	unsigned int val;
+	struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
+
+	if (offset == HALL_GPIO_OFFSET)
+		ret = regmap_read(bdgpio->chip.regmap, BD71828_REG_IO_STAT,
+				  &val);
+	else
+		ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
+				  &val);
+	if (!ret)
+		ret = (val & BD71828_GPIO_OUT_MASK);
+
+	return ret;
+}
+
+static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+				   unsigned long config)
+{
+	struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
+
+	if (offset == HALL_GPIO_OFFSET)
+		return -ENOTSUPP;
+
+	switch (pinconf_to_config_param(config)) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		return regmap_update_bits(bdgpio->chip.regmap,
+					  GPIO_OUT_REG(offset),
+					  BD71828_GPIO_DRIVE_MASK,
+					  BD71828_GPIO_OPEN_DRAIN);
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		return regmap_update_bits(bdgpio->chip.regmap,
+					  GPIO_OUT_REG(offset),
+					  BD71828_GPIO_DRIVE_MASK,
+					  BD71828_GPIO_PUSH_PULL);
+	default:
+		break;
+	}
+	return -ENOTSUPP;
+}
+
+static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	/*
+	 * Pin usage is selected by OTP data. We can't read it runtime. Hence
+	 * we trust that if the pin is not excluded by "gpio-reserved-ranges"
+	 * the OTP configuration is set to OUT. (Other pins but HALL input pin
+	 * on BD71828 can't really be used for general purpose input - input
+	 * states are used for specific cases like regulator control or
+	 * PMIC_ON_REQ.
+	 */
+	if (offset == HALL_GPIO_OFFSET)
+		return GPIO_IN;
+
+	return GPIO_OUT;
+}
+
+static int bd71828_probe(struct platform_device *pdev)
+{
+	struct bd71828_gpio *bdgpio;
+	struct rohm_regmap_dev *bd71828;
+
+	bd71828 = dev_get_drvdata(pdev->dev.parent);
+	if (!bd71828) {
+		dev_err(&pdev->dev, "No MFD driver data\n");
+		return -EINVAL;
+	}
+
+	bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio),
+			      GFP_KERNEL);
+	if (!bdgpio)
+		return -ENOMEM;
+
+	bdgpio->chip.dev = &pdev->dev;
+	bdgpio->gpio.parent = pdev->dev.parent;
+	bdgpio->gpio.label = "bd71828-gpio";
+	bdgpio->gpio.owner = THIS_MODULE;
+	bdgpio->gpio.get_direction = bd71828_get_direction;
+	bdgpio->gpio.set_config = bd71828_gpio_set_config;
+	bdgpio->gpio.can_sleep = true;
+	bdgpio->gpio.get = bd71828_gpio_get;
+	bdgpio->gpio.set = bd71828_gpio_set;
+	bdgpio->gpio.base = -1;
+
+	/*
+	 * See if we need some implementation to mark some PINs as
+	 * not controllable based on DT info or if core can handle
+	 * "gpio-reserved-ranges" and exclude them from control
+	 */
+	bdgpio->gpio.ngpio = 4;
+	bdgpio->gpio.of_node = pdev->dev.parent->of_node;
+	bdgpio->chip.regmap = bd71828->regmap;
+
+	return devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio,
+				     bdgpio);
+}
+
+static struct platform_driver bd71828_gpio = {
+	.driver = {
+		.name = "bd71828-gpio"
+	},
+	.probe = bd71828_probe,
+};
+
+module_platform_driver(bd71828_gpio);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71828 voltage regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bd71828-gpio");
-- 
2.21.0


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 

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

* Re: [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC
  2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
                   ` (14 preceding siblings ...)
  2019-11-01 11:51 ` [RFC PATCH v3 15/15] gpio: bd71828: Initial support for ROHM BD71828 PMIC GPIOs Matti Vaittinen
@ 2019-11-01 11:53 ` Vaittinen, Matti
  15 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-01 11:53 UTC (permalink / raw)
  To: mazziesaccount
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree,
	jacek.anaszewski, a.zummo, linus.walleij, mark.rutland, robh+dt,
	bgolaszewski, linux-clk, sboyd, lee.jones, broonie, pavel


On Fri, 2019-11-01 at 13:28 +0200, Matti Vaittinen wrote:
> Patch series introducing support for ROHM BD71828 PMIC
> 
...
> 
> Patch 14:
>         Add generic GPIO direction defines
> Patch 15:
>         Allow control of GP(I)O pins on BD71828 via GPIO subsystem
> Patch 16:
>         Support toggling the LEDs

Sorry Folks - this is a left over. I dropped the LED driverfrom the series for now.

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

* Re: [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators
  2019-11-01 11:43 ` [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators Matti Vaittinen
@ 2019-11-03 22:27   ` Linus Walleij
  2019-11-04  7:05     ` Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Linus Walleij @ 2019-11-03 22:27 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: Matti Vaittinen, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Rob Herring, Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Bartosz Golaszewski,
	Alessandro Zummo, Alexandre Belloni, Linux LED Subsystem,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-clk, open list:GPIO SUBSYSTEM, linux-rtc

On Fri, Nov 1, 2019 at 12:43 PM Matti Vaittinen
<matti.vaittinen@fi.rohmeurope.com> wrote:

> Bucks 1,2,6 and 7 on ROHM BD71828 can be either controlled as
> individual regulartors - or they can be grouped to a group of
> regulators that are controlled by 'run levels'. This can be
> done via I2C. Each regulator can be assigned a voltage and
> enable/disable status for each run-level. These statuses are
> also changeable via I2C.
>
> Run-levels can then be changed either by I2C or GPIO. This
> control mechanism is selected by data in one time programmable
> area (during production) and can't be changed later.
>
> Allow regulators to be controlled via run-levels and allow
> getting/setting the current run-level also via GPIO.
>
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>

I like the way you use the gpio API so FWIW:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

I do not understand the regulator parts of the patch.

Yours,
Linus Walleij

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

* Re: [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction
  2019-11-01 11:49 ` [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction Matti Vaittinen
@ 2019-11-03 22:30   ` Linus Walleij
  2019-11-04  6:57     ` Vaittinen, Matti
  2019-11-04 15:48     ` Vaittinen, Matti
  0 siblings, 2 replies; 38+ messages in thread
From: Linus Walleij @ 2019-11-03 22:30 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: Matti Vaittinen, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Rob Herring, Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Bartosz Golaszewski,
	Alessandro Zummo, Alexandre Belloni, Linux LED Subsystem,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-clk, open list:GPIO SUBSYSTEM, linux-rtc

Hi Matti!

Good initiative (and I will see a ton of janitorial patches as a
result of this...)

On Fri, Nov 1, 2019 at 12:50 PM Matti Vaittinen
<matti.vaittinen@fi.rohmeurope.com> wrote:

> At least for me it is difficult to remember the meaning of GPIO
> direction values. Define GPIO_IN and GPIO_OUT so that occasional
> GPIO contributors would not need to always check the meaning of
> hard coded values 1 and 0.
>
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
(...)
> +#define GPIO_IN                1
> +#define GPIO_OUT       0

Please spell it out or people will be confused:

GPIO_LINE_DIRECTION_IN
GPIO_LINE_DIRECTION_OUT

Yours,
Linus Walleij

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

* Re: [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction
  2019-11-03 22:30   ` Linus Walleij
@ 2019-11-04  6:57     ` Vaittinen, Matti
  2019-11-04 15:48     ` Vaittinen, Matti
  1 sibling, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-04  6:57 UTC (permalink / raw)
  To: linus.walleij
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, jacek.anaszewski, mark.rutland, robh+dt, bgolaszewski,
	linux-clk, sboyd, lee.jones, broonie, pavel

Hello Linus,

On Sun, 2019-11-03 at 23:30 +0100, Linus Walleij wrote:
> Hi Matti!
> 
> Good initiative (and I will see a ton of janitorial patches as a
> result of this...)

Yep. I think I might pull this change out of the RFC and send it
separately. I can also do some conversions for existing drivers - but I
won't probably be able to do all of the drivers. I see no way of doing
any search and replace scripting here - this conversion is going to be
manual work :/

> 
> On Fri, Nov 1, 2019 at 12:50 PM Matti Vaittinen
> <matti.vaittinen@fi.rohmeurope.com> wrote:
> 
> > At least for me it is difficult to remember the meaning of GPIO
> > direction values. Define GPIO_IN and GPIO_OUT so that occasional
> > GPIO contributors would not need to always check the meaning of
> > hard coded values 1 and 0.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> (...)
> > +#define GPIO_IN                1
> > +#define GPIO_OUT       0
> 
> Please spell it out or people will be confused:
> 
> GPIO_LINE_DIRECTION_IN
> GPIO_LINE_DIRECTION_OUT

Right. Besides the 0Day test suite did already spot a few redefinition
problems when some drivers do define GPIO_IN and/or GPIO_OUT... So I'll
change the defines to what you suggest here.

Br,
	Matti Vaittinen

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

* Re: [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators
  2019-11-03 22:27   ` Linus Walleij
@ 2019-11-04  7:05     ` Vaittinen, Matti
  2019-11-05 13:24       ` Linus Walleij
  0 siblings, 1 reply; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-04  7:05 UTC (permalink / raw)
  To: linus.walleij
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, jacek.anaszewski, mark.rutland, robh+dt, bgolaszewski,
	linux-clk, sboyd, lee.jones, broonie, pavel

Hello Linus,

On Sun, 2019-11-03 at 23:27 +0100, Linus Walleij wrote:
> On Fri, Nov 1, 2019 at 12:43 PM Matti Vaittinen
> <matti.vaittinen@fi.rohmeurope.com> wrote:
> 
> > Bucks 1,2,6 and 7 on ROHM BD71828 can be either controlled as
> > individual regulartors - or they can be grouped to a group of
> > regulators that are controlled by 'run levels'. This can be
> > done via I2C. Each regulator can be assigned a voltage and
> > enable/disable status for each run-level. These statuses are
> > also changeable via I2C.
> > 
> > Run-levels can then be changed either by I2C or GPIO. This
> > control mechanism is selected by data in one time programmable
> > area (during production) and can't be changed later.
> > 
> > Allow regulators to be controlled via run-levels and allow
> > getting/setting the current run-level also via GPIO.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> 
> I like the way you use the gpio API so FWIW:
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Thanks. And I like the GPIO set multiple - that's required in order to
do some of the run-level changes without intermediate states. (Eg. both
DVS GPIOs need to be toggled via single register write).

> I do not understand the regulator parts of the patch.

I'm sorry. The patch is not clearest one what comes to the regulator
stuff. I can try splitting it to smaller and more logical changes if
you, Mark or other interested people hope to get it splitted. Or
perhaps it would be simplest to review if it was all in one patch? 

Rationale for splitting it in first place was that I hoped the basic
support (first two regulator patches) to be acceptable without huge
changes - whereas the follow up patches are more like question that how
the heck should I implement this :] I've not hit similar 'change bunch
of regulator states at one go' drivers/hardware before.

Br,
	Matti Vaittinen

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

* Re: [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction
  2019-11-03 22:30   ` Linus Walleij
  2019-11-04  6:57     ` Vaittinen, Matti
@ 2019-11-04 15:48     ` Vaittinen, Matti
  2019-11-05 15:05       ` Linus Walleij
  1 sibling, 1 reply; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-04 15:48 UTC (permalink / raw)
  To: linus.walleij
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, jacek.anaszewski, mark.rutland, robh+dt, bgolaszewski,
	linux-clk, sboyd, lee.jones, broonie, pavel

Hello All,

On Sun, 2019-11-03 at 23:30 +0100, Linus Walleij wrote:
> Hi Matti!
> 
> Good initiative (and I will see a ton of janitorial patches as a
> result of this...)

I have somewhere near 62 patches waiting to be sent =) They're pretty
small but I'd appreciate thorough review as they're mostly untested...
Do you mind receiving them all in one go? Or do you think I should send
the series in smaller chuncks?

> On Fri, Nov 1, 2019 at 12:50 PM Matti Vaittinen
> <matti.vaittinen@fi.rohmeurope.com> wrote:
> 
> > At least for me it is difficult to remember the meaning of GPIO
> > direction values. Define GPIO_IN and GPIO_OUT so that occasional
> > GPIO contributors would not need to always check the meaning of
> > hard coded values 1 and 0.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> (...)
> > +#define GPIO_IN                1
> > +#define GPIO_OUT       0
> 
> Please spell it out or people will be confused:
> 
> GPIO_LINE_DIRECTION_IN
> GPIO_LINE_DIRECTION_OUT
> 
> Yours,
> Linus Walleij


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

* Re: [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators
  2019-11-04  7:05     ` Vaittinen, Matti
@ 2019-11-05 13:24       ` Linus Walleij
  2019-11-05 14:07         ` Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Linus Walleij @ 2019-11-05 13:24 UTC (permalink / raw)
  To: Vaittinen, Matti
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, jacek.anaszewski, mark.rutland, robh+dt, bgolaszewski,
	linux-clk, sboyd, lee.jones, broonie, pavel

On Mon, Nov 4, 2019 at 8:05 AM Vaittinen, Matti
<Matti.Vaittinen@fi.rohmeurope.com> wrote:
> On Sun, 2019-11-03 at 23:27 +0100, Linus Walleij wrote:

> > I do not understand the regulator parts of the patch.
>
> I'm sorry. The patch is not clearest one what comes to the regulator
> stuff. I can try splitting it to smaller and more logical changes if
> you, Mark or other interested people hope to get it splitted. Or
> perhaps it would be simplest to review if it was all in one patch?

As long as the regulator experts are happy with the format,
stay with that. I am just a drive-by coder when it comes to regulators.

Yours,
Linus Walleij

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

* Re: [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators
  2019-11-05 13:24       ` Linus Walleij
@ 2019-11-05 14:07         ` Vaittinen, Matti
  0 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-05 14:07 UTC (permalink / raw)
  To: linus.walleij
  Cc: dmurphy, linux-leds, linux-rtc, linux-gpio, linux-kernel,
	alexandre.belloni, mazziesaccount, mturquette, devicetree,
	jacek.anaszewski, a.zummo, lgirdwood, mark.rutland, robh+dt,
	bgolaszewski, linux-clk, sboyd, lee.jones, broonie, pavel


On Tue, 2019-11-05 at 14:24 +0100, Linus Walleij wrote:
> On Mon, Nov 4, 2019 at 8:05 AM Vaittinen, Matti
> <Matti.Vaittinen@fi.rohmeurope.com> wrote:
> > On Sun, 2019-11-03 at 23:27 +0100, Linus Walleij wrote:
> > > I do not understand the regulator parts of the patch.
> > 
> > I'm sorry. The patch is not clearest one what comes to the
> > regulator
> > stuff. I can try splitting it to smaller and more logical changes
> > if
> > you, Mark or other interested people hope to get it splitted. Or
> > perhaps it would be simplest to review if it was all in one patch?
> 
> As long as the regulator experts are happy with the format,
> stay with that. I am just a drive-by coder when it comes to
> regulators.

"Drive-by coder" - I do definitely like how that sounds :] Maybe I can
borrow that. But even the "drive-by" reviewing is hard. And I guess it
should be made as easy as it can...

Br,
	Matti



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

* Re: [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction
  2019-11-04 15:48     ` Vaittinen, Matti
@ 2019-11-05 15:05       ` Linus Walleij
  2019-11-06  6:51         ` Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Linus Walleij @ 2019-11-05 15:05 UTC (permalink / raw)
  To: Vaittinen, Matti
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, jacek.anaszewski, mark.rutland, robh+dt, bgolaszewski,
	linux-clk, sboyd, lee.jones, broonie, pavel

On Mon, Nov 4, 2019 at 4:48 PM Vaittinen, Matti
<Matti.Vaittinen@fi.rohmeurope.com> wrote:

> > Good initiative (and I will see a ton of janitorial patches as a
> > result of this...)
>
> I have somewhere near 62 patches waiting to be sent =) They're pretty
> small but I'd appreciate thorough review as they're mostly untested...
> Do you mind receiving them all in one go? Or do you think I should send
> the series in smaller chuncks?

I would be fine with one patch introducing the defines and then
one big patch switching everybody and their dog over to using
these definitions.

I usually keep to a patch being "one technical step" and it is
clearly (IMO) one step to introduce the defines and one step
to make use of it in all legacy drivers.

It's late in the kernel cycle but this particular part (the defines
and switching over old driver to use it) I'd be happy
to merge for v5.5.

Yours,
Linus Walleij

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

* Re: [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver
  2019-11-01 11:32 ` [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver Matti Vaittinen
@ 2019-11-05 19:14   ` Dan Murphy
  2019-11-05 20:59     ` Rob Herring
  2019-11-06 13:05     ` Vaittinen, Matti
  2019-11-05 20:57   ` Rob Herring
  1 sibling, 2 replies; 38+ messages in thread
From: Dan Murphy @ 2019-11-05 19:14 UTC (permalink / raw)
  To: Matti Vaittinen, mazziesaccount
  Cc: Jacek Anaszewski, Pavel Machek, Rob Herring, Mark Rutland,
	Lee Jones, Liam Girdwood, Mark Brown, Michael Turquette,
	Stephen Boyd, Linus Walleij, Bartosz Golaszewski,
	Alessandro Zummo, Alexandre Belloni, linux-leds, devicetree,
	linux-kernel, linux-clk, linux-gpio, linux-rtc

Matti

On 11/1/19 6:32 AM, Matti Vaittinen wrote:
> Document ROHM BD71828 PMIC LED driver device tree bindings.
>
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>
> Changes from v2 - new patch
>
>   .../bindings/leds/rohm,leds-bd71828.yaml      | 46 +++++++++++++++++++
>   1 file changed, 46 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
>
> diff --git a/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> new file mode 100644
> index 000000000000..d8aeac9911ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/rohm,leds-bd71828.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ROHM BD71828 Power Management Integrated Circuit LED driver
> +
> +maintainers:
> +  - Jacek Anaszewski <jacek.anaszewski@gmail.com>
> +  - Pavel Machek <pavel@ucw.cz>
> +  - Dan Murphy <dmurphy@ti.com>
> +  - Rob Herring <robh+dt@kernel.org>
> +  - Mark Rutland <mark.rutland@arm.com>
I believe you are the maintainer of this driver not the maintainers
> +
> +description: |
> +  This module is part of the ROHM BD71828 MFD device. For more details
> +  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
> +
> +  The LED controller is represented as a sub-node of the PMIC node on the device
> +  tree.
> +
> +  The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.
> +
> +properties:
> +  compatible:
> +    const: rohm,bd71828-led
> +
> +patternProperties:
> +  "^led-[1-2]$":
> +    type: object
> +    description:
> +      Properties for a single LED. Nodes must be named as led-1 and led-2.

Why is this required?  Can't we use the reg as the number and then we 
can use standard node labels

like led@<reg value>.  Then we can check in the code to make sure that 
the output is not out of bounds.

> +    properties:
> +      #$ref: "common.yaml#"
> +      function:
> +        description:
> +          Purpose of LED as defined in dt-bindings/leds/common.h
> +        $ref: "/schemas/types.yaml#/definitions/string"
> +      color:
> +        description:
> +          LED colour as defined in dt-bindings/leds/common.h

s/colour/color

But again I believe it is indicated above that the LEDs are either going 
to be green or amber.  Unless they can be any color.

Are there plans to make sure that the color is either green or amber in 
the code?  I don't see a patch for the code in this series

> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +
> +required:
> +  - compatible

Is there an example of the node and properties?

Dan


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

* Re: [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings
  2019-11-01 11:31 ` [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings Matti Vaittinen
@ 2019-11-05 20:43   ` Rob Herring
  2019-11-06 12:55     ` SPAM (R/EU IT) // " Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Rob Herring @ 2019-11-05 20:43 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: mazziesaccount, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

On Fri, Nov 01, 2019 at 01:31:03PM +0200, Matti Vaittinen wrote:
> ROHM BD71828 Power management IC integrates 7 buck converters, 7 LDOs,
> a real-time clock (RTC), 3 GPO/regulator control pins, HALL input
> and a 32.768 kHz clock gate.
> 
> Document the dt bindings drivers are using.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
> 
> Changes from v2 - my first encounter with yaml :/
> 
>  .../bindings/mfd/rohm,bd71828-pmic.yaml       | 249 ++++++++++++++++++
>  1 file changed, 249 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
> new file mode 100644
> index 000000000000..b2a88f6e1bb7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
> @@ -0,0 +1,249 @@
> +# SPDX-License-Identifier: GPL-2.0

# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

for new bindings.

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/rohm,bd71828-pmic.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ROHM BD71828 Power Management Integrated Circuit bindings
> +
> +maintainers:
> +  - Lee Jones <lee.jones@linaro.org>
> +  - Rob Herring <robh@kernel.org>
> +  - Mark Rutland <mark.rutland@arm.com>

Don't list me or Mark here. I maintain everything...

> +
> +description: |
> +  BD71828GW is a single-chip power management IC for battery-powered portable
> +  devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA
> +  single-cell linear charger. Also included is a Coulomb counter, a real-time
> +  clock (RTC), and a 32.768 kHz clock gate.
> +
> +  The BD71828 RUN state is divided into 4 configurable run-levels named RUN0,
> +  RUN1, RUN2 and RUN3. Bucks 1, 2, 6 and 7 can be either controlled individually
> +  via I2C, or some/all of them can be bound to run-levels and controlled as a
> +  group. If bucks are controlled individually these run-levels are ignored. See
> +  ../regulator/rohm,bd71828-regulator.yaml for how to define regulator voltages
> +  for run-levels. Run-levels can be changed by I2C or GPIO depending on PMIC's
> +  OTP configuration.
> +
> +properties:
> +  compatible:
> +    const: rohm,bd71828

blank line here please

> +  reg:
> +    description:
> +      I2C slave address.
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +    description:
> +      The interrupt line the device is connected to.
> +
> +  gpio-controller: true
> +      # Indicate BD71828 acts as a GPIO controller.
> +
> +  "#gpio-cells":
> +    const: 2
> +    description: |
> +      The first cell is the pin number and the second cell is used to specify
> +      flags. See ../gpio/gpio.txt for more information.
> +
> +  clocks:
> +    description:
> +      The parent clock connected to PMIC.

How many?

maxItems: 1

> +
> +  "#clock-cells":
> +    const: 0
> +
> +  rohm,charger-sense-resistor:
> +    $ref: "/schemas/types.yaml#/definitions/uint32"
> +    description: |
> +      BD71827 and BD71828 have SAR ADC for measuring charging currents.
> +      External sense resistor (RSENSE in data sheet) should be used. If some
> +      other but 30MOhm resistor is used the resistance value should be given
> +      here in Ohms.

Standard units need a unit suffix as defined in property-units.txt. So 
'-ohms' in this case. With that, you can drop $ref because we already 
define the type.

Is there a valid range of values? If so, use minimum/maximum.

> +
> +  regulators:
> +    $ref: ../regulator/rohm,bd71828-regulator.yaml

Not bisectable. These files have to come in this patch or before.

> +    description:
> +      List of child nodes that specify the regulators.
> +
> +  leds:
> +    $ref: ../leds/rohm,leds-bd71828.yaml

Filename should match the compatible if possible.

> +
> +  clock-output-names:
> +    description:
> +      Should contain name for output clock.

Need to document what the name is. Though, with only 1 clock, not that 
useful.

> +
> +  rohm,dvs-vsel-gpios:
> +    description: |
> +      GPIOs used to control PMIC run-levels. Should describe two GPIOs.
> +      (See run-level control in data-sheet). If this property is omitted but
> +      some bucks are marked to be controlled by run-levels - then OTP option
> +      allowing run-level control via I2C is assumed.

How many? Needs 'maxItems'.

> +
> +  gpio-reserved-ranges:
> +    description: |
> +      Usage of BD71828 GPIO pins can be changed via OTP. This property can be
> +      used to mark the pins which should not be configured for GPIO. Please see
> +      the ../gpio/gpio.txt for more information.
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - "#clock-cells"
> +  - regulators
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/leds/common.h>
> +    i2c {

'make dt_binding_check' reports an error building this, but I'm not 
seeing where it is:

Error: Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.example.dts:155.36-37 syntax error
FATAL ERROR: Unable to parse input tree

> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        pmic: pmic@4b {
> +            compatible = "rohm,bd71828";
> +            reg = <0x4b>;
> +
> +            interrupt-parent = <&gpio1>;
> +            interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
> +
> +            clocks = <&osc 0>;
> +            #clock-cells = <0>;
> +            clock-output-names = "bd71828-32k-out";
> +
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            gpio-reserved-ranges = <0 1 2 1>;
> +
> +            rohm,dvs-vsel-gpios = <&gpio1 12 0>, <&gpio1 13 0>;
> +            rohm,charger-sense-resistor = <10000000>;
> +
> +            regulators {
> +                buck1: BUCK1 {
> +                    regulator-name = "buck1";
> +                    regulator-min-microvolt = <500000>;
> +                    regulator-max-microvolt = <2000000>;
> +                    regulator-ramp-delay = <2500>;
> +                    rohm,dvs-runlvl-ctrl;
> +                    rohm,dvs-runlevel0-voltage = <500000>;
> +                    rohm,dvs-runlevel1-voltage = <506250>;
> +                    rohm,dvs-runlevel2-voltage = <512500>;
> +                    rohm,dvs-runlevel3-voltage = <518750>;
> +                    regulator-boot-on;
> +                };
> +                buck2: BUCK2 {
> +                    regulator-name = "buck2";
> +                    regulator-min-microvolt = <500000>;
> +                    regulator-max-microvolt = <2000000>;
> +                    regulator-ramp-delay = <2500>;
> +                    rohm,dvs-runlvl-ctrl;
> +                    rohm,dvs-runlevel0-voltage = <500000>;
> +                    rohm,dvs-runlevel1-voltage = <506250>;
> +                    rohm,dvs-runlevel2-voltage = <512500>;
> +                    rohm,dvs-runlevel3-voltage = <518750>;
> +                    regulator-boot-on;
> +                };
> +                buck3: BUCK3 {
> +                    regulator-name = "buck3";
> +                    regulator-min-microvolt = <1200000>;
> +                    regulator-max-microvolt = <2000000>;
> +                    regulator-boot-on;
> +                };
> +                buck4: BUCK4 {
> +                    regulator-name = "buck4";
> +                    regulator-min-microvolt = <1000000>;
> +                    regulator-max-microvolt = <1800000>;
> +                    regulator-boot-on;
> +                };
> +                buck5: BUCK5 {
> +                    regulator-name = "buck5";
> +                    regulator-min-microvolt = <2500000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +                buck6: BUCK6 {
> +                    regulator-name = "buck6";
> +                    regulator-min-microvolt = <500000>;
> +                    regulator-max-microvolt = <2000000>;
> +                    regulator-ramp-delay = <2500>;
> +                    rohm,dvs-runlvl-ctrl;
> +                    rohm,dvs-runlevel0-voltage = <500000>;
> +                    rohm,dvs-runlevel1-voltage = <506250>;
> +                    rohm,dvs-runlevel2-voltage = <512500>;
> +                    rohm,dvs-runlevel3-voltage = <518750>;
> +                    regulator-boot-on;
> +                };
> +                buck7: BUCK7 {
> +                    regulator-name = "buck7";
> +                    regulator-min-microvolt = <500000>;
> +                    regulator-max-microvolt = <2000000>;
> +                    regulator-ramp-delay = <2500>;
> +                    rohm,dvs-runlvl-ctrl;
> +                    rohm,dvs-runlevel0-voltage = <500000>;
> +                    rohm,dvs-runlevel1-voltage = <506250>;
> +                    rohm,dvs-runlevel2-voltage = <512500>;
> +                    rohm,dvs-runlevel3-voltage = <518750>;
> +                    regulator-boot-on;
> +                };
> +                ldo1: LDO1 {
> +                    regulator-name = "ldo1";
> +                    regulator-min-microvolt = <800000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +                ldo2: LDO2 {
> +                    regulator-name = "ldo2";
> +                    regulator-min-microvolt = <800000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +                ldo3: LDO3 {
> +                    regulator-name = "ldo3";
> +                    regulator-min-microvolt = <800000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +                ldo4: LDO4 {
> +                    regulator-name = "ldo4";
> +                    regulator-min-microvolt = <800000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +                ldo5: LDO5 {
> +                    regulator-name = "ldo5";
> +                    regulator-min-microvolt = <800000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +                ldo6: LDO6 {
> +                    regulator-name = "ldo6";
> +                    regulator-min-microvolt = <1800000>;
> +                    regulator-max-microvolt = <1800000>;
> +                    regulator-boot-on;
> +                };
> +                ldo7_reg: LDO7 {
> +                    regulator-name = "ldo7";
> +                    regulator-min-microvolt = <800000>;
> +                    regulator-max-microvolt = <3300000>;
> +                    regulator-boot-on;
> +                };
> +            };
> +
> +            leds {
> +                compatible = "rohm,bd71828-led";
> +
> +                led-1 {
> +                    function = LED_FUNCTION_INDICATOR;
> +                    color = <LED_COLOR_ID_GREEN>;
> +                };
> +                led-2 {
> +                    function = LED_FUNCTION_CHARGING;
> +                    color = <LED_COLOR_ID_AMBER>;
> +                };
> +            };
> +        };
> +    };
> -- 
> 2.21.0
> 
> 
> -- 
> Matti Vaittinen, Linux device drivers
> ROHM Semiconductors, Finland SWDC
> Kiviharjunlenkki 1E
> 90220 OULU
> FINLAND
> 
> ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
> Simon says - in Latin please.
> ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
> Thanks to Simon Glass for the translation =] 

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

* Re: [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings
  2019-11-01 11:31 ` [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings Matti Vaittinen
@ 2019-11-05 20:52   ` Rob Herring
  2019-11-07  6:50     ` SPAM (R/EU IT) // " Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Rob Herring @ 2019-11-05 20:52 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: mazziesaccount, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

On Fri, Nov 01, 2019 at 01:31:46PM +0200, Matti Vaittinen wrote:
> Document ROHM BD71828 PMIC regulator device tree bindings.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
> 
> Changes from v2 - my first encounter with yaml :/
> 
>  .../regulator/rohm,bd71828-regulator.yaml     | 123 ++++++++++++++++++
>  1 file changed, 123 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
> 
> diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
> new file mode 100644
> index 000000000000..60715d8b92df
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
> @@ -0,0 +1,123 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/regulator/rohm,bd71828-regulator.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ROHM BD71828 Power Management Integrated Circuit regulators
> +
> +maintainers:
> +  - Liam Girdwood <lgirdwood@gmail.com>
> +  - Mark Brown <broonie@kernel.org>
> +  - Rob Herring <robh+dt@kernel.org>
> +  - Mark Rutland <mark.rutland@arm.com>
> +
> +description: |
> +  This module is part of the ROHM BD71828 MFD device. For more details
> +  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
> +
> +  The regulator controller is represented as a sub-node of the PMIC node
> +  on the device tree.
> +
> +  Regulator nodes should be named to BUCK_<number> and LDO_<number>.
> +  The valid names for BD71828 regulator nodes are
> +  BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7
> +  LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
> +
> +patternProperties:
> +  "^LDO[1-7]$":
> +    type: object
> +    allOf:
> +      - $ref: regulator.yaml#
> +    description:
> +      Properties for single LDO regulator.
> +
> +    properties:
> +      #Is there a nice way to check the name is same as node name but lower case

Well, lowercase nodenames are preferred... But still, no, there's not.

And I think you could just drop this and the nodename is used instead.

> +      regulator-name:
> +        description:
> +          should be "ldo1", ..., "ldo7"

You can at least do:

pattern: "^ldo[1-7]$"


> +
> +  "^BUCK[1-7]$":
> +    type: object
> +    allOf:
> +      - $ref: regulator.yaml#
> +    description:
> +      Properties for single BUCK regulator.
> +
> +    properties:
> +      #Is there a nice way to check the name is same as node name but lower case
> +      regulator-name:
> +        description:
> +          should be "buck1", ..., "buck7"
> +
> +      rohm,dvs-run-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          PMIC default "RUN" state voltage in uV. See below table for
> +          bucks which support this.

Use standard unit-suffixes on all these (-microvolt). And then drop the 
$ref.

Any constraints on the range?

> +
> +      rohm,dvs-idle-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          PMIC default "IDLE" state voltage in uV. See below table for
> +          bucks which support this.
> +
> +      rohm,dvs-suspend-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          PMIC default "SUSPEND" state voltage in uV. See below table for
> +          bucks which support this.
> +
> +      rohm,dvs-lpsr-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          PMIC default "LPSR" state voltage in uV. See below table for
> +          bucks which support this.
> +
> +#Supported default DVS states:
> +#buck		| run		| idle		| suspend	| lpsr
> +#----------------------------------------------------------------------------
> +#1, 2, 6, and 7	| supported	| supported	| 	supported (*)
> +#----------------------------------------------------------------------------
> +#3, 4, and 5	| 			supported (**)
> +#----------------------------------------------------------------------------
> +#(*)  LPSR and SUSPEND states use same voltage but both states have own enable /
> +#     disable settings. Voltage 0 can be specified for a state to make regulator
> +#     disabled on that state.
> +#(**) All states use same voltage but have own enable / disable settings.
> +#     Voltage 0 can be specified for a state to make regulator disabled on that
> +#     state.
> +
> +      rohm,dvs-runlvl-ctrl:
> +        description: |
> +          buck control is done based on run-level. Regulator is not
> +          individually controllable. See ../mfd/rohm,bd71828-pmic.yaml for
> +          how to specify run-level control mechanism. Only bucks 1, 2, 6
> +          and 7 support this.
> +        type: boolean
> +
> +      rohm,dvs-runlevel0-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          voltage for run-level 0. Microvolts.
> +
> +      rohm,dvs-runlevel1-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          voltage for run-level 1. Microvolts.
> +
> +      rohm,dvs-runlevel2-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          voltage for run-level 2. Microvolts.
> +
> +      rohm,dvs-runlevel3-voltage:
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +        description:
> +          voltage for run-level 3. Microvolts.

Perhaps an array of 4 values for runlevel?

> +
> +    required:
> +      - regulator-name
> +  additionalProperties: false
> +additionalProperties: false
> -- 
> 2.21.0
> 
> 
> -- 
> Matti Vaittinen, Linux device drivers
> ROHM Semiconductors, Finland SWDC
> Kiviharjunlenkki 1E
> 90220 OULU
> FINLAND
> 
> ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
> Simon says - in Latin please.
> ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
> Thanks to Simon Glass for the translation =] 

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

* Re: [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver
  2019-11-01 11:32 ` [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver Matti Vaittinen
  2019-11-05 19:14   ` Dan Murphy
@ 2019-11-05 20:57   ` Rob Herring
  1 sibling, 0 replies; 38+ messages in thread
From: Rob Herring @ 2019-11-05 20:57 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: mazziesaccount, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

On Fri, Nov 01, 2019 at 01:32:33PM +0200, Matti Vaittinen wrote:
> Document ROHM BD71828 PMIC LED driver device tree bindings.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
> 
> Changes from v2 - new patch
> 
>  .../bindings/leds/rohm,leds-bd71828.yaml      | 46 +++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> 
> diff --git a/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> new file mode 100644
> index 000000000000..d8aeac9911ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/rohm,leds-bd71828.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ROHM BD71828 Power Management Integrated Circuit LED driver
> +
> +maintainers:
> +  - Jacek Anaszewski <jacek.anaszewski@gmail.com>
> +  - Pavel Machek <pavel@ucw.cz>
> +  - Dan Murphy <dmurphy@ti.com>
> +  - Rob Herring <robh+dt@kernel.org>
> +  - Mark Rutland <mark.rutland@arm.com>
> +
> +description: |
> +  This module is part of the ROHM BD71828 MFD device. For more details
> +  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
> +
> +  The LED controller is represented as a sub-node of the PMIC node on the device
> +  tree.
> +
> +  The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.
> +
> +properties:
> +  compatible:
> +    const: rohm,bd71828-led
> +
> +patternProperties:
> +  "^led-[1-2]$":
> +    type: object
> +    description:
> +      Properties for a single LED. Nodes must be named as led-1 and led-2.
> +    properties:
> +      #$ref: "common.yaml#"
> +      function:
> +        description:
> +          Purpose of LED as defined in dt-bindings/leds/common.h
> +        $ref: "/schemas/types.yaml#/definitions/string"
> +      color:
> +        description:
> +          LED colour as defined in dt-bindings/leds/common.h
> +        $ref: "/schemas/types.yaml#/definitions/uint32"

You can assume that we will have a common schema for these. So the only 
thing needed is whether you use the properties ("true" is enough for 
that), any additional constraints (not likely here), and whether 
required or not.

> +
> +required:
> +  - compatible
> -- 
> 2.21.0
> 
> 
> -- 
> Matti Vaittinen, Linux device drivers
> ROHM Semiconductors, Finland SWDC
> Kiviharjunlenkki 1E
> 90220 OULU
> FINLAND
> 
> ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
> Simon says - in Latin please.
> ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
> Thanks to Simon Glass for the translation =] 

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

* Re: [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver
  2019-11-05 19:14   ` Dan Murphy
@ 2019-11-05 20:59     ` Rob Herring
  2019-11-06 13:05     ` Vaittinen, Matti
  1 sibling, 0 replies; 38+ messages in thread
From: Rob Herring @ 2019-11-05 20:59 UTC (permalink / raw)
  To: Dan Murphy
  Cc: Matti Vaittinen, mazziesaccount, Jacek Anaszewski, Pavel Machek,
	Mark Rutland, Lee Jones, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

On Tue, Nov 05, 2019 at 01:14:33PM -0600, Dan Murphy wrote:
> Matti
> 
> On 11/1/19 6:32 AM, Matti Vaittinen wrote:
> > Document ROHM BD71828 PMIC LED driver device tree bindings.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> > 
> > Changes from v2 - new patch
> > 
> >   .../bindings/leds/rohm,leds-bd71828.yaml      | 46 +++++++++++++++++++
> >   1 file changed, 46 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> > new file mode 100644
> > index 000000000000..d8aeac9911ef
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> > @@ -0,0 +1,46 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/leds/rohm,leds-bd71828.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ROHM BD71828 Power Management Integrated Circuit LED driver
> > +
> > +maintainers:
> > +  - Jacek Anaszewski <jacek.anaszewski@gmail.com>
> > +  - Pavel Machek <pavel@ucw.cz>
> > +  - Dan Murphy <dmurphy@ti.com>
> > +  - Rob Herring <robh+dt@kernel.org>
> > +  - Mark Rutland <mark.rutland@arm.com>
> I believe you are the maintainer of this driver not the maintainers

Right, should have been clearer in my other response. Put 
owner/maintainer of the device binding, not subsystem.

> > +
> > +description: |
> > +  This module is part of the ROHM BD71828 MFD device. For more details
> > +  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
> > +
> > +  The LED controller is represented as a sub-node of the PMIC node on the device
> > +  tree.
> > +
> > +  The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.
> > +
> > +properties:
> > +  compatible:
> > +    const: rohm,bd71828-led
> > +
> > +patternProperties:
> > +  "^led-[1-2]$":
> > +    type: object
> > +    description:
> > +      Properties for a single LED. Nodes must be named as led-1 and led-2.
> 
> Why is this required?  Can't we use the reg as the number and then we can
> use standard node labels
> 
> like led@<reg value>.  Then we can check in the code to make sure that the
> output is not out of bounds.
> 
> > +    properties:
> > +      #$ref: "common.yaml#"
> > +      function:
> > +        description:
> > +          Purpose of LED as defined in dt-bindings/leds/common.h
> > +        $ref: "/schemas/types.yaml#/definitions/string"
> > +      color:
> > +        description:
> > +          LED colour as defined in dt-bindings/leds/common.h
> 
> s/colour/color
> 
> But again I believe it is indicated above that the LEDs are either going to
> be green or amber.  Unless they can be any color.
> 
> Are there plans to make sure that the color is either green or amber in the
> code?  I don't see a patch for the code in this series
> 
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +
> > +required:
> > +  - compatible
> 
> Is there an example of the node and properties?

For MFDs, I prefer a complete example in the MFD binding doc. We need it 
complete to validate the example.

Rob

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

* Re: [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction
  2019-11-05 15:05       ` Linus Walleij
@ 2019-11-06  6:51         ` Vaittinen, Matti
  0 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-06  6:51 UTC (permalink / raw)
  To: linus.walleij
  Cc: dmurphy, linux-leds, linux-rtc, linux-gpio, linux-kernel,
	alexandre.belloni, mazziesaccount, mturquette, devicetree,
	jacek.anaszewski, a.zummo, lgirdwood, mark.rutland, robh+dt,
	bgolaszewski, linux-clk, sboyd, lee.jones, broonie, pavel

Hello Linus,

On Tue, 2019-11-05 at 16:05 +0100, Linus Walleij wrote:
> On Mon, Nov 4, 2019 at 4:48 PM Vaittinen, Matti
> <Matti.Vaittinen@fi.rohmeurope.com> wrote:
> 
> > > Good initiative (and I will see a ton of janitorial patches as a
> > > result of this...)
> > 
> > I have somewhere near 62 patches waiting to be sent =) They're
> > pretty
> > small but I'd appreciate thorough review as they're mostly
> > untested...
> > Do you mind receiving them all in one go? Or do you think I should
> > send
> > the series in smaller chuncks?
> 
> I would be fine with one patch introducing the defines and then
> one big patch switching everybody and their dog over to using
> these definitions.
> 
> I usually keep to a patch being "one technical step" and it is
> clearly (IMO) one step to introduce the defines and one step
> to make use of it in all legacy drivers.
> 
> It's late in the kernel cycle but this particular part (the defines
> and switching over old driver to use it) I'd be happy
> to merge for v5.5.

I'll prepare one patch for defines and one large patch for driver
changes on top of GPIO tree then. I'll leave out the last one 62/62 -
it can be applied later if it is considered a good idea - I'd
appreciate if you / Bartosz had the time to check it though. 

> 
> Yours,
> Linus Walleij


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

* Re: SPAM (R/EU IT) // Re: [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings
  2019-11-05 20:43   ` Rob Herring
@ 2019-11-06 12:55     ` " Vaittinen, Matti
  0 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-06 12:55 UTC (permalink / raw)
  To: robh
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mazziesaccount, lgirdwood, devicetree,
	jacek.anaszewski, a.zummo, linus.walleij, mturquette,
	mark.rutland, bgolaszewski, linux-clk, lee.jones, pavel, broonie,
	sboyd

Hello Again Rob,

And thanks again.

On Tue, 2019-11-05 at 14:43 -0600, Rob Herring wrote:
> On Fri, Nov 01, 2019 at 01:31:03PM +0200, Matti Vaittinen wrote:
> > ROHM BD71828 Power management IC integrates 7 buck converters, 7
> > LDOs,
> > a real-time clock (RTC), 3 GPO/regulator control pins, HALL input
> > and a 32.768 kHz clock gate.
> > 
> > Document the dt bindings drivers are using.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> > 
> > Changes from v2 - my first encounter with yaml :/
> > 
> >  .../bindings/mfd/rohm,bd71828-pmic.yaml       | 249
> > ++++++++++++++++++
> >  1 file changed, 249 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71828-
> > pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71828-
> > pmic.yaml
> > new file mode 100644
> > index 000000000000..b2a88f6e1bb7
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
> > @@ -0,0 +1,249 @@
> > +# SPDX-License-Identifier: GPL-2.0
> 
> # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> 
> for new bindings.

Linus Walleij already notified me about this. I just wondered why this
is not reflected in:

LICENSES/preferred/GPL-2.0

which seems to state:
Valid-License-Identifier: GPL-2.0
Valid-License-Identifier: GPL-2.0-only
Valid-License-Identifier: GPL-2.0+
Valid-License-Identifier: GPL-2.0-or-later
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
Usage-Guide:
  To use this license in source code, put one of the following SPDX
  tag/value pairs into a comment according to the placement
  guidelines in the licensing rules documentation.
  For 'GNU General Public License (GPL) version 2 only' use:
    SPDX-License-Identifier: GPL-2.0
  or
    SPDX-License-Identifier: GPL-2.0-only


https://elixir.bootlin.com/linux/v5.4-rc5/source/LICENSES/preferred/GPL-2.0

I'll change the SPDX for new files for next version.


> 
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/mfd/rohm,bd71828-pmic.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ROHM BD71828 Power Management Integrated Circuit bindings
> > +
> > +maintainers:
> > +  - Lee Jones <lee.jones@linaro.org>
> > +  - Rob Herring <robh@kernel.org>
> > +  - Mark Rutland <mark.rutland@arm.com>
> 
> Don't list me or Mark here. I maintain everything...

Ok. So I'll add myself then. Although I am by no means an expert what
comes to binding schemas. I know the device and driver though.

> > +
> > +  clock-output-names:
> > +    description:
> > +      Should contain name for output clock.
> 
> Need to document what the name is. Though, with only 1 clock, not
> that 
> useful.

Hmmm. I thought this would depend on rest of the system's DT. Why
should it be same on each board? (I can drop this out though).

> > +  - |
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/leds/common.h>
> > +    i2c {
> 
> 'make dt_binding_check' reports an error building this, but I'm not 
> seeing where it is:
> 
> Error: Documentation/devicetree/bindings/mfd/rohm,bd71828-
> pmic.example.dts:155.36-37 syntax error
> FATAL ERROR: Unable to parse input tree

I guess it is the LED function definition. Those function/colour
bindings were only added in 5.4-rc1. Do you have them defined in your
build environment at /include/dt-bindings/leds/common.h?

Rest of the comments are clear to me :)

Br,
	Matti Vaittinen

> -- 
> > Matti Vaittinen, Linux device drivers
> > ROHM Semiconductors, Finland SWDC
> > Kiviharjunlenkki 1E
> > 90220 OULU
> > FINLAND
> > 
> > ~~~ "I don't think so," said Rene Descartes. Just then he vanished
> > ~~~
> > Simon says - in Latin please.
> > ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
> > Thanks to Simon Glass for the translation =] 


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

* Re: [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver
  2019-11-05 19:14   ` Dan Murphy
  2019-11-05 20:59     ` Rob Herring
@ 2019-11-06 13:05     ` Vaittinen, Matti
  1 sibling, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-06 13:05 UTC (permalink / raw)
  To: mazziesaccount, dmurphy
  Cc: linux-leds, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree,
	jacek.anaszewski, a.zummo, linus.walleij, mark.rutland, robh+dt,
	bgolaszewski, linux-clk, sboyd, lee.jones, broonie, pavel

Hello Dan,

Thanks for the check once again!

On Tue, 2019-11-05 at 13:14 -0600, Dan Murphy wrote:
> Matti
> 
> On 11/1/19 6:32 AM, Matti Vaittinen wrote:
> > Document ROHM BD71828 PMIC LED driver device tree bindings.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> > 
> > Changes from v2 - new patch
> > 
> >   .../bindings/leds/rohm,leds-bd71828.yaml      | 46
> > +++++++++++++++++++
> >   1 file changed, 46 insertions(+)
> >   create mode 100644
> > Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/leds/rohm,leds-
> > bd71828.yaml b/Documentation/devicetree/bindings/leds/rohm,leds-
> > bd71828.yaml
> > new file mode 100644
> > index 000000000000..d8aeac9911ef
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/leds/rohm,leds-bd71828.yaml
> > @@ -0,0 +1,46 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/leds/rohm,leds-bd71828.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ROHM BD71828 Power Management Integrated Circuit LED driver
> > +
> > +maintainers:
> > +  - Jacek Anaszewski <jacek.anaszewski@gmail.com>
> > +  - Pavel Machek <pavel@ucw.cz>
> > +  - Dan Murphy <dmurphy@ti.com>
> > +  - Rob Herring <robh+dt@kernel.org>
> > +  - Mark Rutland <mark.rutland@arm.com>
> I believe you are the maintainer of this driver not the maintainers

Right. Thanks for pointing that out.

> > +
> > +description: |
> > +  This module is part of the ROHM BD71828 MFD device. For more
> > details
> > +  see Documentation/devicetree/bindings/mfd/rohm,bd71828-
> > pmic.yaml.
> > +
> > +  The LED controller is represented as a sub-node of the PMIC node
> > on the device
> > +  tree.
> > +
> > +  The device has two LED outputs referred as GRNLED and AMBLED in
> > data-sheet.
> > +
> > +properties:
> > +  compatible:
> > +    const: rohm,bd71828-led
> > +
> > +patternProperties:
> > +  "^led-[1-2]$":
> > +    type: object
> > +    description:
> > +      Properties for a single LED. Nodes must be named as led-1
> > and led-2.
> 
> Why is this required?  Can't we use the reg as the number and then
> we 
> can use standard node labels

This was related to my idea of using the node-names as unique keys.
Please see:
https://lore.kernel.org/lkml/cover.1572351774.git.matti.vaittinen@fi.rohmeurope.com/

What would you expect the reg = <>; to describe from HW?

> like led@<reg value>.  Then we can check in the code to make sure
> that 
> the output is not out of bounds.
> 
> > +    properties:
> > +      #$ref: "common.yaml#"
> > +      function:
> > +        description:
> > +          Purpose of LED as defined in dt-bindings/leds/common.h
> > +        $ref: "/schemas/types.yaml#/definitions/string"
> > +      color:
> > +        description:
> > +          LED colour as defined in dt-bindings/leds/common.h
> 
> s/colour/color

That depends on your location :)

> But again I believe it is indicated above that the LEDs are either
> going 
> to be green or amber.  Unless they can be any color.

This was my original reason for omitting the DT for BD71828 LEDs
altogether. LEDs are expected to be green and amber - but it is true
that PMIC can not ensure there will be no other colours.

> Are there plans to make sure that the color is either green or amber
> in 
> the code?  I don't see a patch for the code in this series

Yes. As I wrote in cover-letter, the LED driver is pending until I see
how the RFC for adding LED node finding and some more common property
parsing to LED core is received by others. (Although I do understand if
you didn't read the cover-letter. It's quite a bunch of text and
reading it over and over again is no fun).

> 
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +
> > +required:
> > +  - compatible
> 
> Is there an example of the node and properties?

Yes, in MFD doc.

Br,
	Matti Vaittinen

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

* Re: SPAM (R/EU IT) // Re: [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings
  2019-11-05 20:52   ` Rob Herring
@ 2019-11-07  6:50     ` " Vaittinen, Matti
  0 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-07  6:50 UTC (permalink / raw)
  To: robh
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mazziesaccount, lgirdwood, devicetree,
	jacek.anaszewski, a.zummo, linus.walleij, mturquette,
	mark.rutland, bgolaszewski, linux-clk, lee.jones, pavel, broonie,
	sboyd

Hello Rob,

On Tue, 2019-11-05 at 14:52 -0600, Rob Herring wrote:
> On Fri, Nov 01, 2019 at 01:31:46PM +0200, Matti Vaittinen wrote:
> > Document ROHM BD71828 PMIC regulator device tree bindings.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> > 
> > Changes from v2 - my first encounter with yaml :/
> > 
> >  .../regulator/rohm,bd71828-regulator.yaml     | 123
> > ++++++++++++++++++
> >  1 file changed, 123 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/regulator/rohm,bd71828-
> > regulator.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/regulator/rohm,bd71828-
> > regulator.yaml
> > b/Documentation/devicetree/bindings/regulator/rohm,bd71828-
> > regulator.yaml
> > new file mode 100644
> > index 000000000000..60715d8b92df
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/regulator/rohm,bd71828-
> > regulator.yaml
> > @@ -0,0 +1,123 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: 
> > http://devicetree.org/schemas/regulator/rohm,bd71828-regulator.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ROHM BD71828 Power Management Integrated Circuit regulators
> > +
> > +maintainers:
> > +  - Liam Girdwood <lgirdwood@gmail.com>
> > +  - Mark Brown <broonie@kernel.org>
> > +  - Rob Herring <robh+dt@kernel.org>
> > +  - Mark Rutland <mark.rutland@arm.com>
> > +
> > +description: |
> > +  This module is part of the ROHM BD71828 MFD device. For more
> > details
> > +  see Documentation/devicetree/bindings/mfd/rohm,bd71828-
> > pmic.yaml.
> > +
> > +  The regulator controller is represented as a sub-node of the
> > PMIC node
> > +  on the device tree.
> > +
> > +  Regulator nodes should be named to BUCK_<number> and
> > LDO_<number>.
> > +  The valid names for BD71828 regulator nodes are
> > +  BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7
> > +  LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
> > +
> > +patternProperties:
> > +  "^LDO[1-7]$":
> > +    type: object
> > +    allOf:
> > +      - $ref: regulator.yaml#
> > +    description:
> > +      Properties for single LDO regulator.
> > +
> > +    properties:
> > +      #Is there a nice way to check the name is same as node name
> > but lower case
> 
> Well, lowercase nodenames are preferred... But still, no, there's
> not.

I'd like to follow the convention of using upper-case node names like
ROHM BD71837, BD71847 and BD70528 PMICs do.

> And I think you could just drop this and the nodename is used
> instead.

If I used lower-case, then yes. But if I follow what other BD-PMICs
did, then I guess I should keep this. (lowercase names for consumers
feel more correct to me). Someone once told me that naming is hard :|

> > +      regulator-name:
> > +        description:
> > +          should be "ldo1", ..., "ldo7"
> 
> You can at least do:
> 
> pattern: "^ldo[1-7]$"

Yep. Thanks :)

> > +
> > +  "^BUCK[1-7]$":
> > +    type: object
> > +    allOf:
> > +      - $ref: regulator.yaml#
> > +    description:
> > +      Properties for single BUCK regulator.
> > +
> > +    properties:
> > +      #Is there a nice way to check the name is same as node name
> > but lower case
> > +      regulator-name:
> > +        description:
> > +          should be "buck1", ..., "buck7"
> > +
> > +      rohm,dvs-run-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          PMIC default "RUN" state voltage in uV. See below table
> > for
> > +          bucks which support this.
> 
> Use standard unit-suffixes on all these (-microvolt). And then drop
> the 
> $ref.

Hmm.. The rohm,dvs-run-voltage, rohm,dvs-idle-voltage and rohm,dvs-
suspend-voltage are already defined in rohm,bd71837-regulator.txt. I am
a bit hesitant what comes to changing the existing properties as it
will probably cause some problems out there... On the other hand, I
don't like defining two different "rohm" DT entries for same thing. How
important you think having the correct suffix here is? Should the old
one(s) be still silently supported by driver(s) while changing the docs
also for bd71837 and bd71847 to contain the new ones? Although - if the
idea is to convert also docs for bd71837/47 to yaml - that would mean
at least breaking the build for someone who uses old DTS. I just don't
know what would be the right thing to do. (naming is ...).

> 
> Any constraints on the range?

Sure. Thanks. I'll add constrains.

> 
> > +
> > +      rohm,dvs-idle-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          PMIC default "IDLE" state voltage in uV. See below table
> > for
> > +          bucks which support this.
> > +
> > +      rohm,dvs-suspend-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          PMIC default "SUSPEND" state voltage in uV. See below
> > table for
> > +          bucks which support this.
> > +
> > +      rohm,dvs-lpsr-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          PMIC default "LPSR" state voltage in uV. See below table
> > for
> > +          bucks which support this.
> > +
> > +#Supported default DVS states:
> > +#buck		| run		| idle		| suspend	
> > | lpsr
> > +#-----------------------------------------------------------------
> > -----------
> > +#1, 2, 6, and 7	| supported	| supported	| 	supported
> > (*)
> > +#-----------------------------------------------------------------
> > -----------
> > +#3, 4, and 5	| 			supported (**)
> > +#-----------------------------------------------------------------
> > -----------
> > +#(*)  LPSR and SUSPEND states use same voltage but both states
> > have own enable /
> > +#     disable settings. Voltage 0 can be specified for a state to
> > make regulator
> > +#     disabled on that state.
> > +#(**) All states use same voltage but have own enable / disable
> > settings.
> > +#     Voltage 0 can be specified for a state to make regulator
> > disabled on that
> > +#     state.
> > +
> > +      rohm,dvs-runlvl-ctrl:
> > +        description: |
> > +          buck control is done based on run-level. Regulator is
> > not
> > +          individually controllable. See ../mfd/rohm,bd71828-
> > pmic.yaml for
> > +          how to specify run-level control mechanism. Only bucks
> > 1, 2, 6
> > +          and 7 support this.
> > +        type: boolean
> > +
> > +      rohm,dvs-runlevel0-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          voltage for run-level 0. Microvolts.
> > +
> > +      rohm,dvs-runlevel1-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          voltage for run-level 1. Microvolts.
> > +
> > +      rohm,dvs-runlevel2-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          voltage for run-level 2. Microvolts.
> > +
> > +      rohm,dvs-runlevel3-voltage:
> > +        $ref: "/schemas/types.yaml#/definitions/uint32"
> > +        description:
> > +          voltage for run-level 3. Microvolts.
> 
> Perhaps an array of 4 values for runlevel?

I'm not sure. From HW perspective giving all values is not required if
HW defaults are to be used. I'd like to keep giving any of these
optional. OTOH, I see the possible issue of having more than 4 run-
levels in the future. (I see possible issue, I do not see any product
from ROHM that would contain those - but I don't see too far to the
future from my low seat ;]) Having 10 run-level properties would look
horrible.

> > +
> > +    required:
> > +      - regulator-name
> > +  additionalProperties: false
> > +additionalProperties: false
> > -- 
> > 2.21.0
> > 
> > 
> > -- 
> > Matti Vaittinen, Linux device drivers
> > ROHM Semiconductors, Finland SWDC
> > Kiviharjunlenkki 1E
> > 90220 OULU
> > FINLAND
> > 
> > ~~~ "I don't think so," said Rene Descartes. Just then he vanished
> > ~~~
> > Simon says - in Latin please.
> > ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
> > Thanks to Simon Glass for the translation =] 


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

* Re: [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core
  2019-11-01 11:29 ` [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core Matti Vaittinen
@ 2019-11-11 10:57   ` Lee Jones
  2019-11-11 11:20     ` Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Lee Jones @ 2019-11-11 10:57 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: mazziesaccount, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Rob Herring, Mark Rutland, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

On Fri, 01 Nov 2019, Matti Vaittinen wrote:

> BD71828GW is a single-chip power management IC for battery-powered portable
> devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA
> single-cell linear charger. Also included is a Coulomb counter, a real-time
> clock (RTC), 3 GPO/regulator control pins, HALL input and a 32.768 kHz
> clock gate.
> 
> Add MFD core driver providing interrupt controller facilities and i2c
> access to sub device drivers.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
> 
> No changes compared to v2
> 
>  drivers/mfd/Kconfig              |  15 ++
>  drivers/mfd/Makefile             |   2 +-
>  drivers/mfd/rohm-bd71828.c       | 322 +++++++++++++++++++++++
>  include/linux/mfd/rohm-bd71828.h | 425 +++++++++++++++++++++++++++++++
>  include/linux/mfd/rohm-generic.h |   1 +
>  5 files changed, 764 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mfd/rohm-bd71828.c
>  create mode 100644 include/linux/mfd/rohm-bd71828.h

/me wonders why this is still an RFC after 3 revisions?

[...]

> +static struct mfd_cell bd71828_mfd_cells[] = {
> +	{ .name = "bd71828-pmic", },
> +	{ .name = "bd71828-gpio", },
> +	{ .name = "bd71828-led", },
> +	/*
> +	 * We use BD71837 driver to drive the clock block. Only differences to
> +	 * BD70528 clock gate are the register address and mask.
> +	 */
> +	{ .name = "bd718xx-clk", },
> +	{
> +		.name = "bd71827-power",

Why isn't this on one line, like the others above?

> +	}, {
> +		.name = "bd70528-rtc",
> +		.resources = rtc_irqs,
> +		.num_resources = ARRAY_SIZE(rtc_irqs),
> +	},
> +};

[...]

> +unsigned int bit0_offsets[] = {11};		/* RTC IRQ register */
> +unsigned int bit1_offsets[] = {10};		/* TEMP IRQ register */
> +unsigned int bit2_offsets[] = {6, 7, 8, 9};	/* BAT MON IRQ registers */
> +unsigned int bit3_offsets[] = {5};		/* BAT IRQ register */
> +unsigned int bit4_offsets[] = {4};		/* CHG IRQ register */
> +unsigned int bit5_offsets[] = {3};		/* VSYS IRQ register */
> +unsigned int bit6_offsets[] = {1, 2};		/* DCIN IRQ registers */

Something actually wrong with the tabbing here, or is this a
Git/patch/mailer anomaly?

[...]

> +static int bd71828_i2c_probe(struct i2c_client *i2c,
> +			     const struct i2c_device_id *id)
> +{
> +	struct rohm_regmap_dev *chip;
> +	struct regmap_irq_chip_data *irq_data;
> +	int ret;
> +
> +	if (!i2c->irq) {
> +		dev_err(&i2c->dev, "No IRQ configured\n");
> +		return -EINVAL;
> +	}
> +
> +	chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
> +	if (!chip)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(&i2c->dev, chip);
> +
> +	chip->chip_type = ROHM_CHIP_TYPE_BD71828;
> +	chip->regmap = devm_regmap_init_i2c(i2c, &bd71828_regmap);
> +	if (IS_ERR(chip->regmap)) {
> +		dev_err(&i2c->dev, "Failed to initialize Regmap\n");
> +		return PTR_ERR(chip->regmap);
> +	}
> +
> +	ret = devm_regmap_add_irq_chip(&i2c->dev, chip->regmap,
> +				       i2c->irq, IRQF_ONESHOT, 0,
> +				       &bd71828_irq_chip, &irq_data);
> +	if (ret) {
> +		dev_err(&i2c->dev, "Failed to add IRQ chip\n");
> +		return ret;
> +	}

Nit: '\n' here.

> +	dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
> +		bd71828_irq_chip.num_irqs);
> +
> +	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
> +				   bd71828_mfd_cells,
> +				   ARRAY_SIZE(bd71828_mfd_cells), NULL, 0,
> +				   regmap_irq_get_domain(irq_data));
> +	if (ret)
> +		dev_err(&i2c->dev, "Failed to create subdevices\n");
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id bd71828_of_match[] = {
> +	{ .compatible = "rohm,bd71828", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, bd71828_of_match);
> +
> +static struct i2c_driver bd71828_drv = {
> +	.driver = {
> +		.name = "rohm-bd71828",
> +		.of_match_table = bd71828_of_match,
> +	},
> +	.probe = &bd71828_i2c_probe,

If 'id' isn't used, perhaps you should be using probe2?

[...]

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support
  2019-11-01 11:33 ` [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support Matti Vaittinen
@ 2019-11-11 10:59   ` Lee Jones
  2019-11-11 11:07     ` Vaittinen, Matti
  0 siblings, 1 reply; 38+ messages in thread
From: Lee Jones @ 2019-11-11 10:59 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: mazziesaccount, Jacek Anaszewski, Pavel Machek, Dan Murphy,
	Rob Herring, Mark Rutland, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Linus Walleij,
	Bartosz Golaszewski, Alessandro Zummo, Alexandre Belloni,
	linux-leds, devicetree, linux-kernel, linux-clk, linux-gpio,
	linux-rtc

On Fri, 01 Nov 2019, Matti Vaittinen wrote:

> Use gpio_keys to send power input-event to user-space when power
> button (short) press is detected.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
> 
> Changes from v2 - No changes
> 
>  drivers/mfd/rohm-bd71828.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
> index b7de79e1fcdb..f77ba1ec3e99 100644
> --- a/drivers/mfd/rohm-bd71828.c
> +++ b/drivers/mfd/rohm-bd71828.c
> @@ -4,7 +4,9 @@
>  //
>  // ROHM BD71828 PMIC driver
>  
> +#include <linux/gpio_keys.h>
>  #include <linux/i2c.h>
> +#include <linux/input.h>
>  #include <linux/interrupt.h>
>  #include <linux/ioport.h>
>  #include <linux/irq.h>
> @@ -15,6 +17,18 @@
>  #include <linux/regmap.h>
>  #include <linux/types.h>
>  
> +static struct gpio_keys_button button = {
> +	.code = KEY_POWER,
> +	.gpio = -1,
> +	.type = EV_KEY,
> +};
> +
> +static struct gpio_keys_platform_data bd71828_powerkey_data = {
> +	.buttons = &button,
> +	.nbuttons = 1,
> +	.name = "bd71828-pwrkey",
> +};
> +
>  static const struct resource rtc_irqs[] = {
>  	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"),
>  	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"),
> @@ -36,6 +50,10 @@ static struct mfd_cell bd71828_mfd_cells[] = {
>  		.name = "bd70528-rtc",
>  		.resources = rtc_irqs,
>  		.num_resources = ARRAY_SIZE(rtc_irqs),
> +	}, {
> +		.name = "gpio-keys",
> +		.platform_data = &bd71828_powerkey_data,
> +		.pdata_size = sizeof(bd71828_powerkey_data),
>  	},
>  };
>  
> @@ -288,9 +306,19 @@ static int bd71828_i2c_probe(struct i2c_client *i2c,
>  		dev_err(&i2c->dev, "Failed to add IRQ chip\n");
>  		return ret;
>  	}
> +

This should be fixed in the last patch.

>  	dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
>  		bd71828_irq_chip.num_irqs);
>  
> +	ret = regmap_irq_get_virq(irq_data, BD71828_INT_SHORTPUSH);
> +

Remove this empty line.

> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Failed to get the power-key IRQ\n");
> +		return ret;
> +	}
> +
> +	button.irq = ret;
> +

Once fixed, please apply my:

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support
  2019-11-11 10:59   ` Lee Jones
@ 2019-11-11 11:07     ` Vaittinen, Matti
  0 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-11 11:07 UTC (permalink / raw)
  To: lee.jones
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, linus.walleij, mark.rutland, robh+dt, jacek.anaszewski,
	bgolaszewski, linux-clk, sboyd, pavel, broonie

Hello Lee,

On Mon, 2019-11-11 at 10:59 +0000, Lee Jones wrote:
> On Fri, 01 Nov 2019, Matti Vaittinen wrote:
> 
> > Use gpio_keys to send power input-event to user-space when power
> > button (short) press is detected.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> > 
> > Changes from v2 - No changes
> > 
> >  drivers/mfd/rohm-bd71828.c | 28 ++++++++++++++++++++++++++++
> >  1 file changed, 28 insertions(+)
> > 
> > diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-
> > bd71828.c
> > index b7de79e1fcdb..f77ba1ec3e99 100644
> > --- a/drivers/mfd/rohm-bd71828.c
> > +++ b/drivers/mfd/rohm-bd71828.c
> > @@ -4,7 +4,9 @@
> >  //
> >  // ROHM BD71828 PMIC driver
> >  
> > +#include <linux/gpio_keys.h>
> >  #include <linux/i2c.h>
> > +#include <linux/input.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/ioport.h>
> >  #include <linux/irq.h>
> > @@ -15,6 +17,18 @@
> >  #include <linux/regmap.h>
> >  #include <linux/types.h>
> >  
> > +static struct gpio_keys_button button = {
> > +	.code = KEY_POWER,
> > +	.gpio = -1,
> > +	.type = EV_KEY,
> > +};
> > +
> > +static struct gpio_keys_platform_data bd71828_powerkey_data = {
> > +	.buttons = &button,
> > +	.nbuttons = 1,
> > +	.name = "bd71828-pwrkey",
> > +};
> > +
> >  static const struct resource rtc_irqs[] = {
> >  	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"),
> >  	DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"),
> > @@ -36,6 +50,10 @@ static struct mfd_cell bd71828_mfd_cells[] = {
> >  		.name = "bd70528-rtc",
> >  		.resources = rtc_irqs,
> >  		.num_resources = ARRAY_SIZE(rtc_irqs),
> > +	}, {
> > +		.name = "gpio-keys",
> > +		.platform_data = &bd71828_powerkey_data,
> > +		.pdata_size = sizeof(bd71828_powerkey_data),
> >  	},
> >  };
> >  
> > @@ -288,9 +306,19 @@ static int bd71828_i2c_probe(struct i2c_client
> > *i2c,
> >  		dev_err(&i2c->dev, "Failed to add IRQ chip\n");
> >  		return ret;
> >  	}
> > +
> 
> This should be fixed in the last patch.
> 
> >  	dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
> >  		bd71828_irq_chip.num_irqs);
> >  
> > +	ret = regmap_irq_get_virq(irq_data, BD71828_INT_SHORTPUSH);
> > +
> 
> Remove this empty line.
> 
> > +	if (ret < 0) {
> > +		dev_err(&i2c->dev, "Failed to get the power-key
> > IRQ\n");
> > +		return ret;
> > +	}
> > +
> > +	button.irq = ret;
> > +
> 
> Once fixed, please apply my:
> 
> For my own reference:
>   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> 

Thanks for checking this :) I'll apply fixes in patch v4.




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

* Re: [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core
  2019-11-11 10:57   ` Lee Jones
@ 2019-11-11 11:20     ` Vaittinen, Matti
  0 siblings, 0 replies; 38+ messages in thread
From: Vaittinen, Matti @ 2019-11-11 11:20 UTC (permalink / raw)
  To: lee.jones
  Cc: linux-leds, dmurphy, linux-rtc, linux-gpio, alexandre.belloni,
	linux-kernel, mturquette, lgirdwood, devicetree, mazziesaccount,
	a.zummo, linus.walleij, mark.rutland, robh+dt, jacek.anaszewski,
	bgolaszewski, linux-clk, sboyd, pavel, broonie

Hello Lee,

Thanks for the review!

I was slightly worried I really managed to piss you off last time :)
Glad to see I didn't burn all the bridges (yet) ;)

On Mon, 2019-11-11 at 10:57 +0000, Lee Jones wrote:
> On Fri, 01 Nov 2019, Matti Vaittinen wrote:
> 
> > BD71828GW is a single-chip power management IC for battery-powered
> > portable
> > devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA
> > single-cell linear charger. Also included is a Coulomb counter, a
> > real-time
> > clock (RTC), 3 GPO/regulator control pins, HALL input and a 32.768
> > kHz
> > clock gate.
> > 
> > Add MFD core driver providing interrupt controller facilities and
> > i2c
> > access to sub device drivers.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> > 
> > No changes compared to v2
> > 
> >  drivers/mfd/Kconfig              |  15 ++
> >  drivers/mfd/Makefile             |   2 +-
> >  drivers/mfd/rohm-bd71828.c       | 322 +++++++++++++++++++++++
> >  include/linux/mfd/rohm-bd71828.h | 425
> > +++++++++++++++++++++++++++++++
> >  include/linux/mfd/rohm-generic.h |   1 +
> >  5 files changed, 764 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/mfd/rohm-bd71828.c
> >  create mode 100644 include/linux/mfd/rohm-bd71828.h
> 
> /me wonders why this is still an RFC after 3 revisions?

Because of the regulator part. I've had no comments for it - but I
don't think it should be applied as is in this series. I was kind of
hoping someone more experienced could have pointed me that what I have
tried to achieve here is already handled as <something I am missing
now>.

I don't think we should add sysfs control IF for disabling regulators
(I will drop that completely from first non RFC patch - but I hoped I
might get some friendly pokes/pushes to right direction). Nor am I
happy on how the run-state transitions which impact many regulators are
now handled via single regulator reference - but I can't think of
better approach just now. I hoped I am just missing something which is
obvious to more experienced regulator guys.

If I won't get comments to regulators I'll just drop the sysfs
interfaces (and possibly whole run-level control) and send series
without the RFC then. But I am still cautiously hopeful that Mark has
just a extraordinarily busy moment and will give me some feedback
before I finish v4 :)

> > +unsigned int bit0_offsets[] = {11};		/* RTC IRQ
> > register */
> > +unsigned int bit1_offsets[] = {10};		/* TEMP IRQ
> > register */
> > +unsigned int bit2_offsets[] = {6, 7, 8, 9};	/* BAT MON IRQ
> > registers */
> > +unsigned int bit3_offsets[] = {5};		/* BAT IRQ register */
> > +unsigned int bit4_offsets[] = {4};		/* CHG IRQ register */
> > +unsigned int bit5_offsets[] = {3};		/* VSYS IRQ register */
> > +unsigned int bit6_offsets[] = {1, 2};		/* DCIN IRQ
> > registers */
> 
> Something actually wrong with the tabbing here, or is this a
> Git/patch/mailer anomaly?

I'll check this - I need to staticize these anyways.

> > 
> > +static const struct of_device_id bd71828_of_match[] = {
> > +	{ .compatible = "rohm,bd71828", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, bd71828_of_match);
> > +
> > +static struct i2c_driver bd71828_drv = {
> > +	.driver = {
> > +		.name = "rohm-bd71828",
> > +		.of_match_table = bd71828_of_match,
> > +	},
> > +	.probe = &bd71828_i2c_probe,
> 
> If 'id' isn't used, perhaps you should be using probe2?

probe2? Sounds like I need to do my homework once again :) Thanks for
the pointer.

Rest of the comments were pretty obvious - thanks. I'll fix these for
v4.

Br,
	Matti 


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

end of thread, back to index

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-01 11:28 [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Matti Vaittinen
2019-11-01 11:29 ` [RFC PATCH v3 01/15] mfd: bd71828: Support ROHM BD71828 PMIC - core Matti Vaittinen
2019-11-11 10:57   ` Lee Jones
2019-11-11 11:20     ` Vaittinen, Matti
2019-11-01 11:31 ` [RFC PATCH v3 02/15] dt-bindings: mfd: Document ROHM BD71828 bindings Matti Vaittinen
2019-11-05 20:43   ` Rob Herring
2019-11-06 12:55     ` SPAM (R/EU IT) // " Vaittinen, Matti
2019-11-01 11:31 ` [RFC PATCH v3 03/15] dt-bindings: regulator: Document ROHM BD71282 regulator bindings Matti Vaittinen
2019-11-05 20:52   ` Rob Herring
2019-11-07  6:50     ` SPAM (R/EU IT) // " Vaittinen, Matti
2019-11-01 11:32 ` [RFC PATCH v3 04/15] dt-bindings: leds: ROHM BD71282 PMIC LED driver Matti Vaittinen
2019-11-05 19:14   ` Dan Murphy
2019-11-05 20:59     ` Rob Herring
2019-11-06 13:05     ` Vaittinen, Matti
2019-11-05 20:57   ` Rob Herring
2019-11-01 11:33 ` [RFC PATCH v3 05/15] mfd: input: bd71828: Add power-key support Matti Vaittinen
2019-11-11 10:59   ` Lee Jones
2019-11-11 11:07     ` Vaittinen, Matti
2019-11-01 11:38 ` [RFC PATCH v3 06/15] clk: bd718x7: Support ROHM BD71828 clk block Matti Vaittinen
2019-11-01 11:39 ` [RFC PATCH v3 07/15] clk: bd718x7: simplify header dependencies Matti Vaittinen
2019-11-01 11:41 ` [RFC PATCH v3 08/15] regulator: bd718x7: Split driver to common and bd718x7 specific parts Matti Vaittinen
2019-11-01 11:42 ` [RFC PATCH v3 09/15] regulator: bd71828: Basic support for ROHM bd71828 PMIC regulators Matti Vaittinen
2019-11-01 11:43 ` [RFC PATCH v3 10/15] regulator: bd71828: Add GPIO based run-level control for regulators Matti Vaittinen
2019-11-03 22:27   ` Linus Walleij
2019-11-04  7:05     ` Vaittinen, Matti
2019-11-05 13:24       ` Linus Walleij
2019-11-05 14:07         ` Vaittinen, Matti
2019-11-01 11:44 ` [RFC PATCH v3 11/15] regulator: bd71828: enhanced run-level support Matti Vaittinen
2019-11-01 11:45 ` [RFC PATCH v3 12/15] regulator: bd71828: Support in-kernel APIs to change run-level Matti Vaittinen
2019-11-01 11:49 ` [RFC PATCH v3 13/15] rtc: bd70528 add BD71828 support Matti Vaittinen
2019-11-01 11:49 ` [RFC PATCH v3 14/15] gpio: Add definition for GPIO direction Matti Vaittinen
2019-11-03 22:30   ` Linus Walleij
2019-11-04  6:57     ` Vaittinen, Matti
2019-11-04 15:48     ` Vaittinen, Matti
2019-11-05 15:05       ` Linus Walleij
2019-11-06  6:51         ` Vaittinen, Matti
2019-11-01 11:51 ` [RFC PATCH v3 15/15] gpio: bd71828: Initial support for ROHM BD71828 PMIC GPIOs Matti Vaittinen
2019-11-01 11:53 ` [RFC PATCH v3 00/15] Support ROHM BD71828 PMIC Vaittinen, Matti

Linux-Clk Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-clk/0 linux-clk/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-clk linux-clk/ https://lore.kernel.org/linux-clk \
		linux-clk@vger.kernel.org
	public-inbox-index linux-clk

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-clk


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git