···1010 - Matti Vaittinen <mazziesaccount@gmail.com>11111212description: |1313- This module is part of the ROHM BD71828 MFD device. For more details1414- see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.1313+ This module is part of the ROHM BD71828 and BD72720 MFD device. For more1414+ details see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml1515+ and Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml15161617 The LED controller is represented as a sub-node of the PMIC node on the device1717- tree.1818+ tree. This should be located under "leds" - node in PMIC node.18191920 The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.2021
···6464 description: battery design capacity65656666 trickle-charge-current-microamp:6767- description: current for trickle-charge phase6767+ description: current for trickle-charge phase.6868+ Please note that the trickle-charging here, refers "wake-up" or6969+ "pre-pre" -charging, for very empty batteries. Similar term is also7070+ used for "maintenance" or "top-off" -charging of batteries (like7171+ NiMh bq24400) - that is different and not controlled by this7272+ property.7373+7474+ tricklecharge-upper-limit-microvolt:7575+ description: limit when to change to precharge from trickle charge7676+ Trickle-charging here refers "wake-up" or "pre-pre" -charging.68776978 precharge-current-microamp:7079 description: current for pre-charge phase···128119 - description: alert when battery temperature is lower than this value129120 - description: alert when battery temperature is higher than this value130121122122+ # The volt-drop* -properties describe voltage-drop for a battery, described123123+ # as VDROP in:124124+ # https://patentimages.storage.googleapis.com/6c/f5/17/c1d901c220f6a9/US20150032394A1.pdf125125+ volt-drop-thresh-microvolt:126126+ description: Threshold for starting the VDR correction127127+ maximum: 48000000128128+129129+ volt-drop-soc-bp:130130+ description: Table of capacity values matching the values in VDR tables.131131+ The value should be given as basis points, 1/100 of a percent.132132+133133+ volt-drop-temperatures-millicelsius:134134+ description: An array containing the temperature in milli celsius, for each135135+ of the VDR lookup table.136136+131137required:132138 - compatible133139···160136 - description: open circuit voltage (OCV) in microvolts161137 - description: battery capacity percent162138 maximum: 100139139+140140+ '^volt-drop-[0-9]-microvolt':141141+ description: Table of the voltage drop rate (VDR) values. Each entry in the142142+ table should match a capacity value in the volt-drop-soc table.143143+ Furthermore, the values should be obtained for the temperature given in144144+ volt-drop-temperatures-millicelsius table at index matching the145145+ number in this table's name.163146164147additionalProperties: false165148
···11+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause22+%YAML 1.233+---44+$id: http://devicetree.org/schemas/regulator/rohm,bd72720-regulator.yaml#55+$schema: http://devicetree.org/meta-schemas/core.yaml#66+77+title: ROHM BD72720 Power Management Integrated Circuit regulators88+99+maintainers:1010+ - Matti Vaittinen <mazziesaccount@gmail.com>1111+1212+description: |1313+ This module is part of the ROHM BD72720 MFD device. For more details1414+ see Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml.1515+1616+ The regulator controller is represented as a sub-node of the PMIC node1717+ on the device tree.1818+1919+ Regulator nodes should be named to BUCK_<number> and LDO_<number>.2020+ The valid names for BD72720 regulator nodes are2121+ buck1, buck2, buck3, buck4, buck5, buck6, buck7, buck8, buck9, buck102222+ ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8, ldo9, ldo10, ldo112323+2424+patternProperties:2525+ "^ldo([1-9]|1[0-1])$":2626+ type: object2727+ description:2828+ Properties for single LDO regulator.2929+ $ref: regulator.yaml#3030+3131+ properties:3232+ regulator-name:3333+ pattern: "^ldo([1-9]|1[0-1])$"3434+3535+ rohm,dvs-run-voltage:3636+ description:3737+ PMIC default "RUN" state voltage in uV. See below table for3838+ LDOs which support this. 0 means disabled.3939+ $ref: /schemas/types.yaml#/definitions/uint324040+ minimum: 04141+ maximum: 33000004242+4343+ rohm,dvs-idle-voltage:4444+ description:4545+ PMIC default "IDLE" state voltage in uV. See below table for4646+ LDOs which support this. 0 means disabled.4747+ $ref: /schemas/types.yaml#/definitions/uint324848+ minimum: 04949+ maximum: 33000005050+5151+ rohm,dvs-suspend-voltage:5252+ description:5353+ PMIC default "SUSPEND" state voltage in uV. See below table for5454+ LDOs which support this. 0 means disabled.5555+ $ref: /schemas/types.yaml#/definitions/uint325656+ minimum: 05757+ maximum: 33000005858+5959+ rohm,dvs-lpsr-voltage:6060+ description:6161+ PMIC default "deep-idle" state voltage in uV. See below table for6262+ LDOs which support this. 0 means disabled.6363+ $ref: /schemas/types.yaml#/definitions/uint326464+ minimum: 06565+ maximum: 33000006666+6767+ # Supported default DVS states:6868+ # ldo | run | idle | suspend | lpsr6969+ # --------------------------------------------------------------7070+ # 1, 2, 3, and 4 | supported | supported | supported | supported7171+ # --------------------------------------------------------------7272+ # 5 - 11 | supported (*)7373+ # --------------------------------------------------------------7474+ #7575+ # (*) All states use same voltage but have own enable / disable7676+ # settings. Voltage 0 can be specified for a state to make7777+ # regulator disabled on that state.7878+7979+ unevaluatedProperties: false8080+8181+ "^buck([1-9]|10)$":8282+ type: object8383+ description:8484+ Properties for single BUCK regulator.8585+ $ref: regulator.yaml#8686+8787+ properties:8888+ regulator-name:8989+ pattern: "^buck([1-9]|10)$"9090+9191+ rohm,ldon-head-microvolt:9292+ description:9393+ Set this on boards where BUCK10 is used to supply LDOs 1-4. The bucki9494+ voltage will be changed by the PMIC to follow the LDO output voltages9595+ with the offset voltage given here. This will improve the LDO efficiency.9696+ minimum: 500009797+ maximum: 3000009898+9999+ rohm,dvs-run-voltage:100100+ description:101101+ PMIC default "RUN" state voltage in uV. See below table for102102+ bucks which support this. 0 means disabled.103103+ $ref: /schemas/types.yaml#/definitions/uint32104104+ minimum: 0105105+ maximum: 3300000106106+107107+ rohm,dvs-idle-voltage:108108+ description:109109+ PMIC default "IDLE" state voltage in uV. See below table for110110+ bucks which support this. 0 means disabled.111111+ $ref: /schemas/types.yaml#/definitions/uint32112112+ minimum: 0113113+ maximum: 3300000114114+115115+ rohm,dvs-suspend-voltage:116116+ description:117117+ PMIC default "SUSPEND" state voltage in uV. See below table for118118+ bucks which support this. 0 means disabled.119119+ $ref: /schemas/types.yaml#/definitions/uint32120120+ minimum: 0121121+ maximum: 3300000122122+123123+ rohm,dvs-lpsr-voltage:124124+ description:125125+ PMIC default "deep-idle" state voltage in uV. See below table for126126+ bucks which support this. 0 means disabled.127127+ $ref: /schemas/types.yaml#/definitions/uint32128128+ minimum: 0129129+ maximum: 3300000130130+131131+ # Supported default DVS states:132132+ # buck | run | idle | suspend | lpsr133133+ # --------------------------------------------------------------134134+ # 1, 2, 3, and 4 | supported | supported | supported | supported135135+ # --------------------------------------------------------------136136+ # 5 - 10 | supported (*)137137+ # --------------------------------------------------------------138138+ #139139+ # (*) All states use same voltage but have own enable / disable140140+ # settings. Voltage 0 can be specified for a state to make141141+ # regulator disabled on that state.142142+143143+ required:144144+ - regulator-name145145+146146+ unevaluatedProperties: false147147+148148+additionalProperties: false
···475475 tristate "Clock driver for 32K clk gates on ROHM PMICs"476476 depends on MFD_ROHM_BD718XX || MFD_ROHM_BD71828477477 help478478- This driver supports ROHM BD71837, BD71847, BD71850, BD71815479479- and BD71828 PMICs clock gates.478478+ This driver supports ROHM BD71837, BD71847, BD71850, BD71815,479479+ BD71828, and BD72720 PMICs clock gates.480480481481config COMMON_CLK_FIXED_MMIO482482 bool "Clock driver for Memory Mapped Fixed values"
+8-2
drivers/clk/clk-bd718x7.c
···1919#define BD71828_REG_OUT32K 0x4B2020/* BD71837 and BD71847 */2121#define BD718XX_REG_OUT32K 0x2E2222-2222+/* BD72720 */2323+#define BD72720_REG_OUT32K 0x9a2324/*2425 * BD71837, BD71847, and BD71828 all use bit [0] to clk output control2526 */···119118 c->reg = BD71815_REG_OUT32K;120119 c->mask = CLK_OUT_EN_MASK;121120 break;121121+ case ROHM_CHIP_TYPE_BD72720:122122+ c->reg = BD72720_REG_OUT32K;123123+ c->mask = CLK_OUT_EN_MASK;124124+ break;122125 default:123126 dev_err(&pdev->dev, "Unknown clk chip\n");124127 return -EINVAL;···151146 { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 },152147 { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 },153148 { "bd71815-clk", ROHM_CHIP_TYPE_BD71815 },149149+ { "bd72720-clk", ROHM_CHIP_TYPE_BD72720 },154150 { },155151};156152MODULE_DEVICE_TABLE(platform, bd718x7_clk_id);···167161module_platform_driver(bd71837_clk);168162169163MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");170170-MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and chip clk driver");164164+MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and BD72720 chip clk driver");171165MODULE_LICENSE("GPL");172166MODULE_ALIAS("platform:bd718xx-clk");
+9
drivers/gpio/Kconfig
···13171317 This driver can also be built as a module. If so, the module13181318 will be called gpio-bd71828.1319131913201320+config GPIO_BD7272013211321+ tristate "ROHM BD72720 and BD73900 PMIC GPIO support"13221322+ depends on MFD_ROHM_BD7182813231323+ help13241324+ Support for GPIO on ROHM BD72720 and BD73900 PMICs. There are two13251325+ pins which can be configured to GPI or GPO, and three pins which can13261326+ be configured to GPO on the ROHM PMIC. The pin configuration is done13271327+ on OTP at manufacturing.13281328+13201329config GPIO_BD9571MWV13211330 tristate "ROHM BD9571 GPIO support"13221331 depends on MFD_BD9571MWV
···11+// SPDX-License-Identifier: GPL-2.022+/*33+ * Support to GPIOs on ROHM BD72720 and BD7930044+ * Copyright 2025 ROHM Semiconductors.55+ * Author: Matti Vaittinen <mazziesaccount@gmail.com>66+ */77+88+#include <linux/gpio/driver.h>99+#include <linux/init.h>1010+#include <linux/irq.h>1111+#include <linux/module.h>1212+#include <linux/of.h>1313+#include <linux/platform_device.h>1414+#include <linux/mfd/rohm-bd72720.h>1515+1616+#define BD72720_GPIO_OPEN_DRAIN 01717+#define BD72720_GPIO_CMOS BIT(1)1818+#define BD72720_INT_GPIO1_IN_SRC 41919+/*2020+ * The BD72720 has several "one time programmable" (OTP) configurations which2121+ * can be set at manufacturing phase. A set of these options allow using pins2222+ * as GPIO. The OTP configuration can't be read at run-time, so drivers rely on2323+ * device-tree to advertise the correct options.2424+ *2525+ * Both DVS[0,1] pins can be configured to be used for:2626+ * - OTP0: regulator RUN state control2727+ * - OTP1: GPI2828+ * - OTP2: GPO2929+ * - OTP3: Power sequencer output3030+ * Data-sheet also states that these PINs can always be used for IRQ but the3131+ * driver limits this by allowing them to be used for IRQs with OTP1 only.3232+ *3333+ * Pins GPIO_EXTEN0 (GPIO3), GPIO_EXTEN1 (GPIO4), GPIO_FAULT_B (GPIO5) have OTP3434+ * options for a specific (non GPIO) purposes, but also an option to configure3535+ * them to be used as a GPO.3636+ *3737+ * OTP settings can be separately configured for each pin.3838+ *3939+ * DT properties:4040+ * "rohm,pin-dvs0" and "rohm,pin-dvs1" can be set to one of the values:4141+ * "dvs-input", "gpi", "gpo".4242+ *4343+ * "rohm,pin-exten0", "rohm,pin-exten1" and "rohm,pin-fault_b" can be set to:4444+ * "gpo"4545+ */4646+4747+enum bd72720_gpio_state {4848+ BD72720_PIN_UNKNOWN,4949+ BD72720_PIN_GPI,5050+ BD72720_PIN_GPO,5151+};5252+5353+enum {5454+ BD72720_GPIO1,5555+ BD72720_GPIO2,5656+ BD72720_GPIO3,5757+ BD72720_GPIO4,5858+ BD72720_GPIO5,5959+ BD72720_GPIO_EPDEN,6060+ BD72720_NUM_GPIOS6161+};6262+6363+struct bd72720_gpio {6464+ /* chip.parent points the MFD which provides DT node and regmap */6565+ struct gpio_chip chip;6666+ /* dev points to the platform device for devm and prints */6767+ struct device *dev;6868+ struct regmap *regmap;6969+ int gpio_is_input;7070+};7171+7272+static int bd72720gpi_get(struct bd72720_gpio *bdgpio, unsigned int reg_offset)7373+{7474+ int ret, val, shift;7575+7676+ ret = regmap_read(bdgpio->regmap, BD72720_REG_INT_ETC1_SRC, &val);7777+ if (ret)7878+ return ret;7979+8080+ shift = BD72720_INT_GPIO1_IN_SRC + reg_offset;8181+8282+ return (val >> shift) & 1;8383+}8484+8585+static int bd72720gpo_get(struct bd72720_gpio *bdgpio,8686+ unsigned int offset)8787+{8888+ const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL,8989+ BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL,9090+ BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL };9191+ int ret, val;9292+9393+ ret = regmap_read(bdgpio->regmap, regs[offset], &val);9494+ if (ret)9595+ return ret;9696+9797+ return val & BD72720_GPIO_HIGH;9898+}9999+100100+static int bd72720gpio_get(struct gpio_chip *chip, unsigned int offset)101101+{102102+ struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);103103+104104+ if (BIT(offset) & bdgpio->gpio_is_input)105105+ return bd72720gpi_get(bdgpio, offset);106106+107107+ return bd72720gpo_get(bdgpio, offset);108108+}109109+110110+static int bd72720gpo_set(struct gpio_chip *chip, unsigned int offset,111111+ int value)112112+{113113+ struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);114114+ const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL,115115+ BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL,116116+ BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL };117117+118118+ if (BIT(offset) & bdgpio->gpio_is_input) {119119+ dev_dbg(bdgpio->dev, "pin %d not output.\n", offset);120120+ return -EINVAL;121121+ }122122+123123+ if (value)124124+ return regmap_set_bits(bdgpio->regmap, regs[offset],125125+ BD72720_GPIO_HIGH);126126+127127+ return regmap_clear_bits(bdgpio->regmap, regs[offset],128128+ BD72720_GPIO_HIGH);129129+}130130+131131+static int bd72720_gpio_set_config(struct gpio_chip *chip, unsigned int offset,132132+ unsigned long config)133133+{134134+ struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);135135+ const int regs[] = { BD72720_REG_GPIO1_CTRL, BD72720_REG_GPIO2_CTRL,136136+ BD72720_REG_GPIO3_CTRL, BD72720_REG_GPIO4_CTRL,137137+ BD72720_REG_GPIO5_CTRL, BD72720_REG_EPDEN_CTRL };138138+139139+ /*140140+ * We can only set the output mode, which makes sense only when output141141+ * OTP configuration is used.142142+ */143143+ if (BIT(offset) & bdgpio->gpio_is_input)144144+ return -ENOTSUPP;145145+146146+ switch (pinconf_to_config_param(config)) {147147+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:148148+ return regmap_update_bits(bdgpio->regmap,149149+ regs[offset],150150+ BD72720_GPIO_DRIVE_MASK,151151+ BD72720_GPIO_OPEN_DRAIN);152152+ case PIN_CONFIG_DRIVE_PUSH_PULL:153153+ return regmap_update_bits(bdgpio->regmap,154154+ regs[offset],155155+ BD72720_GPIO_DRIVE_MASK,156156+ BD72720_GPIO_CMOS);157157+ default:158158+ break;159159+ }160160+161161+ return -ENOTSUPP;162162+}163163+164164+static int bd72720gpo_direction_get(struct gpio_chip *chip,165165+ unsigned int offset)166166+{167167+ struct bd72720_gpio *bdgpio = gpiochip_get_data(chip);168168+169169+ if (BIT(offset) & bdgpio->gpio_is_input)170170+ return GPIO_LINE_DIRECTION_IN;171171+172172+ return GPIO_LINE_DIRECTION_OUT;173173+}174174+175175+static int bd72720_valid_mask(struct gpio_chip *gc,176176+ unsigned long *valid_mask,177177+ unsigned int ngpios)178178+{179179+ static const char * const properties[] = {180180+ "rohm,pin-dvs0", "rohm,pin-dvs1", "rohm,pin-exten0",181181+ "rohm,pin-exten1", "rohm,pin-fault_b"182182+ };183183+ struct bd72720_gpio *g = gpiochip_get_data(gc);184184+ const char *val;185185+ int i, ret;186186+187187+ *valid_mask = BIT(BD72720_GPIO_EPDEN);188188+189189+ if (!gc->parent)190190+ return 0;191191+192192+ for (i = 0; i < ARRAY_SIZE(properties); i++) {193193+ ret = fwnode_property_read_string(dev_fwnode(gc->parent),194194+ properties[i], &val);195195+196196+ if (ret) {197197+ if (ret == -EINVAL)198198+ continue;199199+200200+ dev_err(g->dev, "pin %d (%s), bad configuration\n", i,201201+ properties[i]);202202+203203+ return ret;204204+ }205205+206206+ if (strcmp(val, "gpi") == 0) {207207+ if (i != BD72720_GPIO1 && i != BD72720_GPIO2) {208208+ dev_warn(g->dev,209209+ "pin %d (%s) does not support INPUT mode",210210+ i, properties[i]);211211+ continue;212212+ }213213+214214+ *valid_mask |= BIT(i);215215+ g->gpio_is_input |= BIT(i);216216+ } else if (strcmp(val, "gpo") == 0) {217217+ *valid_mask |= BIT(i);218218+ }219219+ }220220+221221+ return 0;222222+}223223+224224+/* Template for GPIO chip */225225+static const struct gpio_chip bd72720gpo_chip = {226226+ .label = "bd72720",227227+ .owner = THIS_MODULE,228228+ .get = bd72720gpio_get,229229+ .get_direction = bd72720gpo_direction_get,230230+ .set = bd72720gpo_set,231231+ .set_config = bd72720_gpio_set_config,232232+ .init_valid_mask = bd72720_valid_mask,233233+ .can_sleep = true,234234+ .ngpio = BD72720_NUM_GPIOS,235235+ .base = -1,236236+};237237+238238+static int gpo_bd72720_probe(struct platform_device *pdev)239239+{240240+ struct bd72720_gpio *g;241241+ struct device *parent, *dev;242242+243243+ /*244244+ * Bind devm lifetime to this platform device => use dev for devm.245245+ * also the prints should originate from this device.246246+ */247247+ dev = &pdev->dev;248248+ /* The device-tree and regmap come from MFD => use parent for that */249249+ parent = dev->parent;250250+251251+ g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL);252252+ if (!g)253253+ return -ENOMEM;254254+255255+ g->chip = bd72720gpo_chip;256256+ g->dev = dev;257257+ g->chip.parent = parent;258258+ g->regmap = dev_get_regmap(parent, NULL);259259+260260+ return devm_gpiochip_add_data(dev, &g->chip, g);261261+}262262+263263+static const struct platform_device_id bd72720_gpio_id[] = {264264+ { "bd72720-gpio" },265265+ { },266266+};267267+MODULE_DEVICE_TABLE(platform, bd72720_gpio_id);268268+269269+static struct platform_driver gpo_bd72720_driver = {270270+ .driver = {271271+ .name = "bd72720-gpio",272272+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,273273+ },274274+ .probe = gpo_bd72720_probe,275275+ .id_table = bd72720_gpio_id,276276+};277277+module_platform_driver(gpo_bd72720_driver);278278+279279+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");280280+MODULE_DESCRIPTION("GPIO interface for BD72720 and BD73900");281281+MODULE_LICENSE("GPL");
+10-8
drivers/mfd/Kconfig
···22172217 and emergency shut down as well as 32,768KHz clock output.2218221822192219config MFD_ROHM_BD7182822202220- tristate "ROHM BD71828 and BD71815 Power Management IC"22202220+ tristate "ROHM BD718[15/28/79], BD72720 and BD73900 PMICs"22212221 depends on I2C=y22222222 depends on OF22232223 select REGMAP_I2C22242224 select REGMAP_IRQ22252225 select MFD_CORE22262226 help22272227- Select this option to get support for the ROHM BD71828 and BD7181522282228- Power Management ICs. BD71828GW and BD71815AGW are single-chip power22292229- management ICs mainly for battery-powered portable devices.22302230- The BD71828 integrates 7 buck converters and 7 LDOs. The BD7181522312231- has 5 bucks, 7 LDOs, and a boost for driving LEDs. Both ICs provide22322232- also a single-cell linear charger, a Coulomb counter, a real-time22332233- clock (RTC), GPIOs and a 32.768 kHz clock gate.22272227+ Select this option to get support for the ROHM BD71815, BD71828,22282228+ BD71879, BD72720 and BD73900 Power Management ICs (PMICs). These are22292229+ single-chip Power Management ICs (PMIC), mainly for battery-powered22302230+ portable devices.22312231+ The BD71815 has 5 bucks, 7 LDOs, and a boost for driving LEDs.22322232+ The BD718[28/79] have 7 buck converters and 7 LDOs.22332233+ The BD72720 and the BD73900 have 10 bucks and 11 LDOs.22342234+ All ICs provide a single-cell linear charger, a Coulomb counter,22352235+ a Real-Time Clock (RTC), GPIOs and a 32.768 kHz clock gate.2234223622352237config MFD_ROHM_BD957XMUF22362238 tristate "ROHM BD9576MUF and BD9573MUF Power Management ICs"
+503-52
drivers/mfd/rohm-bd71828.c
···11// SPDX-License-Identifier: GPL-2.0-only22-//33-// Copyright (C) 2019 ROHM Semiconductors44-//55-// ROHM BD71828/BD71815 PMIC driver22+/*33+ * Copyright (C) 2019 ROHM Semiconductors44+ *55+ * ROHM BD718[15/28/79] and BD72720 PMIC driver66+ */6778#include <linux/gpio_keys.h>89#include <linux/i2c.h>···1413#include <linux/mfd/core.h>1514#include <linux/mfd/rohm-bd71815.h>1615#include <linux/mfd/rohm-bd71828.h>1616+#include <linux/mfd/rohm-bd72720.h>1717#include <linux/mfd/rohm-generic.h>1818#include <linux/module.h>1919#include <linux/of.h>2020#include <linux/regmap.h>2121#include <linux/types.h>2222+2323+#define BD72720_TYPED_IRQ_REG(_irq, _stat_offset, _mask, _type_offset) \2424+ [_irq] = { \2525+ .reg_offset = (_stat_offset), \2626+ .mask = (_mask), \2727+ { \2828+ .type_reg_offset = (_type_offset), \2929+ .type_reg_mask = BD72720_GPIO_IRQ_TYPE_MASK, \3030+ .type_rising_val = BD72720_GPIO_IRQ_TYPE_RISING, \3131+ .type_falling_val = BD72720_GPIO_IRQ_TYPE_FALLING, \3232+ .type_level_low_val = BD72720_GPIO_IRQ_TYPE_LOW, \3333+ .type_level_high_val = BD72720_GPIO_IRQ_TYPE_HIGH, \3434+ .types_supported = IRQ_TYPE_EDGE_BOTH | \3535+ IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW, \3636+ }, \3737+ }22382339static struct gpio_keys_button button = {2440 .code = KEY_POWER,···5941 DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd70528-rtc-alm-0"),6042 DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd70528-rtc-alm-1"),6143 DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd70528-rtc-alm-2"),4444+};4545+4646+static const struct resource bd72720_rtc_irqs[] = {4747+ DEFINE_RES_IRQ_NAMED(BD72720_INT_RTC0, "bd70528-rtc-alm-0"),4848+ DEFINE_RES_IRQ_NAMED(BD72720_INT_RTC1, "bd70528-rtc-alm-1"),4949+ DEFINE_RES_IRQ_NAMED(BD72720_INT_RTC2, "bd70528-rtc-alm-2"),6250};63516452static const struct resource bd71815_power_irqs[] = {···180156 },181157};182158183183-static const struct regmap_range bd71815_volatile_ranges[] = {159159+static const struct resource bd72720_power_irqs[] = {160160+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBUS_RMV, "bd72720_int_vbus_rmv"),161161+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBUS_DET, "bd72720_int_vbus_det"),162162+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBUS_MON_RES, "bd72720_int_vbus_mon_res"),163163+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBUS_MON_DET, "bd72720_int_vbus_mon_det"),164164+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_MON_RES, "bd72720_int_vsys_mon_res"),165165+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_MON_DET, "bd72720_int_vsys_mon_det"),166166+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_UV_RES, "bd72720_int_vsys_uv_res"),167167+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_UV_DET, "bd72720_int_vsys_uv_det"),168168+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_LO_RES, "bd72720_int_vsys_lo_res"),169169+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_LO_DET, "bd72720_int_vsys_lo_det"),170170+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_OV_RES, "bd72720_int_vsys_ov_res"),171171+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VSYS_OV_DET, "bd72720_int_vsys_ov_det"),172172+ DEFINE_RES_IRQ_NAMED(BD72720_INT_BAT_ILIM, "bd72720_int_bat_ilim"),173173+ DEFINE_RES_IRQ_NAMED(BD72720_INT_CHG_DONE, "bd72720_int_chg_done"),174174+ DEFINE_RES_IRQ_NAMED(BD72720_INT_EXTEMP_TOUT, "bd72720_int_extemp_tout"),175175+ DEFINE_RES_IRQ_NAMED(BD72720_INT_CHG_WDT_EXP, "bd72720_int_chg_wdt_exp"),176176+ DEFINE_RES_IRQ_NAMED(BD72720_INT_BAT_MNT_OUT, "bd72720_int_bat_mnt_out"),177177+ DEFINE_RES_IRQ_NAMED(BD72720_INT_BAT_MNT_IN, "bd72720_int_bat_mnt_in"),178178+ DEFINE_RES_IRQ_NAMED(BD72720_INT_CHG_TRNS, "bd72720_int_chg_trns"),179179+180180+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_MON_RES, "bd72720_int_vbat_mon_res"),181181+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_MON_DET, "bd72720_int_vbat_mon_det"),182182+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_SHT_RES, "bd72720_int_vbat_sht_res"),183183+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_SHT_DET, "bd72720_int_vbat_sht_det"),184184+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_LO_RES, "bd72720_int_vbat_lo_res"),185185+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_LO_DET, "bd72720_int_vbat_lo_det"),186186+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_OV_RES, "bd72720_int_vbat_ov_res"),187187+ DEFINE_RES_IRQ_NAMED(BD72720_INT_VBAT_OV_DET, "bd72720_int_vbat_ov_det"),188188+ DEFINE_RES_IRQ_NAMED(BD72720_INT_BAT_RMV, "bd72720_int_bat_rmv"),189189+ DEFINE_RES_IRQ_NAMED(BD72720_INT_BAT_DET, "bd72720_int_bat_det"),190190+ DEFINE_RES_IRQ_NAMED(BD72720_INT_DBAT_DET, "bd72720_int_dbat_det"),191191+ DEFINE_RES_IRQ_NAMED(BD72720_INT_BAT_TEMP_TRNS, "bd72720_int_bat_temp_trns"),192192+ DEFINE_RES_IRQ_NAMED(BD72720_INT_LOBTMP_RES, "bd72720_int_lobtmp_res"),193193+ DEFINE_RES_IRQ_NAMED(BD72720_INT_LOBTMP_DET, "bd72720_int_lobtmp_det"),194194+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OVBTMP_RES, "bd72720_int_ovbtmp_res"),195195+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OVBTMP_DET, "bd72720_int_ovbtmp_det"),196196+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OCUR1_RES, "bd72720_int_ocur1_res"),197197+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OCUR1_DET, "bd72720_int_ocur1_det"),198198+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OCUR2_RES, "bd72720_int_ocur2_res"),199199+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OCUR2_DET, "bd72720_int_ocur2_det"),200200+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OCUR3_RES, "bd72720_int_ocur3_res"),201201+ DEFINE_RES_IRQ_NAMED(BD72720_INT_OCUR3_DET, "bd72720_int_ocur3_det"),202202+ DEFINE_RES_IRQ_NAMED(BD72720_INT_CC_MON1_DET, "bd72720_int_cc_mon1_det"),203203+ DEFINE_RES_IRQ_NAMED(BD72720_INT_CC_MON2_DET, "bd72720_int_cc_mon2_det"),204204+ DEFINE_RES_IRQ_NAMED(BD72720_INT_CC_MON3_DET, "bd72720_int_cc_mon3_det"),205205+};206206+207207+static const struct mfd_cell bd72720_mfd_cells[] = {208208+ { .name = "bd72720-pmic", },209209+ { .name = "bd72720-gpio", },210210+ { .name = "bd72720-led", },211211+ { .name = "bd72720-clk", },184212 {185185- .range_min = BD71815_REG_SEC,186186- .range_max = BD71815_REG_YEAR,213213+ .name = "bd72720-power",214214+ .resources = bd72720_power_irqs,215215+ .num_resources = ARRAY_SIZE(bd72720_power_irqs),187216 }, {188188- .range_min = BD71815_REG_CONF,189189- .range_max = BD71815_REG_BAT_TEMP,217217+ .name = "bd72720-rtc",218218+ .resources = bd72720_rtc_irqs,219219+ .num_resources = ARRAY_SIZE(bd72720_rtc_irqs),190220 }, {191191- .range_min = BD71815_REG_VM_IBAT_U,192192- .range_max = BD71815_REG_CC_CTRL,193193- }, {194194- .range_min = BD71815_REG_CC_STAT,195195- .range_max = BD71815_REG_CC_CURCD_L,196196- }, {197197- .range_min = BD71815_REG_VM_BTMP_MON,198198- .range_max = BD71815_REG_VM_BTMP_MON,199199- }, {200200- .range_min = BD71815_REG_INT_STAT,201201- .range_max = BD71815_REG_INT_UPDATE,202202- }, {203203- .range_min = BD71815_REG_VM_VSYS_U,204204- .range_max = BD71815_REG_REX_CTRL_1,205205- }, {206206- .range_min = BD71815_REG_FULL_CCNTD_3,207207- .range_max = BD71815_REG_CCNTD_CHG_2,221221+ .name = "gpio-keys",222222+ .platform_data = &bd71828_powerkey_data,223223+ .pdata_size = sizeof(bd71828_powerkey_data),208224 },209225};210226227227+static const struct regmap_range bd71815_volatile_ranges[] = {228228+ regmap_reg_range(BD71815_REG_SEC, BD71815_REG_YEAR),229229+ regmap_reg_range(BD71815_REG_CONF, BD71815_REG_BAT_TEMP),230230+ regmap_reg_range(BD71815_REG_VM_IBAT_U, BD71815_REG_CC_CTRL),231231+ regmap_reg_range(BD71815_REG_CC_STAT, BD71815_REG_CC_CURCD_L),232232+ regmap_reg_range(BD71815_REG_VM_BTMP_MON, BD71815_REG_VM_BTMP_MON),233233+ regmap_reg_range(BD71815_REG_INT_STAT, BD71815_REG_INT_UPDATE),234234+ regmap_reg_range(BD71815_REG_VM_VSYS_U, BD71815_REG_REX_CTRL_1),235235+ regmap_reg_range(BD71815_REG_FULL_CCNTD_3, BD71815_REG_CCNTD_CHG_2),236236+};237237+211238static const struct regmap_range bd71828_volatile_ranges[] = {212212- {213213- .range_min = BD71828_REG_PS_CTRL_1,214214- .range_max = BD71828_REG_PS_CTRL_1,215215- }, {216216- .range_min = BD71828_REG_PS_CTRL_3,217217- .range_max = BD71828_REG_PS_CTRL_3,218218- }, {219219- .range_min = BD71828_REG_RTC_SEC,220220- .range_max = BD71828_REG_RTC_YEAR,221221- }, {222222- /*223223- * For now make all charger registers volatile because many224224- * needs to be and because the charger block is not that225225- * performance critical.226226- */227227- .range_min = BD71828_REG_CHG_STATE,228228- .range_max = BD71828_REG_CHG_FULL,229229- }, {230230- .range_min = BD71828_REG_INT_MAIN,231231- .range_max = BD71828_REG_IO_STAT,232232- },239239+ regmap_reg_range(BD71828_REG_PS_CTRL_1, BD71828_REG_PS_CTRL_1),240240+ regmap_reg_range(BD71828_REG_PS_CTRL_3, BD71828_REG_PS_CTRL_3),241241+ regmap_reg_range(BD71828_REG_RTC_SEC, BD71828_REG_RTC_YEAR),242242+ /*243243+ * For now make all charger registers volatile because many244244+ * needs to be and because the charger block is not that245245+ * performance critical.246246+ */247247+ regmap_reg_range(BD71828_REG_CHG_STATE, BD71828_REG_CHG_FULL),248248+ regmap_reg_range(BD71828_REG_INT_MAIN, BD71828_REG_IO_STAT),249249+};250250+251251+static const struct regmap_range bd72720_volatile_ranges_4b[] = {252252+ regmap_reg_range(BD72720_REG_RESETSRC_1, BD72720_REG_RESETSRC_2),253253+ regmap_reg_range(BD72720_REG_POWER_STATE, BD72720_REG_POWER_STATE),254254+ /* The state indicator bit changes when new state is reached */255255+ regmap_reg_range(BD72720_REG_PS_CTRL_1, BD72720_REG_PS_CTRL_1),256256+ regmap_reg_range(BD72720_REG_RCVNUM, BD72720_REG_RCVNUM),257257+ regmap_reg_range(BD72720_REG_CONF, BD72720_REG_HALL_STAT),258258+ regmap_reg_range(BD72720_REG_RTC_SEC, BD72720_REG_RTC_YEAR),259259+ regmap_reg_range(BD72720_REG_INT_LVL1_STAT, BD72720_REG_INT_ETC2_SRC),260260+};261261+262262+static const struct regmap_range bd72720_precious_ranges_4b[] = {263263+ regmap_reg_range(BD72720_REG_INT_LVL1_STAT, BD72720_REG_INT_ETC2_STAT),264264+};265265+266266+/*267267+ * The BD72720 is an odd beast in that it contains two separate sets of268268+ * registers, both starting from address 0x0. The twist is that these "pages"269269+ * are behind different I2C slave addresses. Most of the registers are behind270270+ * a slave address 0x4b, which will be used as the "main" address for this271271+ * device.272272+ *273273+ * Most of the charger related registers are located behind slave address 0x4c.274274+ * It is tempting to push the dealing with the charger registers and the extra275275+ * 0x4c device in power-supply driver - but perhaps it's better for the sake of276276+ * the cleaner re-use to deal with setting up all of the regmaps here.277277+ * Furthermore, the LED stuff may need access to both of these devices.278278+ *279279+ * Instead of providing one of the regmaps to sub-devices in MFD platform data,280280+ * we create one more 'wrapper regmap' with custom read/write operations. These281281+ * custom accessors will select which of the 'real' regmaps to use, based on282282+ * the register address.283283+ *284284+ * The register addresses are 8-bit, so we add offset 0x100 to the addresses285285+ * behind the secondary slave 0x4c. The 'wrapper' regmap can then detect the286286+ * correct slave address based on the register address and call regmap_write()287287+ * and regmap_read() using correct 'real' regmap. This way the registers of288288+ * both of the slaves can be accessed using one 'wrapper' regmap.289289+ *290290+ * NOTE: The added offsets mean that the defined addresses for slave 0x4c must291291+ * be used through the 'wrapper' regmap because the offset must be stripped292292+ * from the register addresses. The 0x4b can be accessed both indirectly using293293+ * the 'wrapper' regmap, and directly using the 'real' regmap.294294+ */295295+#define BD72720_SECONDARY_I2C_SLAVE 0x4c296296+#define BD72720_SECONDARY_I2C_REG_OFFSET 0x100297297+298298+struct bd72720_regmaps {299299+ struct regmap *map1_4b;300300+ struct regmap *map2_4c;301301+};302302+303303+/* Translate the slave 0x4c wrapper register address to a real one */304304+#define BD72720_REG_UNWRAP(reg) ((reg) - BD72720_SECONDARY_I2C_REG_OFFSET)305305+306306+/* Ranges given to 'real' 0x4c regmap must use unwrapped addresses. */307307+#define BD72720_UNWRAP_REG_RANGE(startreg, endreg) \308308+ regmap_reg_range(BD72720_REG_UNWRAP(startreg), BD72720_REG_UNWRAP(endreg))309309+310310+static const struct regmap_range bd72720_volatile_ranges_4c[] = {311311+ /* Status information */312312+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_CHG_STATE, BD72720_REG_CHG_EN),313313+ /*314314+ * Under certain circumstances, write to some bits may be315315+ * ignored316316+ */317317+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_CHG_CTRL, BD72720_REG_CHG_CTRL),318318+ /*319319+ * TODO: Ensure this is used to advertise state, not (only?) to320320+ * control it.321321+ */322322+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_VSYS_STATE_STAT, BD72720_REG_VSYS_STATE_STAT),323323+ /* Measured data */324324+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_VM_VBAT_U, BD72720_REG_VM_VF_L),325325+ /* Self clearing bits */326326+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_VM_VSYS_SA_MINMAX_CTRL,327327+ BD72720_REG_VM_VSYS_SA_MINMAX_CTRL),328328+ /* Counters, self clearing bits */329329+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_CC_CURCD_U, BD72720_REG_CC_CTRL),330330+ /* Self clearing bits */331331+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_CC_CCNTD_CTRL, BD72720_REG_CC_CCNTD_CTRL),332332+ /* Self clearing bits */333333+ BD72720_UNWRAP_REG_RANGE(BD72720_REG_IMPCHK_CTRL, BD72720_REG_IMPCHK_CTRL),233334};234335235336static const struct regmap_access_table bd71815_volatile_regs = {···365216static const struct regmap_access_table bd71828_volatile_regs = {366217 .yes_ranges = &bd71828_volatile_ranges[0],367218 .n_yes_ranges = ARRAY_SIZE(bd71828_volatile_ranges),219219+};220220+221221+static const struct regmap_access_table bd72720_volatile_regs_4b = {222222+ .yes_ranges = &bd72720_volatile_ranges_4b[0],223223+ .n_yes_ranges = ARRAY_SIZE(bd72720_volatile_ranges_4b),224224+};225225+226226+static const struct regmap_access_table bd72720_precious_regs_4b = {227227+ .yes_ranges = &bd72720_precious_ranges_4b[0],228228+ .n_yes_ranges = ARRAY_SIZE(bd72720_precious_ranges_4b),229229+};230230+231231+static const struct regmap_access_table bd72720_volatile_regs_4c = {232232+ .yes_ranges = &bd72720_volatile_ranges_4c[0],233233+ .n_yes_ranges = ARRAY_SIZE(bd72720_volatile_ranges_4c),368234};369235370236static const struct regmap_config bd71815_regmap = {···398234 .cache_type = REGCACHE_MAPLE,399235};400236237237+static int regmap_write_wrapper(void *context, unsigned int reg, unsigned int val)238238+{239239+ struct bd72720_regmaps *maps = context;240240+241241+ if (reg < BD72720_SECONDARY_I2C_REG_OFFSET)242242+ return regmap_write(maps->map1_4b, reg, val);243243+244244+ reg = BD72720_REG_UNWRAP(reg);245245+246246+ return regmap_write(maps->map2_4c, reg, val);247247+}248248+249249+static int regmap_read_wrapper(void *context, unsigned int reg, unsigned int *val)250250+{251251+ struct bd72720_regmaps *maps = context;252252+253253+ if (reg < BD72720_SECONDARY_I2C_REG_OFFSET)254254+ return regmap_read(maps->map1_4b, reg, val);255255+256256+ reg = BD72720_REG_UNWRAP(reg);257257+258258+ return regmap_read(maps->map2_4c, reg, val);259259+}260260+261261+static const struct regmap_config bd72720_wrapper_map_config = {262262+ .name = "wrap-map",263263+ .reg_bits = 9,264264+ .val_bits = 8,265265+ .max_register = BD72720_REG_IMPCHK_CTRL,266266+ /*267267+ * We don't want to duplicate caches. It would be a bit faster to268268+ * have the cache in this 'wrapper regmap', and not in the 'real269269+ * regmaps' bd72720_regmap_4b and bd72720_regmap_4c below. This would270270+ * require all the subdevices to use the wrapper-map in order to be271271+ * able to benefit from the cache.272272+ * Currently most of the sub-devices use only the same slave-address273273+ * as this MFD driver. Now, because we don't add the offset to the274274+ * registers belonging to this slave, those devices can use either the275275+ * wrapper map, or the bd72720_regmap_4b directly. This means majority276276+ * of our sub devices don't need to care which regmap they get using277277+ * the dev_get_regmap(). This unifies the code between the BD72720 and278278+ * those variants which don't have this 'multiple slave addresses'279279+ * -hassle.280280+ * So, for a small performance penalty, we simplify the code for the281281+ * sub-devices by having the caches in the wrapped regmaps and not here.282282+ */283283+ .cache_type = REGCACHE_NONE,284284+ .reg_write = regmap_write_wrapper,285285+ .reg_read = regmap_read_wrapper,286286+};287287+288288+static const struct regmap_config bd72720_regmap_4b = {289289+ .reg_bits = 8,290290+ .val_bits = 8,291291+ .volatile_table = &bd72720_volatile_regs_4b,292292+ .precious_table = &bd72720_precious_regs_4b,293293+ .max_register = BD72720_REG_INT_ETC2_SRC,294294+ .cache_type = REGCACHE_MAPLE,295295+};296296+297297+static const struct regmap_config bd72720_regmap_4c = {298298+ .reg_bits = 8,299299+ .val_bits = 8,300300+ .volatile_table = &bd72720_volatile_regs_4c,301301+ .max_register = BD72720_REG_UNWRAP(BD72720_REG_IMPCHK_CTRL),302302+ .cache_type = REGCACHE_MAPLE,303303+};304304+401305/*402306 * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can403307 * access corect sub-IRQ registers based on bits that are set in main IRQ404404- * register. BD71815 and BD71828 have same sub-register-block offests.308308+ * register. BD71815 and BD71828 have same sub-register-block offests, the309309+ * BD72720 has a different one.405310 */406311407312static unsigned int bit0_offsets[] = {11}; /* RTC IRQ */···482249static unsigned int bit6_offsets[] = {1, 2}; /* DCIN IRQ */483250static unsigned int bit7_offsets[] = {0}; /* BUCK IRQ */484251252252+static unsigned int bd72720_bit0_offsets[] = {0, 1}; /* PS1 and PS2 */253253+static unsigned int bd72720_bit1_offsets[] = {2, 3}; /* DVS1 and DVS2 */254254+static unsigned int bd72720_bit2_offsets[] = {4}; /* VBUS */255255+static unsigned int bd72720_bit3_offsets[] = {5}; /* VSYS */256256+static unsigned int bd72720_bit4_offsets[] = {6}; /* CHG */257257+static unsigned int bd72720_bit5_offsets[] = {7, 8}; /* BAT1 and BAT2 */258258+static unsigned int bd72720_bit6_offsets[] = {9}; /* IBAT */259259+static unsigned int bd72720_bit7_offsets[] = {10, 11}; /* ETC1 and ETC2 */260260+485261static const struct regmap_irq_sub_irq_map bd718xx_sub_irq_offsets[] = {486262 REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),487263 REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),···500258 REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),501259 REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),502260 REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),261261+};262262+263263+static const struct regmap_irq_sub_irq_map bd72720_sub_irq_offsets[] = {264264+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit0_offsets),265265+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit1_offsets),266266+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit2_offsets),267267+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit3_offsets),268268+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit4_offsets),269269+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit5_offsets),270270+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit6_offsets),271271+ REGMAP_IRQ_MAIN_REG_OFFSET(bd72720_bit7_offsets),503272};504273505274static const struct regmap_irq bd71815_irqs[] = {···686433 REGMAP_IRQ_REG(BD71828_INT_RTC2, 11, BD71828_INT_RTC2_MASK),687434};688435436436+static const struct regmap_irq bd72720_irqs[] = {437437+ REGMAP_IRQ_REG(BD72720_INT_LONGPUSH, 0, BD72720_INT_LONGPUSH_MASK),438438+ REGMAP_IRQ_REG(BD72720_INT_MIDPUSH, 0, BD72720_INT_MIDPUSH_MASK),439439+ REGMAP_IRQ_REG(BD72720_INT_SHORTPUSH, 0, BD72720_INT_SHORTPUSH_MASK),440440+ REGMAP_IRQ_REG(BD72720_INT_PUSH, 0, BD72720_INT_PUSH_MASK),441441+ REGMAP_IRQ_REG(BD72720_INT_HALL_DET, 0, BD72720_INT_HALL_DET_MASK),442442+ REGMAP_IRQ_REG(BD72720_INT_HALL_TGL, 0, BD72720_INT_HALL_TGL_MASK),443443+ REGMAP_IRQ_REG(BD72720_INT_WDOG, 0, BD72720_INT_WDOG_MASK),444444+ REGMAP_IRQ_REG(BD72720_INT_SWRESET, 0, BD72720_INT_SWRESET_MASK),445445+ REGMAP_IRQ_REG(BD72720_INT_SEQ_DONE, 1, BD72720_INT_SEQ_DONE_MASK),446446+ REGMAP_IRQ_REG(BD72720_INT_PGFAULT, 1, BD72720_INT_PGFAULT_MASK),447447+ REGMAP_IRQ_REG(BD72720_INT_BUCK1_DVS, 2, BD72720_INT_BUCK1_DVS_MASK),448448+ REGMAP_IRQ_REG(BD72720_INT_BUCK2_DVS, 2, BD72720_INT_BUCK2_DVS_MASK),449449+ REGMAP_IRQ_REG(BD72720_INT_BUCK3_DVS, 2, BD72720_INT_BUCK3_DVS_MASK),450450+ REGMAP_IRQ_REG(BD72720_INT_BUCK4_DVS, 2, BD72720_INT_BUCK4_DVS_MASK),451451+ REGMAP_IRQ_REG(BD72720_INT_BUCK5_DVS, 2, BD72720_INT_BUCK5_DVS_MASK),452452+ REGMAP_IRQ_REG(BD72720_INT_BUCK6_DVS, 2, BD72720_INT_BUCK6_DVS_MASK),453453+ REGMAP_IRQ_REG(BD72720_INT_BUCK7_DVS, 2, BD72720_INT_BUCK7_DVS_MASK),454454+ REGMAP_IRQ_REG(BD72720_INT_BUCK8_DVS, 2, BD72720_INT_BUCK8_DVS_MASK),455455+ REGMAP_IRQ_REG(BD72720_INT_BUCK9_DVS, 3, BD72720_INT_BUCK9_DVS_MASK),456456+ REGMAP_IRQ_REG(BD72720_INT_BUCK10_DVS, 3, BD72720_INT_BUCK10_DVS_MASK),457457+ REGMAP_IRQ_REG(BD72720_INT_LDO1_DVS, 3, BD72720_INT_LDO1_DVS_MASK),458458+ REGMAP_IRQ_REG(BD72720_INT_LDO2_DVS, 3, BD72720_INT_LDO2_DVS_MASK),459459+ REGMAP_IRQ_REG(BD72720_INT_LDO3_DVS, 3, BD72720_INT_LDO3_DVS_MASK),460460+ REGMAP_IRQ_REG(BD72720_INT_LDO4_DVS, 3, BD72720_INT_LDO4_DVS_MASK),461461+462462+ REGMAP_IRQ_REG(BD72720_INT_VBUS_RMV, 4, BD72720_INT_VBUS_RMV_MASK),463463+ REGMAP_IRQ_REG(BD72720_INT_VBUS_DET, 4, BD72720_INT_VBUS_DET_MASK),464464+ REGMAP_IRQ_REG(BD72720_INT_VBUS_MON_RES, 4, BD72720_INT_VBUS_MON_RES_MASK),465465+ REGMAP_IRQ_REG(BD72720_INT_VBUS_MON_DET, 4, BD72720_INT_VBUS_MON_DET_MASK),466466+ REGMAP_IRQ_REG(BD72720_INT_VSYS_MON_RES, 5, BD72720_INT_VSYS_MON_RES_MASK),467467+ REGMAP_IRQ_REG(BD72720_INT_VSYS_MON_DET, 5, BD72720_INT_VSYS_MON_DET_MASK),468468+ REGMAP_IRQ_REG(BD72720_INT_VSYS_UV_RES, 5, BD72720_INT_VSYS_UV_RES_MASK),469469+ REGMAP_IRQ_REG(BD72720_INT_VSYS_UV_DET, 5, BD72720_INT_VSYS_UV_DET_MASK),470470+ REGMAP_IRQ_REG(BD72720_INT_VSYS_LO_RES, 5, BD72720_INT_VSYS_LO_RES_MASK),471471+ REGMAP_IRQ_REG(BD72720_INT_VSYS_LO_DET, 5, BD72720_INT_VSYS_LO_DET_MASK),472472+ REGMAP_IRQ_REG(BD72720_INT_VSYS_OV_RES, 5, BD72720_INT_VSYS_OV_RES_MASK),473473+ REGMAP_IRQ_REG(BD72720_INT_VSYS_OV_DET, 5, BD72720_INT_VSYS_OV_DET_MASK),474474+ REGMAP_IRQ_REG(BD72720_INT_BAT_ILIM, 6, BD72720_INT_BAT_ILIM_MASK),475475+ REGMAP_IRQ_REG(BD72720_INT_CHG_DONE, 6, BD72720_INT_CHG_DONE_MASK),476476+ REGMAP_IRQ_REG(BD72720_INT_EXTEMP_TOUT, 6, BD72720_INT_EXTEMP_TOUT_MASK),477477+ REGMAP_IRQ_REG(BD72720_INT_CHG_WDT_EXP, 6, BD72720_INT_CHG_WDT_EXP_MASK),478478+ REGMAP_IRQ_REG(BD72720_INT_BAT_MNT_OUT, 6, BD72720_INT_BAT_MNT_OUT_MASK),479479+ REGMAP_IRQ_REG(BD72720_INT_BAT_MNT_IN, 6, BD72720_INT_BAT_MNT_IN_MASK),480480+ REGMAP_IRQ_REG(BD72720_INT_CHG_TRNS, 6, BD72720_INT_CHG_TRNS_MASK),481481+482482+ REGMAP_IRQ_REG(BD72720_INT_VBAT_MON_RES, 7, BD72720_INT_VBAT_MON_RES_MASK),483483+ REGMAP_IRQ_REG(BD72720_INT_VBAT_MON_DET, 7, BD72720_INT_VBAT_MON_DET_MASK),484484+ REGMAP_IRQ_REG(BD72720_INT_VBAT_SHT_RES, 7, BD72720_INT_VBAT_SHT_RES_MASK),485485+ REGMAP_IRQ_REG(BD72720_INT_VBAT_SHT_DET, 7, BD72720_INT_VBAT_SHT_DET_MASK),486486+ REGMAP_IRQ_REG(BD72720_INT_VBAT_LO_RES, 7, BD72720_INT_VBAT_LO_RES_MASK),487487+ REGMAP_IRQ_REG(BD72720_INT_VBAT_LO_DET, 7, BD72720_INT_VBAT_LO_DET_MASK),488488+ REGMAP_IRQ_REG(BD72720_INT_VBAT_OV_RES, 7, BD72720_INT_VBAT_OV_RES_MASK),489489+ REGMAP_IRQ_REG(BD72720_INT_VBAT_OV_DET, 7, BD72720_INT_VBAT_OV_DET_MASK),490490+ REGMAP_IRQ_REG(BD72720_INT_BAT_RMV, 8, BD72720_INT_BAT_RMV_MASK),491491+ REGMAP_IRQ_REG(BD72720_INT_BAT_DET, 8, BD72720_INT_BAT_DET_MASK),492492+ REGMAP_IRQ_REG(BD72720_INT_DBAT_DET, 8, BD72720_INT_DBAT_DET_MASK),493493+ REGMAP_IRQ_REG(BD72720_INT_BAT_TEMP_TRNS, 8, BD72720_INT_BAT_TEMP_TRNS_MASK),494494+ REGMAP_IRQ_REG(BD72720_INT_LOBTMP_RES, 8, BD72720_INT_LOBTMP_RES_MASK),495495+ REGMAP_IRQ_REG(BD72720_INT_LOBTMP_DET, 8, BD72720_INT_LOBTMP_DET_MASK),496496+ REGMAP_IRQ_REG(BD72720_INT_OVBTMP_RES, 8, BD72720_INT_OVBTMP_RES_MASK),497497+ REGMAP_IRQ_REG(BD72720_INT_OVBTMP_DET, 8, BD72720_INT_OVBTMP_DET_MASK),498498+ REGMAP_IRQ_REG(BD72720_INT_OCUR1_RES, 9, BD72720_INT_OCUR1_RES_MASK),499499+ REGMAP_IRQ_REG(BD72720_INT_OCUR1_DET, 9, BD72720_INT_OCUR1_DET_MASK),500500+ REGMAP_IRQ_REG(BD72720_INT_OCUR2_RES, 9, BD72720_INT_OCUR2_RES_MASK),501501+ REGMAP_IRQ_REG(BD72720_INT_OCUR2_DET, 9, BD72720_INT_OCUR2_DET_MASK),502502+ REGMAP_IRQ_REG(BD72720_INT_OCUR3_RES, 9, BD72720_INT_OCUR3_RES_MASK),503503+ REGMAP_IRQ_REG(BD72720_INT_OCUR3_DET, 9, BD72720_INT_OCUR3_DET_MASK),504504+ REGMAP_IRQ_REG(BD72720_INT_CC_MON1_DET, 10, BD72720_INT_CC_MON1_DET_MASK),505505+ REGMAP_IRQ_REG(BD72720_INT_CC_MON2_DET, 10, BD72720_INT_CC_MON2_DET_MASK),506506+ REGMAP_IRQ_REG(BD72720_INT_CC_MON3_DET, 10, BD72720_INT_CC_MON3_DET_MASK),507507+/*508508+ * The GPIO1_IN and GPIO2_IN IRQs are generated from the PMIC's GPIO1 and GPIO2509509+ * pins. Eg, they may be wired to other devices which can then use the PMIC as510510+ * an interrupt controller. The GPIO1 and GPIO2 can have the IRQ type511511+ * specified. All of the types (falling, rising, and both edges as well as low512512+ * and high levels) are supported.513513+ */514514+ BD72720_TYPED_IRQ_REG(BD72720_INT_GPIO1_IN, 10, BD72720_INT_GPIO1_IN_MASK, 0),515515+ BD72720_TYPED_IRQ_REG(BD72720_INT_GPIO2_IN, 10, BD72720_INT_GPIO2_IN_MASK, 1),516516+ REGMAP_IRQ_REG(BD72720_INT_VF125_RES, 11, BD72720_INT_VF125_RES_MASK),517517+ REGMAP_IRQ_REG(BD72720_INT_VF125_DET, 11, BD72720_INT_VF125_DET_MASK),518518+ REGMAP_IRQ_REG(BD72720_INT_VF_RES, 11, BD72720_INT_VF_RES_MASK),519519+ REGMAP_IRQ_REG(BD72720_INT_VF_DET, 11, BD72720_INT_VF_DET_MASK),520520+ REGMAP_IRQ_REG(BD72720_INT_RTC0, 11, BD72720_INT_RTC0_MASK),521521+ REGMAP_IRQ_REG(BD72720_INT_RTC1, 11, BD72720_INT_RTC1_MASK),522522+ REGMAP_IRQ_REG(BD72720_INT_RTC2, 11, BD72720_INT_RTC2_MASK),523523+};524524+525525+static int bd72720_set_type_config(unsigned int **buf, unsigned int type,526526+ const struct regmap_irq *irq_data,527527+ int idx, void *irq_drv_data)528528+{529529+ const struct regmap_irq_type *t = &irq_data->type;530530+531531+ /*532532+ * The regmap IRQ ecpects IRQ_TYPE_EDGE_BOTH to be written to register533533+ * as logical OR of the type_falling_val and type_rising_val. This is534534+ * not how the BD72720 implements this configuration, hence we need535535+ * to handle this specific case separately.536536+ */537537+ if (type == IRQ_TYPE_EDGE_BOTH) {538538+ buf[0][idx] &= ~t->type_reg_mask;539539+ buf[0][idx] |= BD72720_GPIO_IRQ_TYPE_BOTH;540540+541541+ return 0;542542+ }543543+544544+ return regmap_irq_set_type_config_simple(buf, type, irq_data, idx, irq_drv_data);545545+}546546+689547static const struct regmap_irq_chip bd71828_irq_chip = {690548 .name = "bd71828_irq",691549 .main_status = BD71828_REG_INT_MAIN,···825461 .num_regs = 12,826462 .num_main_regs = 1,827463 .sub_reg_offsets = &bd718xx_sub_irq_offsets[0],464464+ .num_main_status_bits = 8,465465+ .irq_reg_stride = 1,466466+};467467+468468+static const unsigned int bd72720_irq_type_base[] = { BD72720_REG_GPIO1_CTRL };469469+470470+static const struct regmap_irq_chip bd72720_irq_chip = {471471+ .name = "bd72720_irq",472472+ .main_status = BD72720_REG_INT_LVL1_STAT,473473+ .irqs = &bd72720_irqs[0],474474+ .num_irqs = ARRAY_SIZE(bd72720_irqs),475475+ .status_base = BD72720_REG_INT_PS1_STAT,476476+ .unmask_base = BD72720_REG_INT_PS1_EN,477477+ .config_base = &bd72720_irq_type_base[0],478478+ .num_config_bases = 1,479479+ .num_config_regs = 2,480480+ .set_type_config = bd72720_set_type_config,481481+ .ack_base = BD72720_REG_INT_PS1_STAT,482482+ .init_ack_masked = true,483483+ .num_regs = 12,484484+ .num_main_regs = 1,485485+ .sub_reg_offsets = &bd72720_sub_irq_offsets[0],828486 .num_main_status_bits = 8,829487 .irq_reg_stride = 1,830488};···897511 pm_power_off = NULL;898512}899513514514+static struct regmap *bd72720_do_regmaps(struct i2c_client *i2c)515515+{516516+ struct bd72720_regmaps *maps;517517+ struct i2c_client *secondary_i2c;518518+519519+ secondary_i2c = devm_i2c_new_dummy_device(&i2c->dev, i2c->adapter,520520+ BD72720_SECONDARY_I2C_SLAVE);521521+ if (IS_ERR(secondary_i2c)) {522522+ dev_err_probe(&i2c->dev, PTR_ERR(secondary_i2c), "Failed to get secondary I2C\n");523523+524524+ return ERR_CAST(secondary_i2c);525525+ }526526+527527+ maps = devm_kzalloc(&i2c->dev, sizeof(*maps), GFP_KERNEL);528528+ if (!maps)529529+ return ERR_PTR(-ENOMEM);530530+531531+ maps->map1_4b = devm_regmap_init_i2c(i2c, &bd72720_regmap_4b);532532+ if (IS_ERR(maps->map1_4b))533533+ return maps->map1_4b;534534+535535+ maps->map2_4c = devm_regmap_init_i2c(secondary_i2c, &bd72720_regmap_4c);536536+ if (IS_ERR(maps->map2_4c))537537+ return maps->map2_4c;538538+539539+ return devm_regmap_init(&i2c->dev, NULL, maps, &bd72720_wrapper_map_config);540540+}541541+900542static int bd71828_i2c_probe(struct i2c_client *i2c)901543{902544 struct regmap_irq_chip_data *irq_data;903545 int ret;904904- struct regmap *regmap;546546+ struct regmap *regmap = NULL;905547 const struct regmap_config *regmap_config;906548 const struct regmap_irq_chip *irqchip;907549 unsigned int chip_type;···937523 int cells;938524 int button_irq;939525 int clkmode_reg;526526+ int main_lvl_mask_reg = 0, main_lvl_val = 0;940527941528 if (!i2c->irq) {942529 dev_err(&i2c->dev, "No IRQ configured\n");···969554 */970555 button_irq = 0;971556 break;557557+ case ROHM_CHIP_TYPE_BD72720:558558+ {559559+ mfd = bd72720_mfd_cells;560560+ cells = ARRAY_SIZE(bd72720_mfd_cells);561561+562562+ regmap = bd72720_do_regmaps(i2c);563563+ if (IS_ERR(regmap))564564+ return dev_err_probe(&i2c->dev, PTR_ERR(regmap),565565+ "Failed to initialize Regmap\n");566566+567567+ irqchip = &bd72720_irq_chip;568568+ clkmode_reg = BD72720_REG_OUT32K;569569+ button_irq = BD72720_INT_SHORTPUSH;570570+ main_lvl_mask_reg = BD72720_REG_INT_LVL1_EN;571571+ main_lvl_val = BD72720_MASK_LVL1_EN_ALL;572572+ break;573573+ }972574 default:973575 dev_err(&i2c->dev, "Unknown device type");974576 return -EINVAL;975577 }976578977977- regmap = devm_regmap_init_i2c(i2c, regmap_config);978978- if (IS_ERR(regmap))979979- return dev_err_probe(&i2c->dev, PTR_ERR(regmap),579579+ if (!regmap) {580580+ regmap = devm_regmap_init_i2c(i2c, regmap_config);581581+ if (IS_ERR(regmap))582582+ return dev_err_probe(&i2c->dev, PTR_ERR(regmap),980583 "Failed to initialize Regmap\n");584584+ }981585982586 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq,983587 IRQF_ONESHOT, 0, irqchip, &irq_data);···1007573 dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",1008574 irqchip->num_irqs);1009575576576+ /*577577+ * On some ICs the main IRQ register has corresponding mask register.578578+ * This is not handled by the regmap IRQ. Let's enable all the main579579+ * level IRQs here. Further writes to the main level MASK is not580580+ * needed because masking is handled by the per IRQ 2.nd level MASK581581+ * registers. 2.nd level masks are handled by the regmap IRQ.582582+ */583583+ if (main_lvl_mask_reg) {584584+ ret = regmap_write(regmap, main_lvl_mask_reg, main_lvl_val);585585+ if (ret) {586586+ return dev_err_probe(&i2c->dev, ret,587587+ "Failed to enable main level IRQs\n");588588+ }589589+ }1010590 if (button_irq) {1011591 ret = regmap_irq_get_virq(irq_data, button_irq);1012592 if (ret < 0)···1062614 }, {1063615 .compatible = "rohm,bd71815",1064616 .data = (void *)ROHM_CHIP_TYPE_BD71815,617617+ }, {618618+ .compatible = "rohm,bd72720",619619+ .data = (void *)ROHM_CHIP_TYPE_BD72720,1065620 },1066621 { },1067622};
+129-31
drivers/power/supply/bd71828-power.c
···55#include <linux/kernel.h>66#include <linux/mfd/rohm-bd71815.h>77#include <linux/mfd/rohm-bd71828.h>88+#include <linux/mfd/rohm-bd72720.h>89#include <linux/module.h>910#include <linux/mod_devicetable.h>1011#include <linux/platform_device.h>···4544#define VBAT_LOW_TH 0x00D446454746struct pwr_regs {4848- u8 vbat_avg;4949- u8 ibat;5050- u8 ibat_avg;5151- u8 btemp_vth;5252- u8 chg_state;5353- u8 bat_temp;5454- u8 dcin_stat;5555- u8 dcin_collapse_limit;5656- u8 chg_set1;5757- u8 chg_en;5858- u8 vbat_alm_limit_u;5959- u8 conf;6060- u8 vdcin;4747+ unsigned int vbat_avg;4848+ unsigned int ibat;4949+ unsigned int ibat_avg;5050+ unsigned int btemp_vth;5151+ unsigned int chg_state;5252+ unsigned int bat_temp;5353+ unsigned int dcin_stat;5454+ unsigned int dcin_online_mask;5555+ unsigned int dcin_collapse_limit;5656+ unsigned int chg_set1;5757+ unsigned int chg_en;5858+ unsigned int vbat_alm_limit_u;5959+ unsigned int conf;6060+ unsigned int vdcin;6161+ unsigned int vdcin_himask;6162};62636364static const struct pwr_regs pwr_regs_bd71828 = {···7067 .chg_state = BD71828_REG_CHG_STATE,7168 .bat_temp = BD71828_REG_BAT_TEMP,7269 .dcin_stat = BD71828_REG_DCIN_STAT,7070+ .dcin_online_mask = BD7182x_MASK_DCIN_DET,7371 .dcin_collapse_limit = BD71828_REG_DCIN_CLPS,7472 .chg_set1 = BD71828_REG_CHG_SET1,7573 .chg_en = BD71828_REG_CHG_EN,7674 .vbat_alm_limit_u = BD71828_REG_ALM_VBAT_LIMIT_U,7775 .conf = BD71828_REG_CONF,7876 .vdcin = BD71828_REG_VDCIN_U,7777+ .vdcin_himask = BD7182x_MASK_VDCIN_U,7978};80798180static const struct pwr_regs pwr_regs_bd71815 = {···9085 .chg_state = BD71815_REG_CHG_STATE,9186 .bat_temp = BD71815_REG_BAT_TEMP,9287 .dcin_stat = BD71815_REG_DCIN_STAT,8888+ .dcin_online_mask = BD7182x_MASK_DCIN_DET,9389 .dcin_collapse_limit = BD71815_REG_DCIN_CLPS,9490 .chg_set1 = BD71815_REG_CHG_SET1,9591 .chg_en = BD71815_REG_CHG_SET1,···9892 .conf = BD71815_REG_CONF,999310094 .vdcin = BD71815_REG_VM_DCIN_U,9595+ .vdcin_himask = BD7182x_MASK_VDCIN_U,9696+};9797+9898+static struct pwr_regs pwr_regs_bd72720 = {9999+ .vbat_avg = BD72720_REG_VM_SA_VBAT_U,100100+ .ibat = BD72720_REG_CC_CURCD_U,101101+ .ibat_avg = BD72720_REG_CC_SA_CURCD_U,102102+ .btemp_vth = BD72720_REG_VM_BTMP_U,103103+ /*104104+ * Note, state 0x40 IMP_CHK. not documented105105+ * on other variants but was still handled in106106+ * existing code. No memory traces as to why.107107+ */108108+ .chg_state = BD72720_REG_CHG_STATE,109109+ .bat_temp = BD72720_REG_CHG_BAT_TEMP_STAT,110110+ .dcin_stat = BD72720_REG_INT_VBUS_SRC,111111+ .dcin_online_mask = BD72720_MASK_DCIN_DET,112112+ .dcin_collapse_limit = -1, /* Automatic. Setting not supported */113113+ .chg_set1 = BD72720_REG_CHG_SET_1,114114+ .chg_en = BD72720_REG_CHG_EN,115115+ /* 15mV note in data-sheet */116116+ .vbat_alm_limit_u = BD72720_REG_ALM_VBAT_TH_U,117117+ .conf = BD72720_REG_CONF, /* o XSTB, only PON. Seprate slave addr */118118+ .vdcin = BD72720_REG_VM_VBUS_U, /* 10 bits not 11 as with other ICs */119119+ .vdcin_himask = BD72720_MASK_VDCIN_U,101120};102121103122struct bd71828_power {···329298 dev_err(pwr->dev, "Failed to read DCIN status\n");330299 return ret;331300 }332332- *chg_online = ((r & BD7182x_MASK_DCIN_DET) != 0);301301+ *chg_online = ((r & pwr->regs->dcin_online_mask) != 0);333302334303 return 0;335304}···360329 ret = val & BD7182x_MASK_CONF_PON;361330362331 if (ret)363363- regmap_update_bits(pwr->regmap, pwr->regs->conf,364364- BD7182x_MASK_CONF_PON, 0);332332+ if (regmap_update_bits(pwr->regmap, pwr->regs->conf, BD7182x_MASK_CONF_PON, 0))333333+ dev_err(pwr->dev, "Failed to write CONF register\n");365334366335 return ret;367336}···389358 int ret;390359391360 /* TODO: Collapse limit should come from device-tree ? */392392- ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit,393393- BD7182x_DCIN_COLLAPSE_DEFAULT);394394- if (ret) {395395- dev_err(pwr->dev, "Failed to write DCIN collapse limit\n");396396- return ret;361361+ if (pwr->regs->dcin_collapse_limit != (unsigned int)-1) {362362+ ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit,363363+ BD7182x_DCIN_COLLAPSE_DEFAULT);364364+ if (ret) {365365+ dev_err(pwr->dev, "Failed to write DCIN collapse limit\n");366366+ return ret;367367+ }397368 }398369399370 ret = pwr->bat_inserted(pwr);···452419 break;453420 case POWER_SUPPLY_PROP_VOLTAGE_NOW:454421 ret = bd7182x_read16_himask(pwr, pwr->regs->vdcin,455455- BD7182x_MASK_VDCIN_U, &tmp);422422+ pwr->regs->vdcin_himask, &tmp);456423 if (ret)457424 return ret;458425···663630BD_ISR_DUMMY(dcin_mon_det, "DCIN voltage below threshold")664631BD_ISR_DUMMY(dcin_mon_res, "DCIN voltage above threshold")665632633633+BD_ISR_DUMMY(vbus_curr_limit, "VBUS current limited")634634+BD_ISR_DUMMY(vsys_ov_res, "VSYS over-voltage cleared")635635+BD_ISR_DUMMY(vsys_ov_det, "VSYS over-voltage")666636BD_ISR_DUMMY(vsys_uv_res, "VSYS under-voltage cleared")667637BD_ISR_DUMMY(vsys_uv_det, "VSYS under-voltage")668638BD_ISR_DUMMY(vsys_low_res, "'VSYS low' cleared")···914878 BDIRQ("bd71828-temp-125-over", bd71828_temp_vf125_det),915879 BDIRQ("bd71828-temp-125-under", bd71828_temp_vf125_res),916880 };881881+ static const struct bd7182x_irq_res bd72720_irqs[] = {882882+ BDIRQ("bd72720_int_vbus_rmv", BD_ISR_NAME(dcin_removed)),883883+ BDIRQ("bd72720_int_vbus_det", bd7182x_dcin_detected),884884+ BDIRQ("bd72720_int_vbus_mon_res", BD_ISR_NAME(dcin_mon_res)),885885+ BDIRQ("bd72720_int_vbus_mon_det", BD_ISR_NAME(dcin_mon_det)),886886+ BDIRQ("bd72720_int_vsys_mon_res", BD_ISR_NAME(vsys_mon_res)),887887+ BDIRQ("bd72720_int_vsys_mon_det", BD_ISR_NAME(vsys_mon_det)),888888+ BDIRQ("bd72720_int_vsys_uv_res", BD_ISR_NAME(vsys_uv_res)),889889+ BDIRQ("bd72720_int_vsys_uv_det", BD_ISR_NAME(vsys_uv_det)),890890+ BDIRQ("bd72720_int_vsys_lo_res", BD_ISR_NAME(vsys_low_res)),891891+ BDIRQ("bd72720_int_vsys_lo_det", BD_ISR_NAME(vsys_low_det)),892892+ BDIRQ("bd72720_int_vsys_ov_res", BD_ISR_NAME(vsys_ov_res)),893893+ BDIRQ("bd72720_int_vsys_ov_det", BD_ISR_NAME(vsys_ov_det)),894894+ BDIRQ("bd72720_int_bat_ilim", BD_ISR_NAME(vbus_curr_limit)),895895+ BDIRQ("bd72720_int_chg_done", bd718x7_chg_done),896896+ BDIRQ("bd72720_int_extemp_tout", BD_ISR_NAME(chg_wdg_temp)),897897+ BDIRQ("bd72720_int_chg_wdt_exp", BD_ISR_NAME(chg_wdg)),898898+ BDIRQ("bd72720_int_bat_mnt_out", BD_ISR_NAME(rechg_res)),899899+ BDIRQ("bd72720_int_bat_mnt_in", BD_ISR_NAME(rechg_det)),900900+ BDIRQ("bd72720_int_chg_trns", BD_ISR_NAME(chg_state_changed)),901901+902902+ BDIRQ("bd72720_int_vbat_mon_res", BD_ISR_NAME(bat_mon_res)),903903+ BDIRQ("bd72720_int_vbat_mon_det", BD_ISR_NAME(bat_mon)),904904+ BDIRQ("bd72720_int_vbat_sht_res", BD_ISR_NAME(bat_short_res)),905905+ BDIRQ("bd72720_int_vbat_sht_det", BD_ISR_NAME(bat_short)),906906+ BDIRQ("bd72720_int_vbat_lo_res", BD_ISR_NAME(bat_low_res)),907907+ BDIRQ("bd72720_int_vbat_lo_det", BD_ISR_NAME(bat_low)),908908+ BDIRQ("bd72720_int_vbat_ov_res", BD_ISR_NAME(bat_ov_res)),909909+ BDIRQ("bd72720_int_vbat_ov_det", BD_ISR_NAME(bat_ov)),910910+ BDIRQ("bd72720_int_bat_rmv", BD_ISR_NAME(bat_removed)),911911+ BDIRQ("bd72720_int_bat_det", BD_ISR_NAME(bat_det)),912912+ BDIRQ("bd72720_int_dbat_det", BD_ISR_NAME(bat_dead)),913913+ BDIRQ("bd72720_int_bat_temp_trns", BD_ISR_NAME(temp_transit)),914914+ BDIRQ("bd72720_int_lobtmp_res", BD_ISR_NAME(temp_bat_low_res)),915915+ BDIRQ("bd72720_int_lobtmp_det", BD_ISR_NAME(temp_bat_low)),916916+ BDIRQ("bd72720_int_ovbtmp_res", BD_ISR_NAME(temp_bat_hi_res)),917917+ BDIRQ("bd72720_int_ovbtmp_det", BD_ISR_NAME(temp_bat_hi)),918918+ BDIRQ("bd72720_int_ocur1_res", BD_ISR_NAME(bat_oc1_res)),919919+ BDIRQ("bd72720_int_ocur1_det", BD_ISR_NAME(bat_oc1)),920920+ BDIRQ("bd72720_int_ocur2_res", BD_ISR_NAME(bat_oc2_res)),921921+ BDIRQ("bd72720_int_ocur2_det", BD_ISR_NAME(bat_oc2)),922922+ BDIRQ("bd72720_int_ocur3_res", BD_ISR_NAME(bat_oc3_res)),923923+ BDIRQ("bd72720_int_ocur3_det", BD_ISR_NAME(bat_oc3)),924924+ BDIRQ("bd72720_int_cc_mon2_det", BD_ISR_NAME(bat_cc_mon)),925925+ };917926 int num_irqs;918927 const struct bd7182x_irq_res *irqs;919928···970889 case ROHM_CHIP_TYPE_BD71815:971890 irqs = &bd71815_irqs[0];972891 num_irqs = ARRAY_SIZE(bd71815_irqs);892892+ break;893893+ case ROHM_CHIP_TYPE_BD72720:894894+ irqs = &bd72720_irqs[0];895895+ num_irqs = ARRAY_SIZE(bd72720_irqs);973896 break;974897 default:975898 return -EINVAL;···1043958 struct power_supply_config ac_cfg = {};1044959 struct power_supply_config bat_cfg = {};1045960 int ret;10461046- struct regmap *regmap;10471047-10481048- regmap = dev_get_regmap(pdev->dev.parent, NULL);10491049- if (!regmap) {10501050- dev_err(&pdev->dev, "No parent regmap\n");10511051- return -EINVAL;10521052- }10539611054962 pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL);1055963 if (!pwr)1056964 return -ENOMEM;105796510581058- pwr->regmap = regmap;10591059- pwr->dev = &pdev->dev;966966+ /*967967+ * The BD72720 MFD device registers two regmaps. Power-supply driver968968+ * uses the "wrap-map", which provides access to both of the I2C slave969969+ * addresses used by the BD72720970970+ */1060971 pwr->chip_type = platform_get_device_id(pdev)->driver_data;972972+ if (pwr->chip_type != ROHM_CHIP_TYPE_BD72720)973973+ pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL);974974+ else975975+ pwr->regmap = dev_get_regmap(pdev->dev.parent, "wrap-map");976976+ if (!pwr->regmap) {977977+ dev_err(&pdev->dev, "No parent regmap\n");978978+ return -EINVAL;979979+ }980980+981981+ pwr->dev = &pdev->dev;10619821062983 switch (pwr->chip_type) {1063984 case ROHM_CHIP_TYPE_BD71828:···1075984 pwr->bat_inserted = bd71815_bat_inserted;1076985 pwr->get_temp = bd71815_get_temp;1077986 pwr->regs = &pwr_regs_bd71815;987987+ break;988988+ case ROHM_CHIP_TYPE_BD72720:989989+ pwr->bat_inserted = bd71828_bat_inserted;990990+ pwr->regs = &pwr_regs_bd72720;991991+ pwr->get_temp = bd71828_get_temp;992992+ dev_dbg(pwr->dev, "Found ROHM BD72720\n");1078993 break;1079994 default:1080995 dev_err(pwr->dev, "Unknown PMIC\n");···11271030static const struct platform_device_id bd71828_charger_id[] = {11281031 { "bd71815-power", ROHM_CHIP_TYPE_BD71815 },11291032 { "bd71828-power", ROHM_CHIP_TYPE_BD71828 },10331033+ { "bd72720-power", ROHM_CHIP_TYPE_BD72720 },11301034 { },11311035};11321036MODULE_DEVICE_TABLE(platform, bd71828_charger_id);
+4-4
drivers/regulator/Kconfig
···241241 will be called bd71815-regulator.242242243243config REGULATOR_BD71828244244- tristate "ROHM BD71828 Power Regulator"244244+ tristate "ROHM BD71828, BD72720 and BD73900 Power Regulators"245245 depends on MFD_ROHM_BD71828246246 select REGULATOR_ROHM247247 help248248- This driver supports voltage regulators on ROHM BD71828 PMIC.249249- This will enable support for the software controllable buck250250- and LDO regulators.248248+ This driver supports voltage regulators on ROHM BD71828,249249+ BD71879, BD72720 and BD73900 PMICs. This will enable250250+ support for the software controllable buck and LDO regulators.251251252252 This driver can also be built as a module. If so, the module253253 will be called bd71828-regulator.
···570570 depends on MFD_ROHM_BD71828571571 help572572 If you say Y here you will get support for the RTC573573- block on ROHM BD71815 and BD71828 Power Management IC.573573+ block on ROHM BD71815, BD71828 and BD72720 Power574574+ Management ICs.574575575576 This driver can also be built as a module. If so, the module576577 will be called rtc-bd70528.
+14-7
drivers/rtc/rtc-bd70528.c
···77#include <linux/bcd.h>88#include <linux/mfd/rohm-bd71815.h>99#include <linux/mfd/rohm-bd71828.h>1010+#include <linux/mfd/rohm-bd72720.h>1011#include <linux/module.h>1112#include <linux/of.h>1213#include <linux/platform_device.h>···263262264263 /*265264 * See also BD718XX_ALM_EN_OFFSET:266266- * This works for BD71828 and BD71815 as they have same offset267267- * between ALM0 start and ALM0_MASK. If new ICs are to be268268- * added this requires proper check as ALM0_MASK is not located269269- * at the end of ALM0 block - but after all ALM blocks so if270270- * amount of ALMs differ the offset to enable/disable is likely271271- * to be incorrect and enable/disable must be given as own272272- * reg address here.265265+ * This works for BD71828, BD71815, and BD72720 as they all266266+ * have same offset between the ALM0 start and the ALM0_MASK.267267+ * If new ICs are to be added this requires proper check as268268+ * the ALM0_MASK is not located at the end of ALM0 block -269269+ * but after all ALM blocks. If amount of ALMs differ, the270270+ * offset to enable/disable is likely to be incorrect and271271+ * enable/disable must be given as own reg address here.273272 */274273 bd_rtc->bd718xx_alm_block_start = BD71815_REG_RTC_ALM_START;275274 hour_reg = BD71815_REG_HOUR;···278277 bd_rtc->reg_time_start = BD71828_REG_RTC_START;279278 bd_rtc->bd718xx_alm_block_start = BD71828_REG_RTC_ALM_START;280279 hour_reg = BD71828_REG_RTC_HOUR;280280+ break;281281+ case ROHM_CHIP_TYPE_BD72720:282282+ bd_rtc->reg_time_start = BD72720_REG_RTC_START;283283+ bd_rtc->bd718xx_alm_block_start = BD72720_REG_RTC_ALM_START;284284+ hour_reg = BD72720_REG_RTC_HOUR;281285 break;282286 default:283287 dev_err(&pdev->dev, "Unknown chip\n");···343337static const struct platform_device_id bd718x7_rtc_id[] = {344338 { "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 },345339 { "bd71815-rtc", ROHM_CHIP_TYPE_BD71815 },340340+ { "bd72720-rtc", ROHM_CHIP_TYPE_BD72720 },346341 { },347342};348343MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);