Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'ib-mfd-drm-5.6' and 'ib-mfd-clk-gpio-regulator-rtc-5.6' into ibs-for-mfd-merged

+1718 -223
+52
Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/leds/rohm,bd71828-leds.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71828 Power Management Integrated Circuit LED driver 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + This module is part of the ROHM BD71828 MFD device. For more details 14 + see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml. 15 + 16 + The LED controller is represented as a sub-node of the PMIC node on the device 17 + tree. 18 + 19 + The device has two LED outputs referred as GRNLED and AMBLED in data-sheet. 20 + 21 + select: false 22 + 23 + properties: 24 + compatible: 25 + const: rohm,bd71828-leds 26 + 27 + patternProperties: 28 + "^led-[1-2]$": 29 + type: object 30 + description: 31 + Properties for a single LED. 32 + properties: 33 + #allOf: 34 + #- $ref: "common.yaml#" 35 + rohm,led-compatible: 36 + description: LED identification string 37 + allOf: 38 + - $ref: "/schemas/types.yaml#/definitions/string" 39 + - enum: 40 + - bd71828-ambled 41 + - bd71828-grnled 42 + function: 43 + description: 44 + Purpose of LED as defined in dt-bindings/leds/common.h 45 + $ref: "/schemas/types.yaml#/definitions/string" 46 + color: 47 + description: 48 + LED colour as defined in dt-bindings/leds/common.h 49 + $ref: "/schemas/types.yaml#/definitions/uint32" 50 + 51 + required: 52 + - compatible
+193
Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/rohm,bd71828-pmic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71828 Power Management Integrated Circuit bindings 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + BD71828GW is a single-chip power management IC for battery-powered portable 14 + devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA 15 + single-cell linear charger. Also included is a Coulomb counter, a real-time 16 + clock (RTC), and a 32.768 kHz clock gate. 17 + 18 + properties: 19 + compatible: 20 + const: rohm,bd71828 21 + 22 + reg: 23 + description: 24 + I2C slave address. 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + gpio-controller: true 31 + 32 + "#gpio-cells": 33 + const: 2 34 + description: | 35 + The first cell is the pin number and the second cell is used to specify 36 + flags. See ../gpio/gpio.txt for more information. 37 + 38 + clocks: 39 + maxItems: 1 40 + 41 + "#clock-cells": 42 + const: 0 43 + 44 + rohm,charger-sense-resistor-ohms: 45 + minimum: 10000000 46 + maximum: 50000000 47 + description: | 48 + BD71827 and BD71828 have SAR ADC for measuring charging currents. 49 + External sense resistor (RSENSE in data sheet) should be used. If some 50 + other but 30MOhm resistor is used the resistance value should be given 51 + here in Ohms. 52 + 53 + regulators: 54 + $ref: ../regulator/rohm,bd71828-regulator.yaml 55 + description: 56 + List of child nodes that specify the regulators. 57 + 58 + leds: 59 + $ref: ../leds/rohm,bd71828-leds.yaml 60 + 61 + gpio-reserved-ranges: 62 + description: | 63 + Usage of BD71828 GPIO pins can be changed via OTP. This property can be 64 + used to mark the pins which should not be configured for GPIO. Please see 65 + the ../gpio/gpio.txt for more information. 66 + 67 + required: 68 + - compatible 69 + - reg 70 + - interrupts 71 + - clocks 72 + - "#clock-cells" 73 + - regulators 74 + - gpio-controller 75 + - "#gpio-cells" 76 + 77 + examples: 78 + - | 79 + #include <dt-bindings/interrupt-controller/irq.h> 80 + #include <dt-bindings/leds/common.h> 81 + i2c { 82 + #address-cells = <1>; 83 + #size-cells = <0>; 84 + pmic: pmic@4b { 85 + compatible = "rohm,bd71828"; 86 + reg = <0x4b>; 87 + 88 + interrupt-parent = <&gpio1>; 89 + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; 90 + 91 + clocks = <&osc 0>; 92 + #clock-cells = <0>; 93 + clock-output-names = "bd71828-32k-out"; 94 + 95 + gpio-controller; 96 + #gpio-cells = <2>; 97 + gpio-reserved-ranges = <0 1>, <2 1>; 98 + 99 + rohm,charger-sense-resistor-ohms = <10000000>; 100 + 101 + regulators { 102 + buck1: BUCK1 { 103 + regulator-name = "buck1"; 104 + regulator-min-microvolt = <500000>; 105 + regulator-max-microvolt = <2000000>; 106 + regulator-ramp-delay = <2500>; 107 + }; 108 + buck2: BUCK2 { 109 + regulator-name = "buck2"; 110 + regulator-min-microvolt = <500000>; 111 + regulator-max-microvolt = <2000000>; 112 + regulator-ramp-delay = <2500>; 113 + }; 114 + buck3: BUCK3 { 115 + regulator-name = "buck3"; 116 + regulator-min-microvolt = <1200000>; 117 + regulator-max-microvolt = <2000000>; 118 + }; 119 + buck4: BUCK4 { 120 + regulator-name = "buck4"; 121 + regulator-min-microvolt = <1000000>; 122 + regulator-max-microvolt = <1800000>; 123 + }; 124 + buck5: BUCK5 { 125 + regulator-name = "buck5"; 126 + regulator-min-microvolt = <2500000>; 127 + regulator-max-microvolt = <3300000>; 128 + }; 129 + buck6: BUCK6 { 130 + regulator-name = "buck6"; 131 + regulator-min-microvolt = <500000>; 132 + regulator-max-microvolt = <2000000>; 133 + regulator-ramp-delay = <2500>; 134 + }; 135 + buck7: BUCK7 { 136 + regulator-name = "buck7"; 137 + regulator-min-microvolt = <500000>; 138 + regulator-max-microvolt = <2000000>; 139 + regulator-ramp-delay = <2500>; 140 + }; 141 + ldo1: LDO1 { 142 + regulator-name = "ldo1"; 143 + regulator-min-microvolt = <800000>; 144 + regulator-max-microvolt = <3300000>; 145 + }; 146 + ldo2: LDO2 { 147 + regulator-name = "ldo2"; 148 + regulator-min-microvolt = <800000>; 149 + regulator-max-microvolt = <3300000>; 150 + }; 151 + ldo3: LDO3 { 152 + regulator-name = "ldo3"; 153 + regulator-min-microvolt = <800000>; 154 + regulator-max-microvolt = <3300000>; 155 + }; 156 + ldo4: LDO4 { 157 + regulator-name = "ldo4"; 158 + regulator-min-microvolt = <800000>; 159 + regulator-max-microvolt = <3300000>; 160 + }; 161 + ldo5: LDO5 { 162 + regulator-name = "ldo5"; 163 + regulator-min-microvolt = <800000>; 164 + regulator-max-microvolt = <3300000>; 165 + }; 166 + ldo6: LDO6 { 167 + regulator-name = "ldo6"; 168 + regulator-min-microvolt = <1800000>; 169 + regulator-max-microvolt = <1800000>; 170 + }; 171 + ldo7_reg: LDO7 { 172 + regulator-name = "ldo7"; 173 + regulator-min-microvolt = <800000>; 174 + regulator-max-microvolt = <3300000>; 175 + }; 176 + }; 177 + 178 + leds { 179 + compatible = "rohm,bd71828-leds"; 180 + 181 + led-1 { 182 + rohm,led-compatible = "bd71828-grnled"; 183 + function = LED_FUNCTION_INDICATOR; 184 + color = <LED_COLOR_ID_GREEN>; 185 + }; 186 + led-2 { 187 + rohm,led-compatible = "bd71828-ambled"; 188 + function = LED_FUNCTION_CHARGING; 189 + color = <LED_COLOR_ID_AMBER>; 190 + }; 191 + }; 192 + }; 193 + };
+3 -3
drivers/clk/Kconfig
··· 305 305 Support for Marvell MMP2 and MMP3 SoC clocks 306 306 307 307 config COMMON_CLK_BD718XX 308 - tristate "Clock driver for ROHM BD718x7 PMIC" 309 - depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 308 + tristate "Clock driver for 32K clk gates on ROHM PMICs" 309 + depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828 310 310 help 311 - This driver supports ROHM BD71837, ROHM BD71847 and 311 + This driver supports ROHM BD71837, ROHM BD71847, ROHM BD71828 and 312 312 ROHM BD70528 PMICs clock gates. 313 313 314 314 config COMMON_CLK_FIXED_MMIO
+39 -11
drivers/clk/clk-bd718x7.c
··· 7 7 #include <linux/err.h> 8 8 #include <linux/platform_device.h> 9 9 #include <linux/slab.h> 10 - #include <linux/mfd/rohm-bd718x7.h> 11 - #include <linux/mfd/rohm-bd70528.h> 10 + #include <linux/mfd/rohm-generic.h> 12 11 #include <linux/clk-provider.h> 13 12 #include <linux/clkdev.h> 14 13 #include <linux/regmap.h> 14 + 15 + /* clk control registers */ 16 + /* BD70528 */ 17 + #define BD70528_REG_OUT32K 0x2c 18 + /* BD71828 */ 19 + #define BD71828_REG_OUT32K 0x4B 20 + /* BD71837 and BD71847 */ 21 + #define BD718XX_REG_OUT32K 0x2E 22 + 23 + /* 24 + * BD71837, BD71847, BD70528 and BD71828 all use bit [0] to clk output control 25 + */ 26 + #define CLK_OUT_EN_MASK BIT(0) 27 + 15 28 16 29 struct bd718xx_clk { 17 30 struct clk_hw hw; ··· 34 21 struct rohm_regmap_dev *mfd; 35 22 }; 36 23 37 - static int bd71837_clk_set(struct clk_hw *hw, int status) 24 + static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status) 38 25 { 39 - struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); 40 - 41 26 return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status); 42 27 } 43 28 ··· 44 33 int rv; 45 34 struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); 46 35 47 - rv = bd71837_clk_set(hw, 0); 36 + rv = bd71837_clk_set(c, 0); 48 37 if (rv) 49 38 dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv); 50 39 } 51 40 52 41 static int bd71837_clk_enable(struct clk_hw *hw) 53 42 { 54 - return bd71837_clk_set(hw, 1); 43 + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); 44 + 45 + return bd71837_clk_set(c, 0xffffffff); 55 46 } 56 47 57 48 static int bd71837_clk_is_enabled(struct clk_hw *hw) ··· 87 74 .name = "bd718xx-32k-out", 88 75 .ops = &bd71837_clk_ops, 89 76 }; 77 + enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 90 78 91 79 c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL); 92 80 if (!c) ··· 101 87 dev_err(&pdev->dev, "No parent clk found\n"); 102 88 return -EINVAL; 103 89 } 104 - switch (mfd->chip_type) { 90 + switch (chip) { 105 91 case ROHM_CHIP_TYPE_BD71837: 106 92 case ROHM_CHIP_TYPE_BD71847: 107 93 c->reg = BD718XX_REG_OUT32K; 108 - c->mask = BD718XX_OUT32K_EN; 94 + c->mask = CLK_OUT_EN_MASK; 95 + break; 96 + case ROHM_CHIP_TYPE_BD71828: 97 + c->reg = BD71828_REG_OUT32K; 98 + c->mask = CLK_OUT_EN_MASK; 109 99 break; 110 100 case ROHM_CHIP_TYPE_BD70528: 111 - c->reg = BD70528_REG_CLK_OUT; 112 - c->mask = BD70528_CLK_OUT_EN_MASK; 101 + c->reg = BD70528_REG_OUT32K; 102 + c->mask = CLK_OUT_EN_MASK; 113 103 break; 114 104 default: 115 105 dev_err(&pdev->dev, "Unknown clk chip\n"); ··· 139 121 return rval; 140 122 } 141 123 124 + static const struct platform_device_id bd718x7_clk_id[] = { 125 + { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 }, 126 + { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 }, 127 + { "bd70528-clk", ROHM_CHIP_TYPE_BD70528 }, 128 + { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 }, 129 + { }, 130 + }; 131 + MODULE_DEVICE_TABLE(platform, bd718x7_clk_id); 132 + 142 133 static struct platform_driver bd71837_clk = { 143 134 .driver = { 144 135 .name = "bd718xx-clk", 145 136 }, 146 137 .probe = bd71837_clk_probe, 138 + .id_table = bd718x7_clk_id, 147 139 }; 148 140 149 141 module_platform_driver(bd71837_clk);
+12
drivers/gpio/Kconfig
··· 1021 1021 This driver can also be built as a module. If so, the module 1022 1022 will be called gpio-bd70528. 1023 1023 1024 + config GPIO_BD71828 1025 + tristate "ROHM BD71828 GPIO support" 1026 + depends on MFD_ROHM_BD71828 1027 + help 1028 + Support for GPIOs on ROHM BD71828 PMIC. There are three GPIOs 1029 + available on the ROHM PMIC in total. The GPIOs are limited to 1030 + outputs only and pins must be configured to GPIO outputs by 1031 + OTP. Enable this only if you want to use these pins as outputs. 1032 + 1033 + This driver can also be built as a module. If so, the module 1034 + will be called gpio-bd71828. 1035 + 1024 1036 config GPIO_BD9571MWV 1025 1037 tristate "ROHM BD9571 GPIO support" 1026 1038 depends on MFD_BD9571MWV
+1
drivers/gpio/Makefile
··· 37 37 obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o 38 38 obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o 39 39 obj-$(CONFIG_GPIO_BD70528) += gpio-bd70528.o 40 + obj-$(CONFIG_GPIO_BD71828) += gpio-bd71828.o 40 41 obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o 41 42 obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o 42 43 obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
+159
drivers/gpio/gpio-bd71828.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // Copyright (C) 2018 ROHM Semiconductors 3 + 4 + #include <linux/gpio/driver.h> 5 + #include <linux/mfd/rohm-bd71828.h> 6 + #include <linux/module.h> 7 + #include <linux/platform_device.h> 8 + #include <linux/regmap.h> 9 + 10 + #define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off)) 11 + #define HALL_GPIO_OFFSET 3 12 + 13 + /* 14 + * These defines can be removed when 15 + * "gpio: Add definition for GPIO direction" 16 + * (9208b1e77d6e8e9776f34f46ef4079ecac9c3c25 in GPIO tree) gets merged, 17 + */ 18 + #ifndef GPIO_LINE_DIRECTION_IN 19 + #define GPIO_LINE_DIRECTION_IN 1 20 + #define GPIO_LINE_DIRECTION_OUT 0 21 + #endif 22 + 23 + struct bd71828_gpio { 24 + struct rohm_regmap_dev chip; 25 + struct gpio_chip gpio; 26 + }; 27 + 28 + static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset, 29 + int value) 30 + { 31 + int ret; 32 + struct bd71828_gpio *bdgpio = gpiochip_get_data(chip); 33 + u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO; 34 + 35 + /* 36 + * The HALL input pin can only be used as input. If this is the pin 37 + * we are dealing with - then we are done 38 + */ 39 + if (offset == HALL_GPIO_OFFSET) 40 + return; 41 + 42 + ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset), 43 + BD71828_GPIO_OUT_MASK, val); 44 + if (ret) 45 + dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value); 46 + } 47 + 48 + static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset) 49 + { 50 + int ret; 51 + unsigned int val; 52 + struct bd71828_gpio *bdgpio = gpiochip_get_data(chip); 53 + 54 + if (offset == HALL_GPIO_OFFSET) 55 + ret = regmap_read(bdgpio->chip.regmap, BD71828_REG_IO_STAT, 56 + &val); 57 + else 58 + ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset), 59 + &val); 60 + if (!ret) 61 + ret = (val & BD71828_GPIO_OUT_MASK); 62 + 63 + return ret; 64 + } 65 + 66 + static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 67 + unsigned long config) 68 + { 69 + struct bd71828_gpio *bdgpio = gpiochip_get_data(chip); 70 + 71 + if (offset == HALL_GPIO_OFFSET) 72 + return -ENOTSUPP; 73 + 74 + switch (pinconf_to_config_param(config)) { 75 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 76 + return regmap_update_bits(bdgpio->chip.regmap, 77 + GPIO_OUT_REG(offset), 78 + BD71828_GPIO_DRIVE_MASK, 79 + BD71828_GPIO_OPEN_DRAIN); 80 + case PIN_CONFIG_DRIVE_PUSH_PULL: 81 + return regmap_update_bits(bdgpio->chip.regmap, 82 + GPIO_OUT_REG(offset), 83 + BD71828_GPIO_DRIVE_MASK, 84 + BD71828_GPIO_PUSH_PULL); 85 + default: 86 + break; 87 + } 88 + return -ENOTSUPP; 89 + } 90 + 91 + static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset) 92 + { 93 + /* 94 + * Pin usage is selected by OTP data. We can't read it runtime. Hence 95 + * we trust that if the pin is not excluded by "gpio-reserved-ranges" 96 + * the OTP configuration is set to OUT. (Other pins but HALL input pin 97 + * on BD71828 can't really be used for general purpose input - input 98 + * states are used for specific cases like regulator control or 99 + * PMIC_ON_REQ. 100 + */ 101 + if (offset == HALL_GPIO_OFFSET) 102 + return GPIO_LINE_DIRECTION_IN; 103 + 104 + return GPIO_LINE_DIRECTION_OUT; 105 + } 106 + 107 + static int bd71828_probe(struct platform_device *pdev) 108 + { 109 + struct bd71828_gpio *bdgpio; 110 + struct rohm_regmap_dev *bd71828; 111 + 112 + bd71828 = dev_get_drvdata(pdev->dev.parent); 113 + if (!bd71828) { 114 + dev_err(&pdev->dev, "No MFD driver data\n"); 115 + return -EINVAL; 116 + } 117 + 118 + bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio), 119 + GFP_KERNEL); 120 + if (!bdgpio) 121 + return -ENOMEM; 122 + 123 + bdgpio->chip.dev = &pdev->dev; 124 + bdgpio->gpio.parent = pdev->dev.parent; 125 + bdgpio->gpio.label = "bd71828-gpio"; 126 + bdgpio->gpio.owner = THIS_MODULE; 127 + bdgpio->gpio.get_direction = bd71828_get_direction; 128 + bdgpio->gpio.set_config = bd71828_gpio_set_config; 129 + bdgpio->gpio.can_sleep = true; 130 + bdgpio->gpio.get = bd71828_gpio_get; 131 + bdgpio->gpio.set = bd71828_gpio_set; 132 + bdgpio->gpio.base = -1; 133 + 134 + /* 135 + * See if we need some implementation to mark some PINs as 136 + * not controllable based on DT info or if core can handle 137 + * "gpio-reserved-ranges" and exclude them from control 138 + */ 139 + bdgpio->gpio.ngpio = 4; 140 + bdgpio->gpio.of_node = pdev->dev.parent->of_node; 141 + bdgpio->chip.regmap = bd71828->regmap; 142 + 143 + return devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio, 144 + bdgpio); 145 + } 146 + 147 + static struct platform_driver bd71828_gpio = { 148 + .driver = { 149 + .name = "bd71828-gpio" 150 + }, 151 + .probe = bd71828_probe, 152 + }; 153 + 154 + module_platform_driver(bd71828_gpio); 155 + 156 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 157 + MODULE_DESCRIPTION("BD71828 voltage regulator driver"); 158 + MODULE_LICENSE("GPL"); 159 + MODULE_ALIAS("platform:bd71828-gpio");
+15
drivers/mfd/Kconfig
··· 1906 1906 10 bits SAR ADC for battery temperature monitor and 1S battery 1907 1907 charger. 1908 1908 1909 + config MFD_ROHM_BD71828 1910 + tristate "ROHM BD71828 Power Management IC" 1911 + depends on I2C=y 1912 + depends on OF 1913 + select REGMAP_I2C 1914 + select REGMAP_IRQ 1915 + select MFD_CORE 1916 + help 1917 + Select this option to get support for the ROHM BD71828 Power 1918 + Management IC. BD71828GW is a single-chip power management IC for 1919 + battery-powered portable devices. The IC integrates 7 buck 1920 + converters, 7 LDOs, and a 1500 mA single-cell linear charger. 1921 + Also included is a Coulomb counter, a real-time clock (RTC), and 1922 + a 32.768 kHz clock gate. 1923 + 1909 1924 config MFD_STM32_LPTIMER 1910 1925 tristate "Support for STM32 Low-Power Timer" 1911 1926 depends on (ARCH_STM32 && OF) || COMPILE_TEST
+1
drivers/mfd/Makefile
··· 252 252 obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o 253 253 obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o 254 254 obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o 255 + obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o 255 256 obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o 256 257 obj-$(CONFIG_MFD_STMFX) += stmfx.o 257 258
+1 -2
drivers/mfd/rohm-bd70528.c
··· 48 48 * We use BD71837 driver to drive the clock block. Only differences to 49 49 * BD70528 clock gate are the register address and mask. 50 50 */ 51 - { .name = "bd718xx-clk", }, 51 + { .name = "bd70528-clk", }, 52 52 { .name = "bd70528-wdt", }, 53 53 { 54 54 .name = "bd70528-power", ··· 236 236 237 237 dev_set_drvdata(&i2c->dev, &bd70528->chip); 238 238 239 - bd70528->chip.chip_type = ROHM_CHIP_TYPE_BD70528; 240 239 bd70528->chip.regmap = devm_regmap_init_i2c(i2c, &bd70528_regmap); 241 240 if (IS_ERR(bd70528->chip.regmap)) { 242 241 dev_err(&i2c->dev, "Failed to initialize Regmap\n");
+344
drivers/mfd/rohm-bd71828.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // Copyright (C) 2019 ROHM Semiconductors 4 + // 5 + // ROHM BD71828 PMIC driver 6 + 7 + #include <linux/gpio_keys.h> 8 + #include <linux/i2c.h> 9 + #include <linux/input.h> 10 + #include <linux/interrupt.h> 11 + #include <linux/ioport.h> 12 + #include <linux/irq.h> 13 + #include <linux/mfd/core.h> 14 + #include <linux/mfd/rohm-bd71828.h> 15 + #include <linux/module.h> 16 + #include <linux/of_device.h> 17 + #include <linux/regmap.h> 18 + #include <linux/types.h> 19 + 20 + static struct gpio_keys_button button = { 21 + .code = KEY_POWER, 22 + .gpio = -1, 23 + .type = EV_KEY, 24 + }; 25 + 26 + static struct gpio_keys_platform_data bd71828_powerkey_data = { 27 + .buttons = &button, 28 + .nbuttons = 1, 29 + .name = "bd71828-pwrkey", 30 + }; 31 + 32 + static const struct resource rtc_irqs[] = { 33 + DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"), 34 + DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"), 35 + DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd71828-rtc-alm-2"), 36 + }; 37 + 38 + static struct mfd_cell bd71828_mfd_cells[] = { 39 + { .name = "bd71828-pmic", }, 40 + { .name = "bd71828-gpio", }, 41 + { .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" }, 42 + /* 43 + * We use BD71837 driver to drive the clock block. Only differences to 44 + * BD70528 clock gate are the register address and mask. 45 + */ 46 + { .name = "bd71828-clk", }, 47 + { .name = "bd71827-power", }, 48 + { 49 + .name = "bd71828-rtc", 50 + .resources = rtc_irqs, 51 + .num_resources = ARRAY_SIZE(rtc_irqs), 52 + }, { 53 + .name = "gpio-keys", 54 + .platform_data = &bd71828_powerkey_data, 55 + .pdata_size = sizeof(bd71828_powerkey_data), 56 + }, 57 + }; 58 + 59 + static const struct regmap_range volatile_ranges[] = { 60 + { 61 + .range_min = BD71828_REG_PS_CTRL_1, 62 + .range_max = BD71828_REG_PS_CTRL_1, 63 + }, { 64 + .range_min = BD71828_REG_PS_CTRL_3, 65 + .range_max = BD71828_REG_PS_CTRL_3, 66 + }, { 67 + .range_min = BD71828_REG_RTC_SEC, 68 + .range_max = BD71828_REG_RTC_YEAR, 69 + }, { 70 + /* 71 + * For now make all charger registers volatile because many 72 + * needs to be and because the charger block is not that 73 + * performance critical. 74 + */ 75 + .range_min = BD71828_REG_CHG_STATE, 76 + .range_max = BD71828_REG_CHG_FULL, 77 + }, { 78 + .range_min = BD71828_REG_INT_MAIN, 79 + .range_max = BD71828_REG_IO_STAT, 80 + }, 81 + }; 82 + 83 + static const struct regmap_access_table volatile_regs = { 84 + .yes_ranges = &volatile_ranges[0], 85 + .n_yes_ranges = ARRAY_SIZE(volatile_ranges), 86 + }; 87 + 88 + static struct regmap_config bd71828_regmap = { 89 + .reg_bits = 8, 90 + .val_bits = 8, 91 + .volatile_table = &volatile_regs, 92 + .max_register = BD71828_MAX_REGISTER, 93 + .cache_type = REGCACHE_RBTREE, 94 + }; 95 + 96 + /* 97 + * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can 98 + * access corect sub-IRQ registers based on bits that are set in main IRQ 99 + * register. 100 + */ 101 + 102 + static unsigned int bit0_offsets[] = {11}; /* RTC IRQ */ 103 + static unsigned int bit1_offsets[] = {10}; /* TEMP IRQ */ 104 + static unsigned int bit2_offsets[] = {6, 7, 8, 9}; /* BAT MON IRQ */ 105 + static unsigned int bit3_offsets[] = {5}; /* BAT IRQ */ 106 + static unsigned int bit4_offsets[] = {4}; /* CHG IRQ */ 107 + static unsigned int bit5_offsets[] = {3}; /* VSYS IRQ */ 108 + static unsigned int bit6_offsets[] = {1, 2}; /* DCIN IRQ */ 109 + static unsigned int bit7_offsets[] = {0}; /* BUCK IRQ */ 110 + 111 + static struct regmap_irq_sub_irq_map bd71828_sub_irq_offsets[] = { 112 + REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets), 113 + REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets), 114 + REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets), 115 + REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets), 116 + REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets), 117 + REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets), 118 + REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets), 119 + REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets), 120 + }; 121 + 122 + static struct regmap_irq bd71828_irqs[] = { 123 + REGMAP_IRQ_REG(BD71828_INT_BUCK1_OCP, 0, BD71828_INT_BUCK1_OCP_MASK), 124 + REGMAP_IRQ_REG(BD71828_INT_BUCK2_OCP, 0, BD71828_INT_BUCK2_OCP_MASK), 125 + REGMAP_IRQ_REG(BD71828_INT_BUCK3_OCP, 0, BD71828_INT_BUCK3_OCP_MASK), 126 + REGMAP_IRQ_REG(BD71828_INT_BUCK4_OCP, 0, BD71828_INT_BUCK4_OCP_MASK), 127 + REGMAP_IRQ_REG(BD71828_INT_BUCK5_OCP, 0, BD71828_INT_BUCK5_OCP_MASK), 128 + REGMAP_IRQ_REG(BD71828_INT_BUCK6_OCP, 0, BD71828_INT_BUCK6_OCP_MASK), 129 + REGMAP_IRQ_REG(BD71828_INT_BUCK7_OCP, 0, BD71828_INT_BUCK7_OCP_MASK), 130 + REGMAP_IRQ_REG(BD71828_INT_PGFAULT, 0, BD71828_INT_PGFAULT_MASK), 131 + /* DCIN1 interrupts */ 132 + REGMAP_IRQ_REG(BD71828_INT_DCIN_DET, 1, BD71828_INT_DCIN_DET_MASK), 133 + REGMAP_IRQ_REG(BD71828_INT_DCIN_RMV, 1, BD71828_INT_DCIN_RMV_MASK), 134 + REGMAP_IRQ_REG(BD71828_INT_CLPS_OUT, 1, BD71828_INT_CLPS_OUT_MASK), 135 + REGMAP_IRQ_REG(BD71828_INT_CLPS_IN, 1, BD71828_INT_CLPS_IN_MASK), 136 + /* DCIN2 interrupts */ 137 + REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2, 138 + BD71828_INT_DCIN_MON_RES_MASK), 139 + REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2, 140 + BD71828_INT_DCIN_MON_DET_MASK), 141 + REGMAP_IRQ_REG(BD71828_INT_LONGPUSH, 2, BD71828_INT_LONGPUSH_MASK), 142 + REGMAP_IRQ_REG(BD71828_INT_MIDPUSH, 2, BD71828_INT_MIDPUSH_MASK), 143 + REGMAP_IRQ_REG(BD71828_INT_SHORTPUSH, 2, BD71828_INT_SHORTPUSH_MASK), 144 + REGMAP_IRQ_REG(BD71828_INT_PUSH, 2, BD71828_INT_PUSH_MASK), 145 + REGMAP_IRQ_REG(BD71828_INT_WDOG, 2, BD71828_INT_WDOG_MASK), 146 + REGMAP_IRQ_REG(BD71828_INT_SWRESET, 2, BD71828_INT_SWRESET_MASK), 147 + /* Vsys */ 148 + REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3, 149 + BD71828_INT_VSYS_UV_RES_MASK), 150 + REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3, 151 + BD71828_INT_VSYS_UV_DET_MASK), 152 + REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3, 153 + BD71828_INT_VSYS_LOW_RES_MASK), 154 + REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3, 155 + BD71828_INT_VSYS_LOW_DET_MASK), 156 + REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3, 157 + BD71828_INT_VSYS_HALL_IN_MASK), 158 + REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3, 159 + BD71828_INT_VSYS_HALL_TOGGLE_MASK), 160 + REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3, 161 + BD71828_INT_VSYS_MON_RES_MASK), 162 + REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3, 163 + BD71828_INT_VSYS_MON_DET_MASK), 164 + /* Charger */ 165 + REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4, 166 + BD71828_INT_CHG_DCIN_ILIM_MASK), 167 + REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4, 168 + BD71828_INT_CHG_TOPOFF_TO_DONE_MASK), 169 + REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4, 170 + BD71828_INT_CHG_WDG_TEMP_MASK), 171 + REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4, 172 + BD71828_INT_CHG_WDG_TIME_MASK), 173 + REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4, 174 + BD71828_INT_CHG_RECHARGE_RES_MASK), 175 + REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4, 176 + BD71828_INT_CHG_RECHARGE_DET_MASK), 177 + REGMAP_IRQ_REG(BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 4, 178 + BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK), 179 + REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4, 180 + BD71828_INT_CHG_STATE_TRANSITION_MASK), 181 + /* Battery */ 182 + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5, 183 + BD71828_INT_BAT_TEMP_NORMAL_MASK), 184 + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5, 185 + BD71828_INT_BAT_TEMP_ERANGE_MASK), 186 + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5, 187 + BD71828_INT_BAT_TEMP_WARN_MASK), 188 + REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5, 189 + BD71828_INT_BAT_REMOVED_MASK), 190 + REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5, 191 + BD71828_INT_BAT_DETECTED_MASK), 192 + REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5, 193 + BD71828_INT_THERM_REMOVED_MASK), 194 + REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5, 195 + BD71828_INT_THERM_DETECTED_MASK), 196 + /* Battery Mon 1 */ 197 + REGMAP_IRQ_REG(BD71828_INT_BAT_DEAD, 6, BD71828_INT_BAT_DEAD_MASK), 198 + REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6, 199 + BD71828_INT_BAT_SHORTC_RES_MASK), 200 + REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6, 201 + BD71828_INT_BAT_SHORTC_DET_MASK), 202 + REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6, 203 + BD71828_INT_BAT_LOW_VOLT_RES_MASK), 204 + REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6, 205 + BD71828_INT_BAT_LOW_VOLT_DET_MASK), 206 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6, 207 + BD71828_INT_BAT_OVER_VOLT_RES_MASK), 208 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6, 209 + BD71828_INT_BAT_OVER_VOLT_DET_MASK), 210 + /* Battery Mon 2 */ 211 + REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7, 212 + BD71828_INT_BAT_MON_RES_MASK), 213 + REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7, 214 + BD71828_INT_BAT_MON_DET_MASK), 215 + /* Battery Mon 3 (Coulomb counter) */ 216 + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8, 217 + BD71828_INT_BAT_CC_MON1_MASK), 218 + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8, 219 + BD71828_INT_BAT_CC_MON2_MASK), 220 + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8, 221 + BD71828_INT_BAT_CC_MON3_MASK), 222 + /* Battery Mon 4 */ 223 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9, 224 + BD71828_INT_BAT_OVER_CURR_1_RES_MASK), 225 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9, 226 + BD71828_INT_BAT_OVER_CURR_1_DET_MASK), 227 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9, 228 + BD71828_INT_BAT_OVER_CURR_2_RES_MASK), 229 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9, 230 + BD71828_INT_BAT_OVER_CURR_2_DET_MASK), 231 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9, 232 + BD71828_INT_BAT_OVER_CURR_3_RES_MASK), 233 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9, 234 + BD71828_INT_BAT_OVER_CURR_3_DET_MASK), 235 + /* Temperature */ 236 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10, 237 + BD71828_INT_TEMP_BAT_LOW_RES_MASK), 238 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10, 239 + BD71828_INT_TEMP_BAT_LOW_DET_MASK), 240 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10, 241 + BD71828_INT_TEMP_BAT_HI_RES_MASK), 242 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10, 243 + BD71828_INT_TEMP_BAT_HI_DET_MASK), 244 + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_RES, 10, 245 + BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK), 246 + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_DET, 10, 247 + BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK), 248 + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_DET, 10, 249 + BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK), 250 + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_RES, 10, 251 + BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK), 252 + /* RTC Alarm */ 253 + REGMAP_IRQ_REG(BD71828_INT_RTC0, 11, BD71828_INT_RTC0_MASK), 254 + REGMAP_IRQ_REG(BD71828_INT_RTC1, 11, BD71828_INT_RTC1_MASK), 255 + REGMAP_IRQ_REG(BD71828_INT_RTC2, 11, BD71828_INT_RTC2_MASK), 256 + }; 257 + 258 + static struct regmap_irq_chip bd71828_irq_chip = { 259 + .name = "bd71828_irq", 260 + .main_status = BD71828_REG_INT_MAIN, 261 + .irqs = &bd71828_irqs[0], 262 + .num_irqs = ARRAY_SIZE(bd71828_irqs), 263 + .status_base = BD71828_REG_INT_BUCK, 264 + .mask_base = BD71828_REG_INT_MASK_BUCK, 265 + .ack_base = BD71828_REG_INT_BUCK, 266 + .mask_invert = true, 267 + .init_ack_masked = true, 268 + .num_regs = 12, 269 + .num_main_regs = 1, 270 + .sub_reg_offsets = &bd71828_sub_irq_offsets[0], 271 + .num_main_status_bits = 8, 272 + .irq_reg_stride = 1, 273 + }; 274 + 275 + static int bd71828_i2c_probe(struct i2c_client *i2c) 276 + { 277 + struct rohm_regmap_dev *chip; 278 + struct regmap_irq_chip_data *irq_data; 279 + int ret; 280 + 281 + if (!i2c->irq) { 282 + dev_err(&i2c->dev, "No IRQ configured\n"); 283 + return -EINVAL; 284 + } 285 + 286 + chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 287 + if (!chip) 288 + return -ENOMEM; 289 + 290 + dev_set_drvdata(&i2c->dev, chip); 291 + 292 + chip->regmap = devm_regmap_init_i2c(i2c, &bd71828_regmap); 293 + if (IS_ERR(chip->regmap)) { 294 + dev_err(&i2c->dev, "Failed to initialize Regmap\n"); 295 + return PTR_ERR(chip->regmap); 296 + } 297 + 298 + ret = devm_regmap_add_irq_chip(&i2c->dev, chip->regmap, 299 + i2c->irq, IRQF_ONESHOT, 0, 300 + &bd71828_irq_chip, &irq_data); 301 + if (ret) { 302 + dev_err(&i2c->dev, "Failed to add IRQ chip\n"); 303 + return ret; 304 + } 305 + 306 + dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n", 307 + bd71828_irq_chip.num_irqs); 308 + 309 + ret = regmap_irq_get_virq(irq_data, BD71828_INT_SHORTPUSH); 310 + if (ret < 0) { 311 + dev_err(&i2c->dev, "Failed to get the power-key IRQ\n"); 312 + return ret; 313 + } 314 + 315 + button.irq = ret; 316 + 317 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, 318 + bd71828_mfd_cells, 319 + ARRAY_SIZE(bd71828_mfd_cells), NULL, 0, 320 + regmap_irq_get_domain(irq_data)); 321 + if (ret) 322 + dev_err(&i2c->dev, "Failed to create subdevices\n"); 323 + 324 + return ret; 325 + } 326 + 327 + static const struct of_device_id bd71828_of_match[] = { 328 + { .compatible = "rohm,bd71828", }, 329 + { }, 330 + }; 331 + MODULE_DEVICE_TABLE(of, bd71828_of_match); 332 + 333 + static struct i2c_driver bd71828_drv = { 334 + .driver = { 335 + .name = "rohm-bd71828", 336 + .of_match_table = bd71828_of_match, 337 + }, 338 + .probe_new = &bd71828_i2c_probe, 339 + }; 340 + module_i2c_driver(bd71828_drv); 341 + 342 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 343 + MODULE_DESCRIPTION("ROHM BD71828 Power Management IC driver"); 344 + MODULE_LICENSE("GPL");
+36 -7
drivers/mfd/rohm-bd718x7.c
··· 30 30 .name = "bd718xx-pwrkey", 31 31 }; 32 32 33 - static struct mfd_cell bd718xx_mfd_cells[] = { 33 + static struct mfd_cell bd71837_mfd_cells[] = { 34 34 { 35 35 .name = "gpio-keys", 36 36 .platform_data = &bd718xx_powerkey_data, 37 37 .pdata_size = sizeof(bd718xx_powerkey_data), 38 38 }, 39 - { .name = "bd718xx-clk", }, 40 - { .name = "bd718xx-pmic", }, 39 + { .name = "bd71837-clk", }, 40 + { .name = "bd71837-pmic", }, 41 + }; 42 + 43 + static struct mfd_cell bd71847_mfd_cells[] = { 44 + { 45 + .name = "gpio-keys", 46 + .platform_data = &bd718xx_powerkey_data, 47 + .pdata_size = sizeof(bd718xx_powerkey_data), 48 + }, 49 + { .name = "bd71847-clk", }, 50 + { .name = "bd71847-pmic", }, 41 51 }; 42 52 43 53 static const struct regmap_irq bd718xx_irqs[] = { ··· 134 124 { 135 125 struct bd718xx *bd718xx; 136 126 int ret; 127 + unsigned int chip_type; 128 + struct mfd_cell *mfd; 129 + int cells; 137 130 138 131 if (!i2c->irq) { 139 132 dev_err(&i2c->dev, "No IRQ configured\n"); ··· 149 136 return -ENOMEM; 150 137 151 138 bd718xx->chip_irq = i2c->irq; 152 - bd718xx->chip.chip_type = (unsigned int)(uintptr_t) 153 - of_device_get_match_data(&i2c->dev); 139 + chip_type = (unsigned int)(uintptr_t) 140 + of_device_get_match_data(&i2c->dev); 141 + switch (chip_type) { 142 + case ROHM_CHIP_TYPE_BD71837: 143 + mfd = bd71837_mfd_cells; 144 + cells = ARRAY_SIZE(bd71837_mfd_cells); 145 + break; 146 + case ROHM_CHIP_TYPE_BD71847: 147 + mfd = bd71847_mfd_cells; 148 + cells = ARRAY_SIZE(bd71847_mfd_cells); 149 + break; 150 + default: 151 + dev_err(&i2c->dev, "Unknown device type"); 152 + return -EINVAL; 153 + } 154 154 bd718xx->chip.dev = &i2c->dev; 155 155 dev_set_drvdata(&i2c->dev, bd718xx); 156 156 ··· 196 170 button.irq = ret; 197 171 198 172 ret = devm_mfd_add_devices(bd718xx->chip.dev, PLATFORM_DEVID_AUTO, 199 - bd718xx_mfd_cells, 200 - ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0, 173 + mfd, cells, NULL, 0, 201 174 regmap_irq_get_domain(bd718xx->irq_data)); 202 175 if (ret) 203 176 dev_err(&i2c->dev, "Failed to create subdevices\n"); ··· 211 186 }, 212 187 { 213 188 .compatible = "rohm,bd71847", 189 + .data = (void *)ROHM_CHIP_TYPE_BD71847, 190 + }, 191 + { 192 + .compatible = "rohm,bd71850", 214 193 .data = (void *)ROHM_CHIP_TYPE_BD71847, 215 194 }, 216 195 { }
+4
drivers/regulator/Kconfig
··· 197 197 config REGULATOR_BD718XX 198 198 tristate "ROHM BD71837 Power Regulator" 199 199 depends on MFD_ROHM_BD718XX 200 + select REGULATOR_ROHM 200 201 help 201 202 This driver supports voltage regulators on ROHM BD71837 PMIC. 202 203 This will enable support for the software controllable buck ··· 790 789 help 791 790 Say y here to support the regulators found on Ricoh RN5T567, 792 791 RN5T618 or RC5T619 PMIC. 792 + 793 + config REGULATOR_ROHM 794 + tristate 793 795 794 796 config REGULATOR_RT5033 795 797 tristate "Richtek RT5033 Regulators"
+1
drivers/regulator/Makefile
··· 99 99 obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o 100 100 obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o 101 101 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o 102 + obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o 102 103 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o 103 104 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o 104 105 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
+68 -132
drivers/regulator/bd718x7-regulator.c
··· 318 318 }; 319 319 struct bd718xx_regulator_data { 320 320 struct regulator_desc desc; 321 + const struct rohm_dvs_config dvs; 321 322 const struct reg_init init; 322 323 const struct reg_init *additional_inits; 323 324 int additional_init_amnt; ··· 350 349 }, 351 350 }; 352 351 353 - #define NUM_DVS_BUCKS 4 354 - 355 - struct of_dvs_setting { 356 - const char *prop; 357 - unsigned int reg; 358 - }; 359 - 360 - static int set_dvs_levels(const struct of_dvs_setting *dvs, 361 - struct device_node *np, 362 - const struct regulator_desc *desc, 363 - struct regmap *regmap) 364 - { 365 - int ret, i; 366 - unsigned int uv; 367 - 368 - ret = of_property_read_u32(np, dvs->prop, &uv); 369 - if (ret) { 370 - if (ret != -EINVAL) 371 - return ret; 372 - return 0; 373 - } 374 - 375 - for (i = 0; i < desc->n_voltages; i++) { 376 - ret = regulator_desc_list_voltage_linear_range(desc, i); 377 - if (ret < 0) 378 - continue; 379 - if (ret == uv) { 380 - i <<= ffs(desc->vsel_mask) - 1; 381 - ret = regmap_update_bits(regmap, dvs->reg, 382 - DVS_BUCK_RUN_MASK, i); 383 - break; 384 - } 385 - } 386 - return ret; 387 - } 388 - 389 - static int buck4_set_hw_dvs_levels(struct device_node *np, 352 + static int buck_set_hw_dvs_levels(struct device_node *np, 390 353 const struct regulator_desc *desc, 391 354 struct regulator_config *cfg) 392 355 { 393 - int ret, i; 394 - const struct of_dvs_setting dvs[] = { 395 - { 396 - .prop = "rohm,dvs-run-voltage", 397 - .reg = BD71837_REG_BUCK4_VOLT_RUN, 398 - }, 399 - }; 356 + struct bd718xx_regulator_data *data; 400 357 401 - for (i = 0; i < ARRAY_SIZE(dvs); i++) { 402 - ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); 403 - if (ret) 404 - break; 405 - } 406 - return ret; 407 - } 408 - static int buck3_set_hw_dvs_levels(struct device_node *np, 409 - const struct regulator_desc *desc, 410 - struct regulator_config *cfg) 411 - { 412 - int ret, i; 413 - const struct of_dvs_setting dvs[] = { 414 - { 415 - .prop = "rohm,dvs-run-voltage", 416 - .reg = BD71837_REG_BUCK3_VOLT_RUN, 417 - }, 418 - }; 358 + data = container_of(desc, struct bd718xx_regulator_data, desc); 419 359 420 - for (i = 0; i < ARRAY_SIZE(dvs); i++) { 421 - ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); 422 - if (ret) 423 - break; 424 - } 425 - return ret; 426 - } 427 - 428 - static int buck2_set_hw_dvs_levels(struct device_node *np, 429 - const struct regulator_desc *desc, 430 - struct regulator_config *cfg) 431 - { 432 - int ret, i; 433 - const struct of_dvs_setting dvs[] = { 434 - { 435 - .prop = "rohm,dvs-run-voltage", 436 - .reg = BD718XX_REG_BUCK2_VOLT_RUN, 437 - }, 438 - { 439 - .prop = "rohm,dvs-idle-voltage", 440 - .reg = BD718XX_REG_BUCK2_VOLT_IDLE, 441 - }, 442 - }; 443 - 444 - 445 - 446 - for (i = 0; i < ARRAY_SIZE(dvs); i++) { 447 - ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); 448 - if (ret) 449 - break; 450 - } 451 - return ret; 452 - } 453 - 454 - static int buck1_set_hw_dvs_levels(struct device_node *np, 455 - const struct regulator_desc *desc, 456 - struct regulator_config *cfg) 457 - { 458 - int ret, i; 459 - const struct of_dvs_setting dvs[] = { 460 - { 461 - .prop = "rohm,dvs-run-voltage", 462 - .reg = BD718XX_REG_BUCK1_VOLT_RUN, 463 - }, 464 - { 465 - .prop = "rohm,dvs-idle-voltage", 466 - .reg = BD718XX_REG_BUCK1_VOLT_IDLE, 467 - }, 468 - { 469 - .prop = "rohm,dvs-suspend-voltage", 470 - .reg = BD718XX_REG_BUCK1_VOLT_SUSP, 471 - }, 472 - }; 473 - 474 - for (i = 0; i < ARRAY_SIZE(dvs); i++) { 475 - ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); 476 - if (ret) 477 - break; 478 - } 479 - return ret; 360 + return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap); 480 361 } 481 362 482 363 static const struct bd718xx_regulator_data bd71847_regulators[] = { ··· 379 496 .enable_reg = BD718XX_REG_BUCK1_CTRL, 380 497 .enable_mask = BD718XX_BUCK_EN, 381 498 .owner = THIS_MODULE, 382 - .of_parse_cb = buck1_set_hw_dvs_levels, 499 + .of_parse_cb = buck_set_hw_dvs_levels, 500 + }, 501 + .dvs = { 502 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 503 + ROHM_DVS_LEVEL_SUSPEND, 504 + .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 505 + .run_mask = DVS_BUCK_RUN_MASK, 506 + .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 507 + .idle_mask = DVS_BUCK_RUN_MASK, 508 + .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 509 + .suspend_mask = DVS_BUCK_RUN_MASK, 383 510 }, 384 511 .init = { 385 512 .reg = BD718XX_REG_BUCK1_CTRL, ··· 413 520 .enable_reg = BD718XX_REG_BUCK2_CTRL, 414 521 .enable_mask = BD718XX_BUCK_EN, 415 522 .owner = THIS_MODULE, 416 - .of_parse_cb = buck2_set_hw_dvs_levels, 523 + .of_parse_cb = buck_set_hw_dvs_levels, 524 + }, 525 + .dvs = { 526 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 527 + .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 528 + .run_mask = DVS_BUCK_RUN_MASK, 529 + .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 530 + .idle_mask = DVS_BUCK_RUN_MASK, 417 531 }, 418 532 .init = { 419 533 .reg = BD718XX_REG_BUCK2_CTRL, ··· 692 792 .enable_reg = BD718XX_REG_BUCK1_CTRL, 693 793 .enable_mask = BD718XX_BUCK_EN, 694 794 .owner = THIS_MODULE, 695 - .of_parse_cb = buck1_set_hw_dvs_levels, 795 + .of_parse_cb = buck_set_hw_dvs_levels, 796 + }, 797 + .dvs = { 798 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 799 + ROHM_DVS_LEVEL_SUSPEND, 800 + .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 801 + .run_mask = DVS_BUCK_RUN_MASK, 802 + .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 803 + .idle_mask = DVS_BUCK_RUN_MASK, 804 + .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 805 + .suspend_mask = DVS_BUCK_RUN_MASK, 696 806 }, 697 807 .init = { 698 808 .reg = BD718XX_REG_BUCK1_CTRL, ··· 726 816 .enable_reg = BD718XX_REG_BUCK2_CTRL, 727 817 .enable_mask = BD718XX_BUCK_EN, 728 818 .owner = THIS_MODULE, 729 - .of_parse_cb = buck2_set_hw_dvs_levels, 819 + .of_parse_cb = buck_set_hw_dvs_levels, 820 + }, 821 + .dvs = { 822 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 823 + .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 824 + .run_mask = DVS_BUCK_RUN_MASK, 825 + .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 826 + .idle_mask = DVS_BUCK_RUN_MASK, 730 827 }, 731 828 .init = { 732 829 .reg = BD718XX_REG_BUCK2_CTRL, ··· 757 840 .enable_reg = BD71837_REG_BUCK3_CTRL, 758 841 .enable_mask = BD718XX_BUCK_EN, 759 842 .owner = THIS_MODULE, 760 - .of_parse_cb = buck3_set_hw_dvs_levels, 843 + .of_parse_cb = buck_set_hw_dvs_levels, 844 + }, 845 + .dvs = { 846 + .level_map = ROHM_DVS_LEVEL_RUN, 847 + .run_reg = BD71837_REG_BUCK3_VOLT_RUN, 848 + .run_mask = DVS_BUCK_RUN_MASK, 761 849 }, 762 850 .init = { 763 851 .reg = BD71837_REG_BUCK3_CTRL, ··· 786 864 .enable_reg = BD71837_REG_BUCK4_CTRL, 787 865 .enable_mask = BD718XX_BUCK_EN, 788 866 .owner = THIS_MODULE, 789 - .of_parse_cb = buck4_set_hw_dvs_levels, 867 + .of_parse_cb = buck_set_hw_dvs_levels, 868 + }, 869 + .dvs = { 870 + .level_map = ROHM_DVS_LEVEL_RUN, 871 + .run_reg = BD71837_REG_BUCK4_VOLT_RUN, 872 + .run_mask = DVS_BUCK_RUN_MASK, 790 873 }, 791 874 .init = { 792 875 .reg = BD71837_REG_BUCK4_CTRL, ··· 1091 1164 1092 1165 int i, j, err; 1093 1166 bool use_snvs; 1167 + enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 1094 1168 1095 1169 mfd = dev_get_drvdata(pdev->dev.parent); 1096 1170 if (!mfd) { ··· 1100 1172 goto err; 1101 1173 } 1102 1174 1103 - if (mfd->chip.chip_type >= ROHM_CHIP_TYPE_AMOUNT || 1104 - !pmic_regulators[mfd->chip.chip_type].r_datas) { 1175 + if (chip >= ROHM_CHIP_TYPE_AMOUNT || chip < 0 || 1176 + !pmic_regulators[chip].r_datas) { 1105 1177 dev_err(&pdev->dev, "Unsupported chip type\n"); 1106 1178 err = -EINVAL; 1107 1179 goto err; ··· 1143 1215 } 1144 1216 } 1145 1217 1146 - for (i = 0; i < pmic_regulators[mfd->chip.chip_type].r_amount; i++) { 1218 + for (i = 0; i < pmic_regulators[chip].r_amount; i++) { 1147 1219 1148 1220 const struct regulator_desc *desc; 1149 1221 struct regulator_dev *rdev; 1150 1222 const struct bd718xx_regulator_data *r; 1151 1223 1152 - r = &pmic_regulators[mfd->chip.chip_type].r_datas[i]; 1224 + r = &pmic_regulators[chip].r_datas[i]; 1153 1225 desc = &r->desc; 1154 1226 1155 1227 config.dev = pdev->dev.parent; ··· 1209 1281 return err; 1210 1282 } 1211 1283 1284 + static const struct platform_device_id bd718x7_pmic_id[] = { 1285 + { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 }, 1286 + { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 }, 1287 + { }, 1288 + }; 1289 + MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id); 1290 + 1212 1291 static struct platform_driver bd718xx_regulator = { 1213 1292 .driver = { 1214 1293 .name = "bd718xx-pmic", 1215 1294 }, 1216 1295 .probe = bd718xx_probe, 1296 + .id_table = bd718x7_pmic_id, 1217 1297 }; 1218 1298 1219 1299 module_platform_driver(bd718xx_regulator);
+95
drivers/regulator/rohm-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2020 ROHM Semiconductors 3 + 4 + #include <linux/errno.h> 5 + #include <linux/mfd/rohm-generic.h> 6 + #include <linux/module.h> 7 + #include <linux/of.h> 8 + #include <linux/regmap.h> 9 + #include <linux/regulator/driver.h> 10 + 11 + static int set_dvs_level(const struct regulator_desc *desc, 12 + struct device_node *np, struct regmap *regmap, 13 + char *prop, unsigned int reg, unsigned int mask, 14 + unsigned int omask, unsigned int oreg) 15 + { 16 + int ret, i; 17 + uint32_t uv; 18 + 19 + ret = of_property_read_u32(np, prop, &uv); 20 + if (ret) { 21 + if (ret != -EINVAL) 22 + return ret; 23 + return 0; 24 + } 25 + 26 + if (uv == 0) { 27 + if (omask) 28 + return regmap_update_bits(regmap, oreg, omask, 0); 29 + } 30 + for (i = 0; i < desc->n_voltages; i++) { 31 + ret = regulator_desc_list_voltage_linear_range(desc, i); 32 + if (ret < 0) 33 + continue; 34 + if (ret == uv) { 35 + i <<= ffs(desc->vsel_mask) - 1; 36 + ret = regmap_update_bits(regmap, reg, mask, i); 37 + if (omask && !ret) 38 + ret = regmap_update_bits(regmap, oreg, omask, 39 + omask); 40 + break; 41 + } 42 + } 43 + return ret; 44 + } 45 + 46 + int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs, 47 + struct device_node *np, 48 + const struct regulator_desc *desc, 49 + struct regmap *regmap) 50 + { 51 + int i, ret = 0; 52 + char *prop; 53 + unsigned int reg, mask, omask, oreg = desc->enable_reg; 54 + 55 + for (i = 0; i < ROHM_DVS_LEVEL_MAX && !ret; i++) { 56 + if (dvs->level_map & (1 << i)) { 57 + switch (i + 1) { 58 + case ROHM_DVS_LEVEL_RUN: 59 + prop = "rohm,dvs-run-voltage"; 60 + reg = dvs->run_reg; 61 + mask = dvs->run_mask; 62 + omask = dvs->run_on_mask; 63 + break; 64 + case ROHM_DVS_LEVEL_IDLE: 65 + prop = "rohm,dvs-idle-voltage"; 66 + reg = dvs->idle_reg; 67 + mask = dvs->idle_mask; 68 + omask = dvs->idle_on_mask; 69 + break; 70 + case ROHM_DVS_LEVEL_SUSPEND: 71 + prop = "rohm,dvs-suspend-voltage"; 72 + reg = dvs->suspend_reg; 73 + mask = dvs->suspend_mask; 74 + omask = dvs->suspend_on_mask; 75 + break; 76 + case ROHM_DVS_LEVEL_LPSR: 77 + prop = "rohm,dvs-lpsr-voltage"; 78 + reg = dvs->lpsr_reg; 79 + mask = dvs->lpsr_mask; 80 + omask = dvs->lpsr_on_mask; 81 + break; 82 + default: 83 + return -EINVAL; 84 + } 85 + ret = set_dvs_level(desc, np, regmap, prop, reg, mask, 86 + omask, oreg); 87 + } 88 + } 89 + return ret; 90 + } 91 + EXPORT_SYMBOL(rohm_regulator_set_dvs_levels); 92 + 93 + MODULE_LICENSE("GPL v2"); 94 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 95 + MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");
+2 -1
drivers/rtc/Kconfig
··· 498 498 help 499 499 If you say Y here you will get support for the 500 500 watchdog timer in the ST M41T60 and M41T80 RTC chips series. 501 + 501 502 config RTC_DRV_BD70528 502 503 tristate "ROHM BD70528 PMIC RTC" 503 504 depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG) 504 505 help 505 506 If you say Y here you will get support for the RTC 506 - on ROHM BD70528 Power Management IC. 507 + block on ROHM BD70528 and BD71828 Power Management IC. 507 508 508 509 This driver can also be built as a module. If so, the module 509 510 will be called rtc-bd70528.
+179 -41
drivers/rtc/rtc-bd70528.c
··· 6 6 7 7 #include <linux/bcd.h> 8 8 #include <linux/mfd/rohm-bd70528.h> 9 + #include <linux/mfd/rohm-bd71828.h> 9 10 #include <linux/module.h> 10 11 #include <linux/of.h> 11 12 #include <linux/platform_device.h> ··· 16 15 /* 17 16 * We read regs RTC_SEC => RTC_YEAR 18 17 * this struct is ordered according to chip registers. 19 - * Keep it u8 only to avoid padding issues. 18 + * Keep it u8 only (or packed) to avoid padding issues. 20 19 */ 21 20 struct bd70528_rtc_day { 22 21 u8 sec; ··· 37 36 u8 ctrl; 38 37 } __packed; 39 38 39 + struct bd71828_rtc_alm { 40 + struct bd70528_rtc_data alm0; 41 + struct bd70528_rtc_data alm1; 42 + u8 alm_mask; 43 + u8 alm1_mask; 44 + } __packed; 45 + 40 46 struct bd70528_rtc_alm { 41 47 struct bd70528_rtc_data data; 42 48 u8 alm_mask; ··· 51 43 } __packed; 52 44 53 45 struct bd70528_rtc { 54 - struct rohm_regmap_dev *mfd; 46 + struct rohm_regmap_dev *parent; 55 47 struct device *dev; 48 + u8 reg_time_start; 49 + bool has_rtc_timers; 56 50 }; 57 51 58 52 static int bd70528_set_wake(struct rohm_regmap_dev *bd70528, ··· 133 123 { 134 124 int ret; 135 125 136 - ret = bd70528_wdt_set(r->mfd, new_state & BD70528_WDT_STATE_BIT, 126 + ret = bd70528_wdt_set(r->parent, new_state & BD70528_WDT_STATE_BIT, 137 127 old_state); 138 128 if (ret) { 139 129 dev_err(r->dev, 140 130 "Failed to disable WDG for RTC setting (%d)\n", ret); 141 131 return ret; 142 132 } 143 - ret = bd70528_set_elapsed_tmr(r->mfd, 133 + ret = bd70528_set_elapsed_tmr(r->parent, 144 134 new_state & BD70528_ELAPSED_STATE_BIT, 145 135 old_state); 146 136 if (ret) { ··· 148 138 "Failed to disable 'elapsed timer' for RTC setting\n"); 149 139 return ret; 150 140 } 151 - ret = bd70528_set_wake(r->mfd, new_state & BD70528_WAKE_STATE_BIT, 141 + ret = bd70528_set_wake(r->parent, new_state & BD70528_WAKE_STATE_BIT, 152 142 old_state); 153 143 if (ret) { 154 144 dev_err(r->dev, ··· 162 152 static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r, 163 153 int old_state) 164 154 { 155 + if (!r->has_rtc_timers) 156 + return 0; 157 + 165 158 return bd70528_set_rtc_based_timers(r, old_state, NULL); 166 159 } 167 160 168 161 static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r, 169 162 int *old_state) 170 163 { 164 + if (!r->has_rtc_timers) 165 + return 0; 166 + 171 167 return bd70528_set_rtc_based_timers(r, 0, old_state); 172 168 } 173 169 ··· 229 213 t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK); 230 214 } 231 215 216 + static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a) 217 + { 218 + int ret; 219 + struct bd71828_rtc_alm alm; 220 + struct bd70528_rtc *r = dev_get_drvdata(dev); 221 + struct rohm_regmap_dev *parent = r->parent; 222 + 223 + ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START, 224 + &alm, sizeof(alm)); 225 + if (ret) { 226 + dev_err(dev, "Failed to read alarm regs\n"); 227 + return ret; 228 + } 229 + 230 + tm2rtc(&a->time, &alm.alm0); 231 + 232 + if (!a->enabled) 233 + alm.alm_mask &= ~BD70528_MASK_ALM_EN; 234 + else 235 + alm.alm_mask |= BD70528_MASK_ALM_EN; 236 + 237 + ret = regmap_bulk_write(parent->regmap, BD71828_REG_RTC_ALM_START, 238 + &alm, sizeof(alm)); 239 + if (ret) 240 + dev_err(dev, "Failed to set alarm time\n"); 241 + 242 + return ret; 243 + 244 + } 245 + 232 246 static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a) 233 247 { 234 248 struct bd70528_rtc_wake wake; 235 249 struct bd70528_rtc_alm alm; 236 250 int ret; 237 251 struct bd70528_rtc *r = dev_get_drvdata(dev); 238 - struct rohm_regmap_dev *bd70528 = r->mfd; 252 + struct rohm_regmap_dev *parent = r->parent; 239 253 240 - ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_WAKE_START, 254 + ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_WAKE_START, 241 255 &wake, sizeof(wake)); 242 256 if (ret) { 243 257 dev_err(dev, "Failed to read wake regs\n"); 244 258 return ret; 245 259 } 246 260 247 - ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START, 261 + ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START, 248 262 &alm, sizeof(alm)); 249 263 if (ret) { 250 264 dev_err(dev, "Failed to read alarm regs\n"); ··· 292 246 wake.ctrl &= ~BD70528_MASK_WAKE_EN; 293 247 } 294 248 295 - ret = regmap_bulk_write(bd70528->regmap, 249 + ret = regmap_bulk_write(parent->regmap, 296 250 BD70528_REG_RTC_WAKE_START, &wake, 297 251 sizeof(wake)); 298 252 if (ret) { 299 253 dev_err(dev, "Failed to set wake time\n"); 300 254 return ret; 301 255 } 302 - ret = regmap_bulk_write(bd70528->regmap, BD70528_REG_RTC_ALM_START, 256 + ret = regmap_bulk_write(parent->regmap, BD70528_REG_RTC_ALM_START, 303 257 &alm, sizeof(alm)); 304 258 if (ret) 305 259 dev_err(dev, "Failed to set alarm time\n"); ··· 307 261 return ret; 308 262 } 309 263 264 + static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a) 265 + { 266 + int ret; 267 + struct bd71828_rtc_alm alm; 268 + struct bd70528_rtc *r = dev_get_drvdata(dev); 269 + struct rohm_regmap_dev *parent = r->parent; 270 + 271 + ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START, 272 + &alm, sizeof(alm)); 273 + if (ret) { 274 + dev_err(dev, "Failed to read alarm regs\n"); 275 + return ret; 276 + } 277 + 278 + rtc2tm(&alm.alm0, &a->time); 279 + a->time.tm_mday = -1; 280 + a->time.tm_mon = -1; 281 + a->time.tm_year = -1; 282 + a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN); 283 + a->pending = 0; 284 + 285 + return 0; 286 + } 287 + 310 288 static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a) 311 289 { 312 290 struct bd70528_rtc_alm alm; 313 291 int ret; 314 292 struct bd70528_rtc *r = dev_get_drvdata(dev); 315 - struct rohm_regmap_dev *bd70528 = r->mfd; 293 + struct rohm_regmap_dev *parent = r->parent; 316 294 317 - ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START, 295 + ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START, 318 296 &alm, sizeof(alm)); 319 297 if (ret) { 320 298 dev_err(dev, "Failed to read alarm regs\n"); ··· 360 290 int ret, tmpret, old_states; 361 291 struct bd70528_rtc_data rtc_data; 362 292 struct bd70528_rtc *r = dev_get_drvdata(dev); 363 - struct rohm_regmap_dev *bd70528 = r->mfd; 293 + struct rohm_regmap_dev *parent = r->parent; 364 294 365 295 ret = bd70528_disable_rtc_based_timers(r, &old_states); 366 296 if (ret) 367 297 return ret; 368 298 369 - tmpret = regmap_bulk_read(bd70528->regmap, 370 - BD70528_REG_RTC_START, &rtc_data, 299 + tmpret = regmap_bulk_read(parent->regmap, 300 + r->reg_time_start, &rtc_data, 371 301 sizeof(rtc_data)); 372 302 if (tmpret) { 373 303 dev_err(dev, "Failed to read RTC time registers\n"); ··· 375 305 } 376 306 tm2rtc(t, &rtc_data); 377 307 378 - tmpret = regmap_bulk_write(bd70528->regmap, 379 - BD70528_REG_RTC_START, &rtc_data, 308 + tmpret = regmap_bulk_write(parent->regmap, 309 + r->reg_time_start, &rtc_data, 380 310 sizeof(rtc_data)); 381 311 if (tmpret) { 382 312 dev_err(dev, "Failed to set RTC time\n"); ··· 391 321 return ret; 392 322 } 393 323 324 + static int bd71828_set_time(struct device *dev, struct rtc_time *t) 325 + { 326 + return bd70528_set_time_locked(dev, t); 327 + } 328 + 394 329 static int bd70528_set_time(struct device *dev, struct rtc_time *t) 395 330 { 396 331 int ret; 397 332 struct bd70528_rtc *r = dev_get_drvdata(dev); 398 333 399 - bd70528_wdt_lock(r->mfd); 334 + bd70528_wdt_lock(r->parent); 400 335 ret = bd70528_set_time_locked(dev, t); 401 - bd70528_wdt_unlock(r->mfd); 336 + bd70528_wdt_unlock(r->parent); 402 337 return ret; 403 338 } 404 339 405 340 static int bd70528_get_time(struct device *dev, struct rtc_time *t) 406 341 { 407 342 struct bd70528_rtc *r = dev_get_drvdata(dev); 408 - struct rohm_regmap_dev *bd70528 = r->mfd; 343 + struct rohm_regmap_dev *parent = r->parent; 409 344 struct bd70528_rtc_data rtc_data; 410 345 int ret; 411 346 412 347 /* read the RTC date and time registers all at once */ 413 - ret = regmap_bulk_read(bd70528->regmap, 414 - BD70528_REG_RTC_START, &rtc_data, 348 + ret = regmap_bulk_read(parent->regmap, 349 + r->reg_time_start, &rtc_data, 415 350 sizeof(rtc_data)); 416 351 if (ret) { 417 352 dev_err(dev, "Failed to read RTC time (err %d)\n", ret); ··· 437 362 if (enabled) 438 363 enableval = 0; 439 364 440 - bd70528_wdt_lock(r->mfd); 441 - ret = bd70528_set_wake(r->mfd, enabled, NULL); 365 + bd70528_wdt_lock(r->parent); 366 + ret = bd70528_set_wake(r->parent, enabled, NULL); 442 367 if (ret) { 443 368 dev_err(dev, "Failed to change wake state\n"); 444 369 goto out_unlock; 445 370 } 446 - ret = regmap_update_bits(r->mfd->regmap, BD70528_REG_RTC_ALM_MASK, 371 + ret = regmap_update_bits(r->parent->regmap, BD70528_REG_RTC_ALM_MASK, 447 372 BD70528_MASK_ALM_EN, enableval); 448 373 if (ret) 449 374 dev_err(dev, "Failed to change alarm state\n"); 450 375 451 376 out_unlock: 452 - bd70528_wdt_unlock(r->mfd); 377 + bd70528_wdt_unlock(r->parent); 378 + return ret; 379 + } 380 + 381 + static int bd71828_alm_enable(struct device *dev, unsigned int enabled) 382 + { 383 + int ret; 384 + struct bd70528_rtc *r = dev_get_drvdata(dev); 385 + unsigned int enableval = BD70528_MASK_ALM_EN; 386 + 387 + if (!enabled) 388 + enableval = 0; 389 + 390 + ret = regmap_update_bits(r->parent->regmap, BD71828_REG_RTC_ALM0_MASK, 391 + BD70528_MASK_ALM_EN, enableval); 392 + if (ret) 393 + dev_err(dev, "Failed to change alarm state\n"); 394 + 453 395 return ret; 454 396 } 455 397 ··· 476 384 .read_alarm = bd70528_read_alarm, 477 385 .set_alarm = bd70528_set_alarm, 478 386 .alarm_irq_enable = bd70528_alm_enable, 387 + }; 388 + 389 + static const struct rtc_class_ops bd71828_rtc_ops = { 390 + .read_time = bd70528_get_time, 391 + .set_time = bd71828_set_time, 392 + .read_alarm = bd71828_read_alarm, 393 + .set_alarm = bd71828_set_alarm, 394 + .alarm_irq_enable = bd71828_alm_enable, 479 395 }; 480 396 481 397 static irqreturn_t alm_hndlr(int irq, void *data) ··· 497 397 static int bd70528_probe(struct platform_device *pdev) 498 398 { 499 399 struct bd70528_rtc *bd_rtc; 500 - struct rohm_regmap_dev *mfd; 400 + const struct rtc_class_ops *rtc_ops; 401 + struct rohm_regmap_dev *parent; 402 + const char *irq_name; 501 403 int ret; 502 404 struct rtc_device *rtc; 503 405 int irq; 504 406 unsigned int hr; 407 + bool enable_main_irq = false; 408 + u8 hour_reg; 409 + enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 505 410 506 - mfd = dev_get_drvdata(pdev->dev.parent); 507 - if (!mfd) { 411 + parent = dev_get_drvdata(pdev->dev.parent); 412 + if (!parent) { 508 413 dev_err(&pdev->dev, "No MFD driver data\n"); 509 414 return -EINVAL; 510 415 } ··· 517 412 if (!bd_rtc) 518 413 return -ENOMEM; 519 414 520 - bd_rtc->mfd = mfd; 415 + bd_rtc->parent = parent; 521 416 bd_rtc->dev = &pdev->dev; 522 417 523 - irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm"); 524 - if (irq < 0) 418 + switch (chip) { 419 + case ROHM_CHIP_TYPE_BD70528: 420 + irq_name = "bd70528-rtc-alm"; 421 + bd_rtc->has_rtc_timers = true; 422 + bd_rtc->reg_time_start = BD70528_REG_RTC_START; 423 + hour_reg = BD70528_REG_RTC_HOUR; 424 + enable_main_irq = true; 425 + rtc_ops = &bd70528_rtc_ops; 426 + break; 427 + case ROHM_CHIP_TYPE_BD71828: 428 + irq_name = "bd71828-rtc-alm-0"; 429 + bd_rtc->reg_time_start = BD71828_REG_RTC_START; 430 + hour_reg = BD71828_REG_RTC_HOUR; 431 + rtc_ops = &bd71828_rtc_ops; 432 + break; 433 + default: 434 + dev_err(&pdev->dev, "Unknown chip\n"); 435 + return -ENOENT; 436 + } 437 + 438 + irq = platform_get_irq_byname(pdev, irq_name); 439 + 440 + if (irq < 0) { 441 + dev_err(&pdev->dev, "Failed to get irq\n"); 525 442 return irq; 443 + } 526 444 527 445 platform_set_drvdata(pdev, bd_rtc); 528 446 529 - ret = regmap_read(mfd->regmap, BD70528_REG_RTC_HOUR, &hr); 447 + ret = regmap_read(parent->regmap, hour_reg, &hr); 530 448 531 449 if (ret) { 532 450 dev_err(&pdev->dev, "Failed to reag RTC clock\n"); ··· 559 431 if (!(hr & BD70528_MASK_RTC_HOUR_24H)) { 560 432 struct rtc_time t; 561 433 562 - ret = bd70528_get_time(&pdev->dev, &t); 434 + ret = rtc_ops->read_time(&pdev->dev, &t); 563 435 564 436 if (!ret) 565 - ret = bd70528_set_time(&pdev->dev, &t); 437 + ret = rtc_ops->set_time(&pdev->dev, &t); 566 438 567 439 if (ret) { 568 440 dev_err(&pdev->dev, ··· 582 454 583 455 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 584 456 rtc->range_max = RTC_TIMESTAMP_END_2099; 585 - rtc->ops = &bd70528_rtc_ops; 457 + rtc->ops = rtc_ops; 586 458 587 459 /* Request alarm IRQ prior to registerig the RTC */ 588 460 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr, ··· 596 468 * leave them enabled as irq-controller should disable irqs 597 469 * from sub-registers when IRQ is disabled or freed. 598 470 */ 599 - ret = regmap_update_bits(mfd->regmap, 471 + if (enable_main_irq) { 472 + ret = regmap_update_bits(parent->regmap, 600 473 BD70528_REG_INT_MAIN_MASK, 601 474 BD70528_INT_RTC_MASK, 0); 602 - if (ret) { 603 - dev_err(&pdev->dev, "Failed to enable RTC interrupts\n"); 604 - return ret; 475 + if (ret) { 476 + dev_err(&pdev->dev, "Failed to enable RTC interrupts\n"); 477 + return ret; 478 + } 605 479 } 606 480 607 481 return rtc_register_device(rtc); 608 482 } 483 + 484 + static const struct platform_device_id bd718x7_rtc_id[] = { 485 + { "bd70528-rtc", ROHM_CHIP_TYPE_BD70528 }, 486 + { "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 }, 487 + { }, 488 + }; 489 + MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id); 609 490 610 491 static struct platform_driver bd70528_rtc = { 611 492 .driver = { 612 493 .name = "bd70528-rtc" 613 494 }, 614 495 .probe = bd70528_probe, 496 + .id_table = bd718x7_rtc_id, 615 497 }; 616 498 617 499 module_platform_driver(bd70528_rtc); 618 500 619 501 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 620 - MODULE_DESCRIPTION("BD70528 RTC driver"); 502 + MODULE_DESCRIPTION("ROHM BD70528 and BD71828 PMIC RTC driver"); 621 503 MODULE_LICENSE("GPL"); 622 504 MODULE_ALIAS("platform:bd70528-rtc");
+1 -18
include/linux/mfd/rohm-bd70528.h
··· 7 7 #include <linux/bits.h> 8 8 #include <linux/device.h> 9 9 #include <linux/mfd/rohm-generic.h> 10 + #include <linux/mfd/rohm-shared.h> 10 11 #include <linux/regmap.h> 11 12 12 13 enum { ··· 89 88 #define BD70528_REG_GPIO2_OUT 0x50 90 89 #define BD70528_REG_GPIO3_OUT 0x52 91 90 #define BD70528_REG_GPIO4_OUT 0x54 92 - 93 - /* clk control */ 94 - 95 - #define BD70528_REG_CLK_OUT 0x2c 96 91 97 92 /* RTC */ 98 93 ··· 306 309 307 310 #define BD70528_GPIO_IN_STATE_BASE 1 308 311 309 - #define BD70528_CLK_OUT_EN_MASK 0x1 310 - 311 312 /* RTC masks to mask out reserved bits */ 312 - 313 - #define BD70528_MASK_RTC_SEC 0x7f 314 - #define BD70528_MASK_RTC_MINUTE 0x7f 315 - #define BD70528_MASK_RTC_HOUR_24H 0x80 316 - #define BD70528_MASK_RTC_HOUR_PM 0x20 317 - #define BD70528_MASK_RTC_HOUR 0x1f 318 - #define BD70528_MASK_RTC_DAY 0x3f 319 - #define BD70528_MASK_RTC_WEEK 0x07 320 - #define BD70528_MASK_RTC_MONTH 0x1f 321 - #define BD70528_MASK_RTC_YEAR 0xff 322 - #define BD70528_MASK_RTC_COUNT_L 0x7f 323 313 324 314 #define BD70528_MASK_ELAPSED_TIMER_EN 0x1 325 315 /* Mask second, min and hour fields ··· 316 332 * wake-up we limit ALM to 24H and only 317 333 * unmask sec, min and hour 318 334 */ 319 - #define BD70528_MASK_ALM_EN 0x7 320 335 #define BD70528_MASK_WAKE_EN 0x1 321 336 322 337 /* WDT masks */
+423
include/linux/mfd/rohm-bd71828.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (C) 2019 ROHM Semiconductors */ 3 + 4 + #ifndef __LINUX_MFD_BD71828_H__ 5 + #define __LINUX_MFD_BD71828_H__ 6 + 7 + #include <linux/mfd/rohm-generic.h> 8 + #include <linux/mfd/rohm-shared.h> 9 + 10 + /* Regulator IDs */ 11 + enum { 12 + BD71828_BUCK1, 13 + BD71828_BUCK2, 14 + BD71828_BUCK3, 15 + BD71828_BUCK4, 16 + BD71828_BUCK5, 17 + BD71828_BUCK6, 18 + BD71828_BUCK7, 19 + BD71828_LDO1, 20 + BD71828_LDO2, 21 + BD71828_LDO3, 22 + BD71828_LDO4, 23 + BD71828_LDO5, 24 + BD71828_LDO6, 25 + BD71828_LDO_SNVS, 26 + BD71828_REGULATOR_AMOUNT, 27 + }; 28 + 29 + #define BD71828_BUCK1267_VOLTS 0xEF 30 + #define BD71828_BUCK3_VOLTS 0x10 31 + #define BD71828_BUCK4_VOLTS 0x20 32 + #define BD71828_BUCK5_VOLTS 0x10 33 + #define BD71828_LDO_VOLTS 0x32 34 + /* LDO6 is fixed 1.8V voltage */ 35 + #define BD71828_LDO_6_VOLTAGE 1800000 36 + 37 + /* Registers and masks*/ 38 + 39 + /* MODE control */ 40 + #define BD71828_REG_PS_CTRL_1 0x04 41 + #define BD71828_REG_PS_CTRL_2 0x05 42 + #define BD71828_REG_PS_CTRL_3 0x06 43 + 44 + //#define BD71828_REG_SWRESET 0x06 45 + #define BD71828_MASK_RUN_LVL_CTRL 0x30 46 + 47 + /* Regulator control masks */ 48 + 49 + #define BD71828_MASK_RAMP_DELAY 0x6 50 + 51 + #define BD71828_MASK_RUN_EN 0x08 52 + #define BD71828_MASK_SUSP_EN 0x04 53 + #define BD71828_MASK_IDLE_EN 0x02 54 + #define BD71828_MASK_LPSR_EN 0x01 55 + 56 + #define BD71828_MASK_RUN0_EN 0x01 57 + #define BD71828_MASK_RUN1_EN 0x02 58 + #define BD71828_MASK_RUN2_EN 0x04 59 + #define BD71828_MASK_RUN3_EN 0x08 60 + 61 + #define BD71828_MASK_DVS_BUCK1_CTRL 0x10 62 + #define BD71828_DVS_BUCK1_CTRL_I2C 0 63 + #define BD71828_DVS_BUCK1_USE_RUNLVL 0x10 64 + 65 + #define BD71828_MASK_DVS_BUCK2_CTRL 0x20 66 + #define BD71828_DVS_BUCK2_CTRL_I2C 0 67 + #define BD71828_DVS_BUCK2_USE_RUNLVL 0x20 68 + 69 + #define BD71828_MASK_DVS_BUCK6_CTRL 0x40 70 + #define BD71828_DVS_BUCK6_CTRL_I2C 0 71 + #define BD71828_DVS_BUCK6_USE_RUNLVL 0x40 72 + 73 + #define BD71828_MASK_DVS_BUCK7_CTRL 0x80 74 + #define BD71828_DVS_BUCK7_CTRL_I2C 0 75 + #define BD71828_DVS_BUCK7_USE_RUNLVL 0x80 76 + 77 + #define BD71828_MASK_BUCK1267_VOLT 0xff 78 + #define BD71828_MASK_BUCK3_VOLT 0x1f 79 + #define BD71828_MASK_BUCK4_VOLT 0x3f 80 + #define BD71828_MASK_BUCK5_VOLT 0x1f 81 + #define BD71828_MASK_LDO_VOLT 0x3f 82 + 83 + /* Regulator control regs */ 84 + #define BD71828_REG_BUCK1_EN 0x08 85 + #define BD71828_REG_BUCK1_CTRL 0x09 86 + #define BD71828_REG_BUCK1_MODE 0x0a 87 + #define BD71828_REG_BUCK1_IDLE_VOLT 0x0b 88 + #define BD71828_REG_BUCK1_SUSP_VOLT 0x0c 89 + #define BD71828_REG_BUCK1_VOLT 0x0d 90 + 91 + #define BD71828_REG_BUCK2_EN 0x12 92 + #define BD71828_REG_BUCK2_CTRL 0x13 93 + #define BD71828_REG_BUCK2_MODE 0x14 94 + #define BD71828_REG_BUCK2_IDLE_VOLT 0x15 95 + #define BD71828_REG_BUCK2_SUSP_VOLT 0x16 96 + #define BD71828_REG_BUCK2_VOLT 0x17 97 + 98 + #define BD71828_REG_BUCK3_EN 0x1c 99 + #define BD71828_REG_BUCK3_MODE 0x1d 100 + #define BD71828_REG_BUCK3_VOLT 0x1e 101 + 102 + #define BD71828_REG_BUCK4_EN 0x1f 103 + #define BD71828_REG_BUCK4_MODE 0x20 104 + #define BD71828_REG_BUCK4_VOLT 0x21 105 + 106 + #define BD71828_REG_BUCK5_EN 0x22 107 + #define BD71828_REG_BUCK5_MODE 0x23 108 + #define BD71828_REG_BUCK5_VOLT 0x24 109 + 110 + #define BD71828_REG_BUCK6_EN 0x25 111 + #define BD71828_REG_BUCK6_CTRL 0x26 112 + #define BD71828_REG_BUCK6_MODE 0x27 113 + #define BD71828_REG_BUCK6_IDLE_VOLT 0x28 114 + #define BD71828_REG_BUCK6_SUSP_VOLT 0x29 115 + #define BD71828_REG_BUCK6_VOLT 0x2a 116 + 117 + #define BD71828_REG_BUCK7_EN 0x2f 118 + #define BD71828_REG_BUCK7_CTRL 0x30 119 + #define BD71828_REG_BUCK7_MODE 0x31 120 + #define BD71828_REG_BUCK7_IDLE_VOLT 0x32 121 + #define BD71828_REG_BUCK7_SUSP_VOLT 0x33 122 + #define BD71828_REG_BUCK7_VOLT 0x34 123 + 124 + #define BD71828_REG_LDO1_EN 0x39 125 + #define BD71828_REG_LDO1_VOLT 0x3a 126 + #define BD71828_REG_LDO2_EN 0x3b 127 + #define BD71828_REG_LDO2_VOLT 0x3c 128 + #define BD71828_REG_LDO3_EN 0x3d 129 + #define BD71828_REG_LDO3_VOLT 0x3e 130 + #define BD71828_REG_LDO4_EN 0x3f 131 + #define BD71828_REG_LDO4_VOLT 0x40 132 + #define BD71828_REG_LDO5_EN 0x41 133 + #define BD71828_REG_LDO5_VOLT 0x43 134 + #define BD71828_REG_LDO5_VOLT_OPT 0x42 135 + #define BD71828_REG_LDO6_EN 0x44 136 + //#define BD71828_REG_LDO6_VOLT 0x4 137 + #define BD71828_REG_LDO7_EN 0x45 138 + #define BD71828_REG_LDO7_VOLT 0x46 139 + 140 + /* GPIO */ 141 + 142 + #define BD71828_GPIO_DRIVE_MASK 0x2 143 + #define BD71828_GPIO_OPEN_DRAIN 0x0 144 + #define BD71828_GPIO_PUSH_PULL 0x2 145 + #define BD71828_GPIO_OUT_HI 0x1 146 + #define BD71828_GPIO_OUT_LO 0x0 147 + #define BD71828_GPIO_OUT_MASK 0x1 148 + 149 + #define BD71828_REG_GPIO_CTRL1 0x47 150 + #define BD71828_REG_GPIO_CTRL2 0x48 151 + #define BD71828_REG_GPIO_CTRL3 0x49 152 + #define BD71828_REG_IO_STAT 0xed 153 + 154 + /* RTC */ 155 + #define BD71828_REG_RTC_SEC 0x4c 156 + #define BD71828_REG_RTC_MINUTE 0x4d 157 + #define BD71828_REG_RTC_HOUR 0x4e 158 + #define BD71828_REG_RTC_WEEK 0x4f 159 + #define BD71828_REG_RTC_DAY 0x50 160 + #define BD71828_REG_RTC_MONTH 0x51 161 + #define BD71828_REG_RTC_YEAR 0x52 162 + 163 + #define BD71828_REG_RTC_ALM0_SEC 0x53 164 + #define BD71828_REG_RTC_ALM_START BD71828_REG_RTC_ALM0_SEC 165 + #define BD71828_REG_RTC_ALM0_MINUTE 0x54 166 + #define BD71828_REG_RTC_ALM0_HOUR 0x55 167 + #define BD71828_REG_RTC_ALM0_WEEK 0x56 168 + #define BD71828_REG_RTC_ALM0_DAY 0x57 169 + #define BD71828_REG_RTC_ALM0_MONTH 0x58 170 + #define BD71828_REG_RTC_ALM0_YEAR 0x59 171 + #define BD71828_REG_RTC_ALM0_MASK 0x61 172 + 173 + #define BD71828_REG_RTC_ALM1_SEC 0x5a 174 + #define BD71828_REG_RTC_ALM1_MINUTE 0x5b 175 + #define BD71828_REG_RTC_ALM1_HOUR 0x5c 176 + #define BD71828_REG_RTC_ALM1_WEEK 0x5d 177 + #define BD71828_REG_RTC_ALM1_DAY 0x5e 178 + #define BD71828_REG_RTC_ALM1_MONTH 0x5f 179 + #define BD71828_REG_RTC_ALM1_YEAR 0x60 180 + #define BD71828_REG_RTC_ALM1_MASK 0x62 181 + 182 + #define BD71828_REG_RTC_ALM2 0x63 183 + #define BD71828_REG_RTC_START BD71828_REG_RTC_SEC 184 + 185 + /* Charger/Battey */ 186 + #define BD71828_REG_CHG_STATE 0x65 187 + #define BD71828_REG_CHG_FULL 0xd2 188 + 189 + /* LEDs */ 190 + #define BD71828_REG_LED_CTRL 0x4A 191 + #define BD71828_MASK_LED_AMBER 0x80 192 + #define BD71828_MASK_LED_GREEN 0x40 193 + #define BD71828_LED_ON 0xff 194 + #define BD71828_LED_OFF 0x0 195 + 196 + /* IRQ registers */ 197 + #define BD71828_REG_INT_MASK_BUCK 0xd3 198 + #define BD71828_REG_INT_MASK_DCIN1 0xd4 199 + #define BD71828_REG_INT_MASK_DCIN2 0xd5 200 + #define BD71828_REG_INT_MASK_VSYS 0xd6 201 + #define BD71828_REG_INT_MASK_CHG 0xd7 202 + #define BD71828_REG_INT_MASK_BAT 0xd8 203 + #define BD71828_REG_INT_MASK_BAT_MON1 0xd9 204 + #define BD71828_REG_INT_MASK_BAT_MON2 0xda 205 + #define BD71828_REG_INT_MASK_BAT_MON3 0xdb 206 + #define BD71828_REG_INT_MASK_BAT_MON4 0xdc 207 + #define BD71828_REG_INT_MASK_TEMP 0xdd 208 + #define BD71828_REG_INT_MASK_RTC 0xde 209 + 210 + #define BD71828_REG_INT_MAIN 0xdf 211 + #define BD71828_REG_INT_BUCK 0xe0 212 + #define BD71828_REG_INT_DCIN1 0xe1 213 + #define BD71828_REG_INT_DCIN2 0xe2 214 + #define BD71828_REG_INT_VSYS 0xe3 215 + #define BD71828_REG_INT_CHG 0xe4 216 + #define BD71828_REG_INT_BAT 0xe5 217 + #define BD71828_REG_INT_BAT_MON1 0xe6 218 + #define BD71828_REG_INT_BAT_MON2 0xe7 219 + #define BD71828_REG_INT_BAT_MON3 0xe8 220 + #define BD71828_REG_INT_BAT_MON4 0xe9 221 + #define BD71828_REG_INT_TEMP 0xea 222 + #define BD71828_REG_INT_RTC 0xeb 223 + #define BD71828_REG_INT_UPDATE 0xec 224 + 225 + #define BD71828_MAX_REGISTER BD71828_REG_IO_STAT 226 + 227 + /* Masks for main IRQ register bits */ 228 + enum { 229 + BD71828_INT_BUCK, 230 + #define BD71828_INT_BUCK_MASK BIT(BD71828_INT_BUCK) 231 + BD71828_INT_DCIN, 232 + #define BD71828_INT_DCIN_MASK BIT(BD71828_INT_DCIN) 233 + BD71828_INT_VSYS, 234 + #define BD71828_INT_VSYS_MASK BIT(BD71828_INT_VSYS) 235 + BD71828_INT_CHG, 236 + #define BD71828_INT_CHG_MASK BIT(BD71828_INT_CHG) 237 + BD71828_INT_BAT, 238 + #define BD71828_INT_BAT_MASK BIT(BD71828_INT_BAT) 239 + BD71828_INT_BAT_MON, 240 + #define BD71828_INT_BAT_MON_MASK BIT(BD71828_INT_BAT_MON) 241 + BD71828_INT_TEMP, 242 + #define BD71828_INT_TEMP_MASK BIT(BD71828_INT_TEMP) 243 + BD71828_INT_RTC, 244 + #define BD71828_INT_RTC_MASK BIT(BD71828_INT_RTC) 245 + }; 246 + 247 + /* Interrupts */ 248 + enum { 249 + /* BUCK reg interrupts */ 250 + BD71828_INT_BUCK1_OCP, 251 + BD71828_INT_BUCK2_OCP, 252 + BD71828_INT_BUCK3_OCP, 253 + BD71828_INT_BUCK4_OCP, 254 + BD71828_INT_BUCK5_OCP, 255 + BD71828_INT_BUCK6_OCP, 256 + BD71828_INT_BUCK7_OCP, 257 + BD71828_INT_PGFAULT, 258 + /* DCIN1 interrupts */ 259 + BD71828_INT_DCIN_DET, 260 + BD71828_INT_DCIN_RMV, 261 + BD71828_INT_CLPS_OUT, 262 + BD71828_INT_CLPS_IN, 263 + /* DCIN2 interrupts */ 264 + BD71828_INT_DCIN_MON_RES, 265 + BD71828_INT_DCIN_MON_DET, 266 + BD71828_INT_LONGPUSH, 267 + BD71828_INT_MIDPUSH, 268 + BD71828_INT_SHORTPUSH, 269 + BD71828_INT_PUSH, 270 + BD71828_INT_WDOG, 271 + BD71828_INT_SWRESET, 272 + /* Vsys */ 273 + BD71828_INT_VSYS_UV_RES, 274 + BD71828_INT_VSYS_UV_DET, 275 + BD71828_INT_VSYS_LOW_RES, 276 + BD71828_INT_VSYS_LOW_DET, 277 + BD71828_INT_VSYS_HALL_IN, 278 + BD71828_INT_VSYS_HALL_TOGGLE, 279 + BD71828_INT_VSYS_MON_RES, 280 + BD71828_INT_VSYS_MON_DET, 281 + /* Charger */ 282 + BD71828_INT_CHG_DCIN_ILIM, 283 + BD71828_INT_CHG_TOPOFF_TO_DONE, 284 + BD71828_INT_CHG_WDG_TEMP, 285 + BD71828_INT_CHG_WDG_TIME, 286 + BD71828_INT_CHG_RECHARGE_RES, 287 + BD71828_INT_CHG_RECHARGE_DET, 288 + BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 289 + BD71828_INT_CHG_STATE_TRANSITION, 290 + /* Battery */ 291 + BD71828_INT_BAT_TEMP_NORMAL, 292 + BD71828_INT_BAT_TEMP_ERANGE, 293 + BD71828_INT_BAT_TEMP_WARN, 294 + BD71828_INT_BAT_REMOVED, 295 + BD71828_INT_BAT_DETECTED, 296 + BD71828_INT_THERM_REMOVED, 297 + BD71828_INT_THERM_DETECTED, 298 + /* Battery Mon 1 */ 299 + BD71828_INT_BAT_DEAD, 300 + BD71828_INT_BAT_SHORTC_RES, 301 + BD71828_INT_BAT_SHORTC_DET, 302 + BD71828_INT_BAT_LOW_VOLT_RES, 303 + BD71828_INT_BAT_LOW_VOLT_DET, 304 + BD71828_INT_BAT_OVER_VOLT_RES, 305 + BD71828_INT_BAT_OVER_VOLT_DET, 306 + /* Battery Mon 2 */ 307 + BD71828_INT_BAT_MON_RES, 308 + BD71828_INT_BAT_MON_DET, 309 + /* Battery Mon 3 (Coulomb counter) */ 310 + BD71828_INT_BAT_CC_MON1, 311 + BD71828_INT_BAT_CC_MON2, 312 + BD71828_INT_BAT_CC_MON3, 313 + /* Battery Mon 4 */ 314 + BD71828_INT_BAT_OVER_CURR_1_RES, 315 + BD71828_INT_BAT_OVER_CURR_1_DET, 316 + BD71828_INT_BAT_OVER_CURR_2_RES, 317 + BD71828_INT_BAT_OVER_CURR_2_DET, 318 + BD71828_INT_BAT_OVER_CURR_3_RES, 319 + BD71828_INT_BAT_OVER_CURR_3_DET, 320 + /* Temperature */ 321 + BD71828_INT_TEMP_BAT_LOW_RES, 322 + BD71828_INT_TEMP_BAT_LOW_DET, 323 + BD71828_INT_TEMP_BAT_HI_RES, 324 + BD71828_INT_TEMP_BAT_HI_DET, 325 + BD71828_INT_TEMP_CHIP_OVER_125_RES, 326 + BD71828_INT_TEMP_CHIP_OVER_125_DET, 327 + BD71828_INT_TEMP_CHIP_OVER_VF_DET, 328 + BD71828_INT_TEMP_CHIP_OVER_VF_RES, 329 + /* RTC Alarm */ 330 + BD71828_INT_RTC0, 331 + BD71828_INT_RTC1, 332 + BD71828_INT_RTC2, 333 + }; 334 + 335 + #define BD71828_INT_BUCK1_OCP_MASK 0x1 336 + #define BD71828_INT_BUCK2_OCP_MASK 0x2 337 + #define BD71828_INT_BUCK3_OCP_MASK 0x4 338 + #define BD71828_INT_BUCK4_OCP_MASK 0x8 339 + #define BD71828_INT_BUCK5_OCP_MASK 0x10 340 + #define BD71828_INT_BUCK6_OCP_MASK 0x20 341 + #define BD71828_INT_BUCK7_OCP_MASK 0x40 342 + #define BD71828_INT_PGFAULT_MASK 0x80 343 + 344 + #define BD71828_INT_DCIN_DET_MASK 0x1 345 + #define BD71828_INT_DCIN_RMV_MASK 0x2 346 + #define BD71828_INT_CLPS_OUT_MASK 0x4 347 + #define BD71828_INT_CLPS_IN_MASK 0x8 348 + /* DCIN2 interrupts */ 349 + #define BD71828_INT_DCIN_MON_RES_MASK 0x1 350 + #define BD71828_INT_DCIN_MON_DET_MASK 0x2 351 + #define BD71828_INT_LONGPUSH_MASK 0x4 352 + #define BD71828_INT_MIDPUSH_MASK 0x8 353 + #define BD71828_INT_SHORTPUSH_MASK 0x10 354 + #define BD71828_INT_PUSH_MASK 0x20 355 + #define BD71828_INT_WDOG_MASK 0x40 356 + #define BD71828_INT_SWRESET_MASK 0x80 357 + /* Vsys */ 358 + #define BD71828_INT_VSYS_UV_RES_MASK 0x1 359 + #define BD71828_INT_VSYS_UV_DET_MASK 0x2 360 + #define BD71828_INT_VSYS_LOW_RES_MASK 0x4 361 + #define BD71828_INT_VSYS_LOW_DET_MASK 0x8 362 + #define BD71828_INT_VSYS_HALL_IN_MASK 0x10 363 + #define BD71828_INT_VSYS_HALL_TOGGLE_MASK 0x20 364 + #define BD71828_INT_VSYS_MON_RES_MASK 0x40 365 + #define BD71828_INT_VSYS_MON_DET_MASK 0x80 366 + /* Charger */ 367 + #define BD71828_INT_CHG_DCIN_ILIM_MASK 0x1 368 + #define BD71828_INT_CHG_TOPOFF_TO_DONE_MASK 0x2 369 + #define BD71828_INT_CHG_WDG_TEMP_MASK 0x4 370 + #define BD71828_INT_CHG_WDG_TIME_MASK 0x8 371 + #define BD71828_INT_CHG_RECHARGE_RES_MASK 0x10 372 + #define BD71828_INT_CHG_RECHARGE_DET_MASK 0x20 373 + #define BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK 0x40 374 + #define BD71828_INT_CHG_STATE_TRANSITION_MASK 0x80 375 + /* Battery */ 376 + #define BD71828_INT_BAT_TEMP_NORMAL_MASK 0x1 377 + #define BD71828_INT_BAT_TEMP_ERANGE_MASK 0x2 378 + #define BD71828_INT_BAT_TEMP_WARN_MASK 0x4 379 + #define BD71828_INT_BAT_REMOVED_MASK 0x10 380 + #define BD71828_INT_BAT_DETECTED_MASK 0x20 381 + #define BD71828_INT_THERM_REMOVED_MASK 0x40 382 + #define BD71828_INT_THERM_DETECTED_MASK 0x80 383 + /* Battery Mon 1 */ 384 + #define BD71828_INT_BAT_DEAD_MASK 0x2 385 + #define BD71828_INT_BAT_SHORTC_RES_MASK 0x4 386 + #define BD71828_INT_BAT_SHORTC_DET_MASK 0x8 387 + #define BD71828_INT_BAT_LOW_VOLT_RES_MASK 0x10 388 + #define BD71828_INT_BAT_LOW_VOLT_DET_MASK 0x20 389 + #define BD71828_INT_BAT_OVER_VOLT_RES_MASK 0x40 390 + #define BD71828_INT_BAT_OVER_VOLT_DET_MASK 0x80 391 + /* Battery Mon 2 */ 392 + #define BD71828_INT_BAT_MON_RES_MASK 0x1 393 + #define BD71828_INT_BAT_MON_DET_MASK 0x2 394 + /* Battery Mon 3 (Coulomb counter) */ 395 + #define BD71828_INT_BAT_CC_MON1_MASK 0x1 396 + #define BD71828_INT_BAT_CC_MON2_MASK 0x2 397 + #define BD71828_INT_BAT_CC_MON3_MASK 0x4 398 + /* Battery Mon 4 */ 399 + #define BD71828_INT_BAT_OVER_CURR_1_RES_MASK 0x1 400 + #define BD71828_INT_BAT_OVER_CURR_1_DET_MASK 0x2 401 + #define BD71828_INT_BAT_OVER_CURR_2_RES_MASK 0x4 402 + #define BD71828_INT_BAT_OVER_CURR_2_DET_MASK 0x8 403 + #define BD71828_INT_BAT_OVER_CURR_3_RES_MASK 0x10 404 + #define BD71828_INT_BAT_OVER_CURR_3_DET_MASK 0x20 405 + /* Temperature */ 406 + #define BD71828_INT_TEMP_BAT_LOW_RES_MASK 0x1 407 + #define BD71828_INT_TEMP_BAT_LOW_DET_MASK 0x2 408 + #define BD71828_INT_TEMP_BAT_HI_RES_MASK 0x4 409 + #define BD71828_INT_TEMP_BAT_HI_DET_MASK 0x8 410 + #define BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK 0x10 411 + #define BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK 0x20 412 + #define BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK 0x40 413 + #define BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK 0x80 414 + /* RTC Alarm */ 415 + #define BD71828_INT_RTC0_MASK 0x1 416 + #define BD71828_INT_RTC1_MASK 0x2 417 + #define BD71828_INT_RTC2_MASK 0x4 418 + 419 + #define BD71828_OUT_TYPE_MASK 0x2 420 + #define BD71828_OUT_TYPE_OPEN_DRAIN 0x0 421 + #define BD71828_OUT_TYPE_CMOS 0x2 422 + 423 + #endif /* __LINUX_MFD_BD71828_H__ */
-6
include/linux/mfd/rohm-bd718x7.h
··· 191 191 #define IRQ_ON_REQ 0x02 192 192 #define IRQ_STBY_REQ 0x01 193 193 194 - /* BD718XX_REG_OUT32K bits */ 195 - #define BD718XX_OUT32K_EN 0x01 196 - 197 - /* BD7183XX gated clock rate */ 198 - #define BD718XX_CLK_RATE 32768 199 - 200 194 /* ROHM BD718XX irqs */ 201 195 enum { 202 196 BD718XX_INT_STBY_REQ,
+68 -2
include/linux/mfd/rohm-generic.h
··· 4 4 #ifndef __LINUX_MFD_ROHM_H__ 5 5 #define __LINUX_MFD_ROHM_H__ 6 6 7 - enum { 7 + #include <linux/regmap.h> 8 + #include <linux/regulator/driver.h> 9 + 10 + enum rohm_chip_type { 8 11 ROHM_CHIP_TYPE_BD71837 = 0, 9 12 ROHM_CHIP_TYPE_BD71847, 10 13 ROHM_CHIP_TYPE_BD70528, 14 + ROHM_CHIP_TYPE_BD71828, 11 15 ROHM_CHIP_TYPE_AMOUNT 12 16 }; 13 17 14 18 struct rohm_regmap_dev { 15 - unsigned int chip_type; 16 19 struct device *dev; 17 20 struct regmap *regmap; 18 21 }; 22 + 23 + enum { 24 + ROHM_DVS_LEVEL_UNKNOWN, 25 + ROHM_DVS_LEVEL_RUN, 26 + ROHM_DVS_LEVEL_IDLE, 27 + ROHM_DVS_LEVEL_SUSPEND, 28 + ROHM_DVS_LEVEL_LPSR, 29 + ROHM_DVS_LEVEL_MAX = ROHM_DVS_LEVEL_LPSR, 30 + }; 31 + 32 + /** 33 + * struct rohm_dvs_config - dynamic voltage scaling register descriptions 34 + * 35 + * @level_map: bitmap representing supported run-levels for this 36 + * regulator 37 + * @run_reg: register address for regulator config at 'run' state 38 + * @run_mask: value mask for regulator voltages at 'run' state 39 + * @run_on_mask: enable mask for regulator at 'run' state 40 + * @idle_reg: register address for regulator config at 'idle' state 41 + * @idle_mask: value mask for regulator voltages at 'idle' state 42 + * @idle_on_mask: enable mask for regulator at 'idle' state 43 + * @suspend_reg: register address for regulator config at 'suspend' state 44 + * @suspend_mask: value mask for regulator voltages at 'suspend' state 45 + * @suspend_on_mask: enable mask for regulator at 'suspend' state 46 + * @lpsr_reg: register address for regulator config at 'lpsr' state 47 + * @lpsr_mask: value mask for regulator voltages at 'lpsr' state 48 + * @lpsr_on_mask: enable mask for regulator at 'lpsr' state 49 + * 50 + * Description of ROHM PMICs voltage configuration registers for different 51 + * system states. This is used to correctly configure the PMIC at startup 52 + * based on values read from DT. 53 + */ 54 + struct rohm_dvs_config { 55 + uint64_t level_map; 56 + unsigned int run_reg; 57 + unsigned int run_mask; 58 + unsigned int run_on_mask; 59 + unsigned int idle_reg; 60 + unsigned int idle_mask; 61 + unsigned int idle_on_mask; 62 + unsigned int suspend_reg; 63 + unsigned int suspend_mask; 64 + unsigned int suspend_on_mask; 65 + unsigned int lpsr_reg; 66 + unsigned int lpsr_mask; 67 + unsigned int lpsr_on_mask; 68 + }; 69 + 70 + #if IS_ENABLED(CONFIG_REGULATOR_ROHM) 71 + int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs, 72 + struct device_node *np, 73 + const struct regulator_desc *desc, 74 + struct regmap *regmap); 75 + 76 + #else 77 + static inline int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs, 78 + struct device_node *np, 79 + const struct regulator_desc *desc, 80 + struct regmap *regmap) 81 + { 82 + return 0; 83 + } 84 + #endif 19 85 20 86 #endif
+21
include/linux/mfd/rohm-shared.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (C) 2020 ROHM Semiconductors */ 3 + 4 + 5 + #ifndef __LINUX_MFD_ROHM_SHARED_H__ 6 + #define __LINUX_MFD_ROHM_SHARED_H__ 7 + 8 + /* RTC definitions shared between BD70528 and BD71828 */ 9 + 10 + #define BD70528_MASK_RTC_SEC 0x7f 11 + #define BD70528_MASK_RTC_MINUTE 0x7f 12 + #define BD70528_MASK_RTC_HOUR_24H 0x80 13 + #define BD70528_MASK_RTC_HOUR_PM 0x20 14 + #define BD70528_MASK_RTC_HOUR 0x3f 15 + #define BD70528_MASK_RTC_DAY 0x3f 16 + #define BD70528_MASK_RTC_WEEK 0x07 17 + #define BD70528_MASK_RTC_MONTH 0x1f 18 + #define BD70528_MASK_RTC_YEAR 0xff 19 + #define BD70528_MASK_ALM_EN 0x7 20 + 21 + #endif /* __LINUX_MFD_ROHM_SHARED_H__ */