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

Configure Feed

Select the types of activity you want to include in your feed.

Add support for MAX77675 device

Merge series from Joan Na <joan.na@analog.com>:

MAX77675 regulator driver and device tree bindings

+1250
+184
Documentation/devicetree/bindings/regulator/adi,max77675.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/adi,max77675.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Maxim MAX77675 PMIC Regulator 8 + 9 + maintainers: 10 + - Joan Na <joan.na@analog.com> 11 + 12 + description: 13 + The MAX77675 is a Power Management IC providing four switching buck 14 + regulators (SBB0–SBB3) accessible via I2C. It supports configuration 15 + of output voltages and enable controls for each regulator. 16 + 17 + allOf: 18 + - $ref: /schemas/input/input.yaml 19 + - $ref: /schemas/pinctrl/pincfg-node.yaml 20 + 21 + properties: 22 + compatible: 23 + const: adi,max77675 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + reset-time-sec: 29 + description: Manual reset time in seconds 30 + enum: [4, 8, 12, 16] 31 + default: 4 32 + 33 + bias-disable: 34 + type: boolean 35 + description: Disable internal pull-up for EN pin 36 + 37 + input-debounce: 38 + description: Debounce time for the enable pin, in microseconds 39 + items: 40 + - enum: [100, 30000] 41 + default: 100 42 + 43 + adi,en-mode: 44 + description: | 45 + Enable mode configuration. 46 + The debounce time set by 'input-debounce' applies to 47 + both push-button and slide-switch modes. 48 + "push-button" - A long press triggers power-on or power-down 49 + "slide-switch" - Low : powers on, High : powers down 50 + "logic" - Low : powers on, High : powers down (no debounce time) 51 + $ref: /schemas/types.yaml#/definitions/string 52 + enum: [push-button, slide-switch, logic] 53 + default: slide-switch 54 + 55 + adi,voltage-change-latency-us: 56 + description: 57 + Specifies the delay (in microseconds) between an output voltage change 58 + request and the start of the SBB voltage ramp. 59 + enum: [10, 100] 60 + default: 100 61 + 62 + adi,drv-sbb-strength: 63 + description: | 64 + SIMO Buck-Boost Drive Strength Trim. 65 + Controls the drive strength of the SIMO regulator's power MOSFETs. 66 + This setting affects switching speed, impacting power efficiency and EMI. 67 + "max" – Maximum drive strength (~0.6 ns transition time) 68 + "high" – High drive strength (~1.2 ns transition time) 69 + "low" – Low drive strength (~1.8 ns transition time) 70 + "min" – Minimum drive strength (~8 ns transition time) 71 + $ref: /schemas/types.yaml#/definitions/string 72 + enum: [max, high, low, min] 73 + default: max 74 + 75 + adi,dvs-slew-rate-mv-per-us: 76 + description: 77 + Dynamic rising slew rate for output voltage transitions, in mV/μs. 78 + This setting is only used when 'adi,fixed-slew-rate' is not present. 79 + enum: [5, 10] 80 + default: 5 81 + 82 + adi,bias-low-power-request: 83 + type: boolean 84 + description: Request low-power bias mode 85 + 86 + adi,simo-ldo-always-on: 87 + type: boolean 88 + description: Set internal LDO to always supply 1.8V 89 + 90 + regulators: 91 + type: object 92 + description: Regulator child nodes 93 + patternProperties: 94 + "^sbb[0-3]$": 95 + type: object 96 + $ref: regulator.yaml# 97 + properties: 98 + adi,fps-slot: 99 + description: | 100 + FPS (Flexible Power Sequencer) slot selection. 101 + The Flexible Power Sequencer allows resources to power up under 102 + hardware or software control. Additionally, each resource can 103 + power up independently or among a group of other regulators with 104 + adjustable power-up and power-down slots. 105 + "slot0" - Assign to FPS Slot 0 106 + "slot1" - Assign to FPS Slot 1 107 + "slot2" - Assign to FPS Slot 2 108 + "slot3" - Assign to FPS Slot 3 109 + "default" - Use the default FPS slot value stored in register 110 + $ref: /schemas/types.yaml#/definitions/string 111 + enum: [slot0, slot1, slot2, slot3, default] 112 + default: default 113 + 114 + adi,fixed-slew-rate: 115 + type: boolean 116 + description: 117 + When this property is present, the device uses a constant 2 mV/μs 118 + slew rate and ignores any dynamic slew rate configuration. 119 + When absent, the device uses the dynamic slew rate specified 120 + by 'adi,dvs-slew-rate-mv-per-us' 121 + 122 + unevaluatedProperties: false 123 + 124 + required: 125 + - compatible 126 + - reg 127 + - regulators 128 + 129 + additionalProperties: false 130 + 131 + examples: 132 + - | 133 + i2c { 134 + #address-cells = <1>; 135 + #size-cells = <0>; 136 + 137 + max77675: pmic@44 { 138 + compatible = "adi,max77675"; 139 + reg = <0x44>; 140 + 141 + reset-time-sec = <4>; 142 + input-debounce = <100>; 143 + 144 + adi,en-mode = "slide-switch"; 145 + adi,voltage-change-latency-us = <100>; 146 + adi,drv-sbb-strength = "max"; 147 + adi,dvs-slew-rate-mv-per-us = <5>; 148 + 149 + regulators { 150 + sbb0: sbb0 { 151 + regulator-name = "sbb0"; 152 + regulator-min-microvolt = <500000>; 153 + regulator-max-microvolt = <5500000>; 154 + adi,fps-slot = "default"; 155 + adi,fixed-slew-rate; 156 + }; 157 + 158 + sbb1: sbb1 { 159 + regulator-name = "sbb1"; 160 + regulator-min-microvolt = <500000>; 161 + regulator-max-microvolt = <5500000>; 162 + adi,fps-slot = "default"; 163 + adi,fixed-slew-rate; 164 + }; 165 + 166 + sbb2: sbb2 { 167 + regulator-name = "sbb2"; 168 + regulator-min-microvolt = <500000>; 169 + regulator-max-microvolt = <5500000>; 170 + adi,fps-slot = "default"; 171 + adi,fixed-slew-rate; 172 + }; 173 + 174 + sbb3: sbb3 { 175 + regulator-name = "sbb3"; 176 + regulator-min-microvolt = <500000>; 177 + regulator-max-microvolt = <5500000>; 178 + adi,fps-slot = "default"; 179 + adi,fixed-slew-rate; 180 + }; 181 + }; 182 + }; 183 + }; 184 +
+9
drivers/regulator/Kconfig
··· 659 659 Semiconductor. This device has a SIMO with three independent 660 660 power rails and an LDO. 661 661 662 + config REGULATOR_MAX77675 663 + tristate "Maxim MAX77675 regulator driver" 664 + depends on I2C && OF 665 + select REGMAP_I2C 666 + help 667 + This driver controls the Maxim MAX77675 power regulator via I2C. 668 + It supports four programmable buck-boost outputs. 669 + Say Y here to enable the regulator driver 670 + 662 671 config REGULATOR_MAX77857 663 672 tristate "ADI MAX77857/MAX77831 regulator support" 664 673 depends on I2C
+1
drivers/regulator/Makefile
··· 79 79 obj-$(CONFIG_REGULATOR_MAX77541) += max77541-regulator.o 80 80 obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o 81 81 obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o 82 + obj-$(CONFIG_REGULATOR_MAX77675) += max77675-regulator.o 82 83 obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o 83 84 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 84 85 obj-$(CONFIG_REGULATOR_MAX8893) += max8893.o
+1056
drivers/regulator/max77675-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (c) 2025 Analog Devices, Inc. 4 + * ADI regulator driver for MAX77675. 5 + */ 6 + 7 + #include <linux/module.h> 8 + #include <linux/mod_devicetable.h> 9 + #include <linux/cleanup.h> 10 + #include <linux/slab.h> 11 + #include <linux/of.h> 12 + #include <linux/i2c.h> 13 + #include <linux/regmap.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/regulator/driver.h> 16 + #include <linux/regulator/consumer.h> 17 + #include <linux/regulator/of_regulator.h> 18 + #include <linux/bitfield.h> 19 + #include <linux/bitops.h> 20 + 21 + /* Register Addresses */ 22 + #define MAX77675_REG_CNFG_GLBL_A 0x00 23 + #define MAX77675_REG_CNFG_GLBL_B 0x01 24 + #define MAX77675_REG_INT_GLBL 0x02 25 + #define MAX77675_REG_INTM_GLBL 0x03 26 + #define MAX77675_REG_STAT_GLBL 0x04 27 + #define MAX77675_REG_ERCF_GLBL 0x05 28 + #define MAX77675_REG_CID 0x06 29 + #define MAX77675_REG_CNFG_SBB_TOP_A 0x07 30 + #define MAX77675_REG_CNFG_SBB0_A 0x08 31 + #define MAX77675_REG_CNFG_SBB0_B 0x09 32 + #define MAX77675_REG_CNFG_SBB1_A 0x0A 33 + #define MAX77675_REG_CNFG_SBB1_B 0x0B 34 + #define MAX77675_REG_CNFG_SBB2_A 0x0C 35 + #define MAX77675_REG_CNFG_SBB2_B 0x0D 36 + #define MAX77675_REG_CNFG_SBB3_A 0x0E 37 + #define MAX77675_REG_CNFG_SBB3_B 0x0F 38 + #define MAX77675_REG_CNFG_SBB_TOP_B 0x10 39 + 40 + /* CNFG_GLBL_A (0x00) bit masks and shifts */ 41 + #define MAX77675_MRT_MASK GENMASK(7, 6) /* Manual Reset Time (bits 7:6) */ 42 + #define MAX77675_MRT_SHIFT 6 43 + #define MAX77675_PU_DIS_BIT BIT(5) /* Pullup Disable (bit 5) */ 44 + #define MAX77675_PU_DIS_SHIFT 5 45 + #define MAX77675_BIAS_LPM_BIT BIT(4) /* Bias Low Power Mode (bit 4) */ 46 + #define MAX77675_BIAS_LPM_SHIFT 4 47 + #define MAX77675_SIMO_CH_DIS_BIT BIT(3) /* SIMO Internal Channel Disable (bit 3) */ 48 + #define MAX77675_SIMO_CH_DIS_SHIFT 3 49 + #define MAX77675_EN_MODE_MASK GENMASK(2, 1) /* nEN Mode (bits 2:1) */ 50 + #define MAX77675_EN_MODE_SHIFT 1 51 + #define MAX77675_DBEN_EN_BIT BIT(0) /* Debounce Enable (bit 0) */ 52 + #define MAX77675_DBEN_EN_SHIFT 0 53 + 54 + /* CNFG_GLBL_B (0x01) */ 55 + #define MAX77675_SFT_CTRL_MASK GENMASK(2, 0) /* Soft Start Control */ 56 + #define MAX77675_SFT_CTRL_SHIFT 0 57 + 58 + /* INT_GLBL (0x02) bit bits and shifts */ 59 + #define MAX77675_INT_SBB3_F_BIT BIT(7) 60 + #define MAX77675_INT_SBB3_F_SHIFT 7 61 + #define MAX77675_INT_SBB2_F_BIT BIT(6) 62 + #define MAX77675_INT_SBB2_F_SHIFT 6 63 + #define MAX77675_INT_SBB1_F_BIT BIT(5) 64 + #define MAX77675_INT_SBB1_F_SHIFT 5 65 + #define MAX77675_INT_SBB0_F_BIT BIT(4) 66 + #define MAX77675_INT_SBB0_F_SHIFT 4 67 + #define MAX77675_INT_TJAL2_R_BIT BIT(3) 68 + #define MAX77675_INT_TJAL2_R_SHIFT 3 69 + #define MAX77675_INT_TJAL1_R_BIT BIT(2) 70 + #define MAX77675_INT_TJAL1_R_SHIFT 2 71 + #define MAX77675_INT_EN_R_BIT BIT(1) 72 + #define MAX77675_INT_EN_R_SHIFT 1 73 + #define MAX77675_INT_EN_F_BIT BIT(0) 74 + #define MAX77675_INT_EN_F_SHIFT 0 75 + 76 + /* INTM_GLBL (0x03) bits and shifts */ 77 + #define MAX77675_INTM_SBB3_F_BIT BIT(7) 78 + #define MAX77675_INTM_SBB3_F_SHIFT 7 79 + #define MAX77675_INTM_SBB2_F_BIT BIT(6) 80 + #define MAX77675_INTM_SBB2_F_SHIFT 6 81 + #define MAX77675_INTM_SBB1_F_BIT BIT(5) 82 + #define MAX77675_INTM_SBB1_F_SHIFT 5 83 + #define MAX77675_INTM_SBB0_F_BIT BIT(4) 84 + #define MAX77675_INTM_SBB0_F_SHIFT 4 85 + #define MAX77675_INTM_TJAL2_R_BIT BIT(3) 86 + #define MAX77675_INTM_TJAL2_R_SHIFT 3 87 + #define MAX77675_INTM_TJAL1_R_BIT BIT(2) 88 + #define MAX77675_INTM_TJAL1_R_SHIFT 2 89 + #define MAX77675_INTM_EN_R_BIT BIT(1) 90 + #define MAX77675_INTM_EN_R_SHIFT 1 91 + #define MAX77675_INTM_EN_F_BIT BIT(0) 92 + #define MAX77675_INTM_EN_F_SHIFT 0 93 + 94 + /* STAT_GLBL (0x04) bits and shifts */ 95 + #define MAX77675_STAT_SBB3_S_BIT BIT(7) 96 + #define MAX77675_STAT_SBB3_S_SHIFT 7 97 + #define MAX77675_STAT_SBB2_S_BIT BIT(6) 98 + #define MAX77675_STAT_SBB2_S_SHIFT 6 99 + #define MAX77675_STAT_SBB1_S_BIT BIT(5) 100 + #define MAX77675_STAT_SBB1_S_SHIFT 5 101 + #define MAX77675_STAT_SBB0_S_BIT BIT(4) 102 + #define MAX77675_STAT_SBB0_S_SHIFT 4 103 + #define MAX77675_STAT_TJAL2_S_BIT BIT(2) 104 + #define MAX77675_STAT_TJAL2_S_SHIFT 2 105 + #define MAX77675_STAT_TJAL1_S_BIT BIT(1) 106 + #define MAX77675_STAT_TJAL1_S_SHIFT 1 107 + #define MAX77675_STAT_STAT_EN_BIT BIT(0) 108 + #define MAX77675_STAT_STAT_EN_SHIFT 0 109 + 110 + #define MAX77675_STAT_STAT_EN_BIT BIT(0) 111 + #define MAX77675_STAT_STAT_EN_SHIFT 0 112 + 113 + /* ERCFLAG (0x05) bits and shifts */ 114 + #define MAX77675_SFT_CRST_F_BIT BIT(5) /* Software Cold Reset Flag */ 115 + #define MAX77675_SFT_CRST_F_SHIFT 5 116 + #define MAX77675_SFT_OFF_F_BIT BIT(4) /* Software Off Flag */ 117 + #define MAX77675_SFT_OFF_F_SHIFT 4 118 + #define MAX77675_MRST_BIT BIT(3) /* Manual Reset Timer Flag */ 119 + #define MAX77675_MRST_SHIFT 3 120 + #define MAX77675_UVLO_BIT BIT(2) /* Undervoltage Lockout Flag */ 121 + #define MAX77675_UVLO_SHIFT 2 122 + #define MAX77675_OVLO_BIT BIT(1) /* Overvoltage Lockout Flag */ 123 + #define MAX77675_OVLO_SHIFT 1 124 + #define MAX77675_TOVLD_BIT BIT(0) /* Thermal Overload Flag */ 125 + #define MAX77675_TOVLD_SHIFT 0 126 + 127 + /* CID (0x06) bits and shifts */ 128 + #define MAX77675_CID_MASK GENMASK(4, 0) /* Chip Identification Code mask */ 129 + #define MAX77675_CID_SHIFT 0 /* Starts at bit 0 */ 130 + 131 + /* CNFG_SBB_TOP_A (0x07) bits and shifts */ 132 + #define MAX77675_STEP_SZ_SBB3_BIT BIT(5) 133 + #define MAX77675_STEP_SZ_SBB3_SHIFT 5 134 + #define MAX77675_STEP_SZ_SBB2_BIT BIT(4) 135 + #define MAX77675_STEP_SZ_SBB2_SHIFT 4 136 + #define MAX77675_STEP_SZ_SBB1_BIT BIT(3) 137 + #define MAX77675_STEP_SZ_SBB1_SHIFT 3 138 + #define MAX77675_STEP_SZ_SBB0_BIT BIT(2) 139 + #define MAX77675_STEP_SZ_SBB0_SHIFT 2 140 + #define MAX77675_DRV_SBB_MASK GENMASK(1, 0) 141 + #define MAX77675_DRV_SBB_SHIFT 0 142 + 143 + /* CNFG_SBB0_A (0x08) bits and shifts */ 144 + #define MAX77675_TV_SBB0_MASK GENMASK(7, 0) 145 + #define MAX77675_TV_SBB0_SHIFT 0 146 + 147 + /* CNFG_SBB0_B (0x09) bits and shifts */ 148 + #define MAX77675_ADE_SBB0_BIT BIT(3) 149 + #define MAX77675_ADE_SBB0_SHIFT 3 150 + #define MAX77675_EN_SBB0_MASK GENMASK(2, 0) 151 + #define MAX77675_EN_SBB0_SHIFT 0 152 + 153 + /* CNFG_SBB1_A (0x0A) bits and shifts */ 154 + #define MAX77675_TV_SBB1_MASK GENMASK(7, 0) 155 + #define MAX77675_TV_SBB1_SHIFT 0 156 + 157 + /* CNFG_SBB1_B (0x0B) bits and shifts */ 158 + #define MAX77675_ADE_SBB1_BIT BIT(3) 159 + #define MAX77675_ADE_SBB1_SHIFT 3 160 + #define MAX77675_EN_SBB1_MASK GENMASK(2, 0) 161 + #define MAX77675_EN_SBB1_SHIFT 0 162 + 163 + /* CNFG_SBB2_A (0x0C) bits and shifts */ 164 + #define MAX77675_TV_SBB2_MASK GENMASK(7, 0) 165 + #define MAX77675_TV_SBB2_SHIFT 0 166 + 167 + /* CNFG_SBB2_B (0x0D) bits and shifts */ 168 + #define MAX77675_ADE_SBB2_BIT BIT(3) 169 + #define MAX77675_ADE_SBB2_SHIFT 3 170 + #define MAX77675_EN_SBB2_MASK GENMASK(2, 0) 171 + #define MAX77675_EN_SBB2_SHIFT 0 172 + 173 + /* CNFG_SBB3_A (0x0E) bits and shifts */ 174 + #define MAX77675_TV_SBB3_MASK GENMASK(7, 0) 175 + #define MAX77675_TV_SBB3_SHIFT 0 176 + 177 + /* CNFG_SBB3_B (0x0F) bits and shifts */ 178 + #define MAX77675_ADE_SBB3_BIT BIT(3) 179 + #define MAX77675_ADE_SBB3_SHIFT 3 180 + #define MAX77675_EN_SBB3_MASK GENMASK(2, 0) 181 + #define MAX77675_EN_SBB3_SHIFT 0 182 + 183 + #define MAX77675_EN_SBB_MASK GENMASK(2, 0) 184 + 185 + /* CNFG_SBB_TOP_B (0x10) bits and shifts */ 186 + #define MAX77675_DVS_SLEW_BIT BIT(5) 187 + #define MAX77675_DVS_SLEW_SHIFT 5 188 + #define MAX77675_LAT_MODE_BIT BIT(4) 189 + #define MAX77675_LAT_MODE_SHIFT 4 190 + #define MAX77675_SR_SBB3_BIT BIT(3) 191 + #define MAX77675_SR_SBB3_SHIFT 3 192 + #define MAX77675_SR_SBB2_BIT BIT(2) 193 + #define MAX77675_SR_SBB2_SHIFT 2 194 + #define MAX77675_SR_SBB1_BIT BIT(1) 195 + #define MAX77675_SR_SBB1_SHIFT 1 196 + #define MAX77675_SR_SBB0_BIT BIT(0) 197 + #define MAX77675_SR_SBB0_SHIFT 0 198 + 199 + #define MAX77675_MAX_REGISTER 0x10 200 + 201 + /* Common minimum voltage (in microvolts) */ 202 + #define MAX77675_MIN_UV 500000 // 500 mV 203 + 204 + /* Voltage step configuration for 25mV mode */ 205 + #define MAX77675_STEP_25MV 25000 // Step size: 25 mV 206 + #define MAX77675_MAX_UV_25MV 5500000 // Max voltage: 5.5 V 207 + #define MAX77675_NUM_LEVELS_25MV 201 // levels = (5500mV - 500mV) / 25mV + 1 208 + 209 + /* Voltage step configuration for 12.5mV mode */ 210 + #define MAX77675_STEP_12_5MV 12500 // Step size: 12.5 mV 211 + #define MAX77675_MAX_UV_12_5MV 3687500 // Max voltage: 3.6875 V 212 + #define MAX77675_NUM_LEVELS_12_5MV 255 // levels = (3687.5mV - 500mV) / 12.5mV + 1 213 + 214 + #define MAX77675_ENABLE_OFF 0x04 215 + #define MAX77675_ENABLE_ON 0x06 216 + 217 + #define MAX77675_REGULATOR_AD_OFF 0x00 218 + #define MAX77675_REGULATOR_AD_ON BIT(3) 219 + 220 + /* FPS source */ 221 + #define MAX77675_FPS_SLOT_0 0x0 222 + #define MAX77675_FPS_SLOT_1 0x1 223 + #define MAX77675_FPS_SLOT_2 0x2 224 + #define MAX77675_FPS_SLOT_3 0x3 225 + #define MAX77675_FPS_DEF 0x4 226 + 227 + /* nEN Manual Reset Time Configuration (MRT) */ 228 + #define MAX77675_MRT_4S 0x0 229 + #define MAX77675_MRT_8S 0x1 230 + #define MAX77675_MRT_12S 0x2 231 + #define MAX77675_MRT_16S 0x3 232 + 233 + /* nEN Mode Configuration */ 234 + #define MAX77675_EN_PUSH_BUTTON 0x0 235 + #define MAX77675_EN_SLIDE_SWITCH 0x1 236 + #define MAX77675_EN_LOGIC 0x2 237 + 238 + /* Debounce Timer Enable (DBEN_nEN) */ 239 + #define MAX77675_DBEN_100US 0x0 240 + #define MAX77675_DBEN_30000US 0x1 241 + 242 + /* Rising slew rate control for SBB0 when ramping up */ 243 + #define MAX77675_SR_2MV_PER_US 0x0 // 2 mV/us 244 + #define MAX77675_SR_USE_DVS 0x1 // Use DVS slew rate setting (adi,dvs-slew-rate) 245 + 246 + /* Latency Mode */ 247 + #define MAX77675_HIGH_LATENCY_MODE 0x0 // High latency, low quiescent current (~100us) 248 + #define MAX77675_LOW_LATENCY_MODE 0x1 // Low latency, high quiescent current (~10us) 249 + 250 + /* Dynamic Voltage Scaling (DVS) Slew Rate */ 251 + #define MAX77675_DVS_SLEW_5MV_PER_US 0x0 // 5 mV/us 252 + #define MAX77675_DVS_SLEW_10MV_PER_US 0x1 // 10 mV/us 253 + 254 + /* SIMO Buck-Boost Drive Strength (All Channels) */ 255 + #define MAX77675_DRV_SBB_STRENGTH_MAX 0x0 // Maximum drive strength (~0.6 ns transition time) 256 + #define MAX77675_DRV_SBB_STRENGTH_HIGH 0x1 // High drive strength (~1.2 ns transition time) 257 + #define MAX77675_DRV_SBB_STRENGTH_LOW 0x2 // Low drive strength (~1.8 ns transition time) 258 + #define MAX77675_DRV_SBB_STRENGTH_MIN 0x3 // Minimum drive strength (~8 ns transition time) 259 + 260 + /* Regulator ID enumeration */ 261 + enum max77675_regulator_id { 262 + MAX77675_ID_SBB0 = 0, 263 + MAX77675_ID_SBB1, 264 + MAX77675_ID_SBB2, 265 + MAX77675_ID_SBB3, 266 + MAX77675_ID_NUM_MAX, 267 + }; 268 + 269 + struct max77675_regulator_sbb_setting { 270 + u8 fps_slot; 271 + bool fixed_slew_rate; 272 + }; 273 + 274 + struct max77675_config { 275 + u8 en_mode; 276 + u8 voltage_change_latency; 277 + u8 drv_sbb_strength; 278 + u8 dvs_slew_rate; 279 + u8 debounce_time; 280 + u8 manual_reset_time; 281 + bool en_pullup_disable; 282 + bool bias_low_power_request; 283 + bool simo_ldo_always_on; 284 + }; 285 + 286 + struct max77675_regulator { 287 + struct device *dev; 288 + struct regmap *regmap; 289 + struct max77675_config config; 290 + struct max77675_regulator_sbb_setting sbb_setting[MAX77675_ID_NUM_MAX]; 291 + }; 292 + 293 + static int max77675_regulator_get_fps_src(struct max77675_regulator *maxreg, int id) 294 + { 295 + unsigned int reg_addr; 296 + unsigned int val; 297 + int ret; 298 + 299 + switch (id) { 300 + case MAX77675_ID_SBB0: 301 + reg_addr = MAX77675_REG_CNFG_SBB0_B; 302 + break; 303 + case MAX77675_ID_SBB1: 304 + reg_addr = MAX77675_REG_CNFG_SBB1_B; 305 + break; 306 + case MAX77675_ID_SBB2: 307 + reg_addr = MAX77675_REG_CNFG_SBB2_B; 308 + break; 309 + case MAX77675_ID_SBB3: 310 + reg_addr = MAX77675_REG_CNFG_SBB3_B; 311 + break; 312 + default: 313 + dev_err(maxreg->dev, "Invalid regulator id: %d\n", id); 314 + return -EINVAL; 315 + } 316 + 317 + ret = regmap_read(maxreg->regmap, reg_addr, &val); 318 + if (ret < 0) { 319 + dev_err(maxreg->dev, "Failed to read FPS source (reg 0x%02x): %d\n", 320 + reg_addr, ret); 321 + return ret; 322 + } 323 + 324 + return FIELD_GET(MAX77675_EN_SBB_MASK, val); 325 + } 326 + 327 + static int max77675_regulator_set_fps_src(struct max77675_regulator *maxreg, int id, u8 fps_src) 328 + { 329 + unsigned int reg_addr; 330 + 331 + switch (id) { 332 + case MAX77675_ID_SBB0: 333 + reg_addr = MAX77675_REG_CNFG_SBB0_B; 334 + break; 335 + case MAX77675_ID_SBB1: 336 + reg_addr = MAX77675_REG_CNFG_SBB1_B; 337 + break; 338 + case MAX77675_ID_SBB2: 339 + reg_addr = MAX77675_REG_CNFG_SBB2_B; 340 + break; 341 + case MAX77675_ID_SBB3: 342 + reg_addr = MAX77675_REG_CNFG_SBB3_B; 343 + break; 344 + default: 345 + dev_err(maxreg->dev, "Invalid regulator id: %d\n", id); 346 + return -EINVAL; 347 + } 348 + 349 + return regmap_update_bits(maxreg->regmap, reg_addr, MAX77675_EN_SBB_MASK, fps_src); 350 + } 351 + 352 + static int max77675_set_sbb_slew_rate_fixed(struct max77675_regulator *maxreg, int id, bool fixed) 353 + { 354 + u8 mask, value; 355 + u8 slew_src_ctrl_bit = fixed ? 0 : 1; 356 + 357 + switch (id) { 358 + case MAX77675_ID_SBB0: 359 + mask = MAX77675_SR_SBB0_BIT; 360 + value = FIELD_PREP(MAX77675_SR_SBB0_BIT, slew_src_ctrl_bit); 361 + break; 362 + 363 + case MAX77675_ID_SBB1: 364 + mask = MAX77675_SR_SBB1_BIT; 365 + value = FIELD_PREP(MAX77675_SR_SBB1_BIT, slew_src_ctrl_bit); 366 + break; 367 + 368 + case MAX77675_ID_SBB2: 369 + mask = MAX77675_SR_SBB2_BIT; 370 + value = FIELD_PREP(MAX77675_SR_SBB2_BIT, slew_src_ctrl_bit); 371 + break; 372 + 373 + case MAX77675_ID_SBB3: 374 + mask = MAX77675_SR_SBB3_BIT; 375 + value = FIELD_PREP(MAX77675_SR_SBB3_BIT, slew_src_ctrl_bit); 376 + break; 377 + 378 + default: 379 + return -EINVAL; 380 + } 381 + 382 + return regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_B, mask, value); 383 + } 384 + 385 + static int max77675_init_regulator(struct max77675_regulator *maxreg, int id) 386 + { 387 + struct max77675_regulator_sbb_setting *sbb_setting = &maxreg->sbb_setting[id]; 388 + int ret; 389 + 390 + if (sbb_setting->fps_slot == MAX77675_FPS_DEF) { 391 + ret = max77675_regulator_get_fps_src(maxreg, id); 392 + if (ret < 0) 393 + return ret; 394 + 395 + sbb_setting->fps_slot = ret; 396 + } else { 397 + ret = max77675_regulator_set_fps_src(maxreg, id, sbb_setting->fps_slot); 398 + if (ret < 0) 399 + return ret; 400 + } 401 + 402 + ret = max77675_set_sbb_slew_rate_fixed(maxreg, id, sbb_setting->fixed_slew_rate); 403 + if (ret < 0) 404 + return ret; 405 + 406 + return 0; 407 + } 408 + 409 + static int max77675_of_parse_cb(struct device_node *np, 410 + const struct regulator_desc *desc, 411 + struct regulator_config *config) 412 + { 413 + struct max77675_regulator *maxreg = config->driver_data; 414 + struct max77675_regulator_sbb_setting *sbb_setting = &maxreg->sbb_setting[desc->id]; 415 + static const char * const fps_slots[] = { "slot0", "slot1", "slot2", "slot3", "default" }; 416 + const char *fps_str; 417 + int slot; 418 + 419 + /* Parse FPS slot from DT */ 420 + if (of_property_read_string(np, "adi,fps-slot", &fps_str)) { 421 + /* Property not set, use default */ 422 + sbb_setting->fps_slot = MAX77675_FPS_DEF; 423 + } else { 424 + /* Match string to index */ 425 + slot = match_string(fps_slots, ARRAY_SIZE(fps_slots), fps_str); 426 + if (slot < 0) { 427 + dev_dbg(maxreg->dev, "Invalid fps-slot '%s', using default\n", fps_str); 428 + sbb_setting->fps_slot = MAX77675_FPS_DEF; 429 + } else { 430 + sbb_setting->fps_slot = slot; 431 + } 432 + } 433 + 434 + /* Parse slew rate control source */ 435 + sbb_setting->fixed_slew_rate = of_property_read_bool(np, "adi,fixed-slew-rate"); 436 + 437 + /* Apply parsed configuration */ 438 + return max77675_init_regulator(maxreg, desc->id); 439 + } 440 + 441 + static int max77675_get_error_flags(struct regulator_dev *rdev, unsigned int *flags) 442 + { 443 + struct max77675_regulator *maxreg = rdev_get_drvdata(rdev); 444 + unsigned int int_flags; 445 + int id = rdev_get_id(rdev); 446 + int ret; 447 + 448 + ret = regmap_read(maxreg->regmap, MAX77675_REG_INT_GLBL, &int_flags); 449 + if (ret) { 450 + dev_err(maxreg->dev, "Failed to read INT_GLBL: %d\n", ret); 451 + return ret; 452 + } 453 + 454 + *flags = 0; 455 + 456 + switch (id) { 457 + case MAX77675_ID_SBB0: 458 + if (int_flags & MAX77675_INT_SBB0_F_BIT) 459 + *flags |= REGULATOR_ERROR_FAIL; 460 + break; 461 + case MAX77675_ID_SBB1: 462 + if (int_flags & MAX77675_INT_SBB1_F_BIT) 463 + *flags |= REGULATOR_ERROR_FAIL; 464 + break; 465 + case MAX77675_ID_SBB2: 466 + if (int_flags & MAX77675_INT_SBB2_F_BIT) 467 + *flags |= REGULATOR_ERROR_FAIL; 468 + break; 469 + case MAX77675_ID_SBB3: 470 + if (int_flags & MAX77675_INT_SBB3_F_BIT) 471 + *flags |= REGULATOR_ERROR_FAIL; 472 + break; 473 + default: 474 + dev_warn(maxreg->dev, "Unsupported regulator ID: %d\n", id); 475 + break; 476 + } 477 + 478 + if (int_flags & MAX77675_INT_TJAL2_R_BIT) { 479 + /* TJAL2 interrupt: Over-temperature condition (above 120 degree) */ 480 + *flags |= REGULATOR_ERROR_OVER_TEMP; 481 + } 482 + 483 + return 0; 484 + } 485 + 486 + static const struct regulator_ops max77675_regulator_ops = { 487 + .list_voltage = regulator_list_voltage_linear, 488 + .enable = regulator_enable_regmap, 489 + .disable = regulator_disable_regmap, 490 + .is_enabled = regulator_is_enabled_regmap, 491 + .map_voltage = regulator_map_voltage_linear, 492 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 493 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 494 + .set_active_discharge = regulator_set_active_discharge_regmap, 495 + .get_error_flags = max77675_get_error_flags, 496 + }; 497 + 498 + static struct regulator_desc max77675_regulators[MAX77675_ID_NUM_MAX] = { 499 + { 500 + .name = "sbb0", 501 + .of_match = of_match_ptr("sbb0"), 502 + .regulators_node = of_match_ptr("regulators"), 503 + .of_parse_cb = max77675_of_parse_cb, 504 + .id = MAX77675_ID_SBB0, 505 + .ops = &max77675_regulator_ops, 506 + .type = REGULATOR_VOLTAGE, 507 + .owner = THIS_MODULE, 508 + .n_voltages = MAX77675_NUM_LEVELS_25MV, 509 + .min_uV = MAX77675_MIN_UV, 510 + .uV_step = MAX77675_STEP_25MV, 511 + .vsel_reg = MAX77675_REG_CNFG_SBB0_A, 512 + .vsel_mask = MAX77675_TV_SBB0_MASK, 513 + .enable_reg = MAX77675_REG_CNFG_SBB0_B, 514 + .enable_mask = MAX77675_EN_SBB0_MASK, 515 + .enable_val = MAX77675_ENABLE_ON, 516 + .disable_val = MAX77675_ENABLE_OFF, 517 + .active_discharge_off = MAX77675_REGULATOR_AD_OFF, 518 + .active_discharge_on = MAX77675_REGULATOR_AD_ON, 519 + .active_discharge_mask = MAX77675_ADE_SBB0_BIT, 520 + .active_discharge_reg = MAX77675_REG_CNFG_SBB0_B, 521 + }, 522 + { 523 + .name = "sbb1", 524 + .of_match = of_match_ptr("sbb1"), 525 + .regulators_node = of_match_ptr("regulators"), 526 + .of_parse_cb = max77675_of_parse_cb, 527 + .id = MAX77675_ID_SBB1, 528 + .ops = &max77675_regulator_ops, 529 + .type = REGULATOR_VOLTAGE, 530 + .owner = THIS_MODULE, 531 + .n_voltages = MAX77675_NUM_LEVELS_25MV, 532 + .min_uV = MAX77675_MIN_UV, 533 + .uV_step = MAX77675_STEP_25MV, 534 + .vsel_reg = MAX77675_REG_CNFG_SBB1_A, 535 + .vsel_mask = MAX77675_TV_SBB1_MASK, 536 + .enable_reg = MAX77675_REG_CNFG_SBB1_B, 537 + .enable_mask = MAX77675_EN_SBB1_MASK, 538 + .enable_val = MAX77675_ENABLE_ON, 539 + .disable_val = MAX77675_ENABLE_OFF, 540 + .active_discharge_off = MAX77675_REGULATOR_AD_OFF, 541 + .active_discharge_on = MAX77675_REGULATOR_AD_ON, 542 + .active_discharge_mask = MAX77675_ADE_SBB1_BIT, 543 + .active_discharge_reg = MAX77675_REG_CNFG_SBB1_B, 544 + }, 545 + { 546 + .name = "sbb2", 547 + .of_match = of_match_ptr("sbb2"), 548 + .regulators_node = of_match_ptr("regulators"), 549 + .of_parse_cb = max77675_of_parse_cb, 550 + .id = MAX77675_ID_SBB2, 551 + .ops = &max77675_regulator_ops, 552 + .type = REGULATOR_VOLTAGE, 553 + .owner = THIS_MODULE, 554 + .n_voltages = MAX77675_NUM_LEVELS_25MV, 555 + .min_uV = MAX77675_MIN_UV, 556 + .uV_step = MAX77675_STEP_25MV, 557 + .vsel_reg = MAX77675_REG_CNFG_SBB2_A, 558 + .vsel_mask = MAX77675_TV_SBB2_MASK, 559 + .enable_reg = MAX77675_REG_CNFG_SBB2_B, 560 + .enable_mask = MAX77675_EN_SBB2_MASK, 561 + .enable_val = MAX77675_ENABLE_ON, 562 + .disable_val = MAX77675_ENABLE_OFF, 563 + .active_discharge_off = MAX77675_REGULATOR_AD_OFF, 564 + .active_discharge_on = MAX77675_REGULATOR_AD_ON, 565 + .active_discharge_mask = MAX77675_ADE_SBB2_BIT, 566 + .active_discharge_reg = MAX77675_REG_CNFG_SBB2_B, 567 + }, 568 + { 569 + .name = "sbb3", 570 + .of_match = of_match_ptr("sbb3"), 571 + .regulators_node = of_match_ptr("regulators"), 572 + .of_parse_cb = max77675_of_parse_cb, 573 + .id = MAX77675_ID_SBB3, 574 + .ops = &max77675_regulator_ops, 575 + .type = REGULATOR_VOLTAGE, 576 + .owner = THIS_MODULE, 577 + .n_voltages = MAX77675_NUM_LEVELS_25MV, 578 + .min_uV = MAX77675_MIN_UV, 579 + .uV_step = MAX77675_STEP_25MV, 580 + .vsel_reg = MAX77675_REG_CNFG_SBB3_A, 581 + .vsel_mask = MAX77675_TV_SBB3_MASK, 582 + .enable_reg = MAX77675_REG_CNFG_SBB3_B, 583 + .enable_mask = MAX77675_EN_SBB3_MASK, 584 + .enable_val = MAX77675_ENABLE_ON, 585 + .disable_val = MAX77675_ENABLE_OFF, 586 + .active_discharge_off = MAX77675_REGULATOR_AD_OFF, 587 + .active_discharge_on = MAX77675_REGULATOR_AD_ON, 588 + .active_discharge_mask = MAX77675_ADE_SBB3_BIT, 589 + .active_discharge_reg = MAX77675_REG_CNFG_SBB3_B, 590 + }, 591 + }; 592 + 593 + static bool max77675_volatile_reg(struct device *dev, unsigned int reg) 594 + { 595 + switch (reg) { 596 + case MAX77675_REG_CNFG_GLBL_B: 597 + /* This register can be updated by an internal state machine */ 598 + case MAX77675_REG_INT_GLBL: 599 + case MAX77675_REG_STAT_GLBL: 600 + case MAX77675_REG_ERCF_GLBL: 601 + return true; 602 + default: 603 + return false; 604 + } 605 + } 606 + 607 + static const struct regmap_config max77675_regmap_config = { 608 + .reg_bits = 8, 609 + .val_bits = 8, 610 + .max_register = MAX77675_MAX_REGISTER, 611 + .cache_type = REGCACHE_MAPLE, 612 + .volatile_reg = max77675_volatile_reg, 613 + }; 614 + 615 + static int max77675_apply_config(struct max77675_regulator *maxreg) 616 + { 617 + const struct max77675_config *cfg = &maxreg->config; 618 + int ret; 619 + 620 + /* Set EN pin mode */ 621 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A, 622 + MAX77675_EN_MODE_MASK, 623 + FIELD_PREP(MAX77675_EN_MODE_MASK, cfg->en_mode)); 624 + if (ret) { 625 + dev_err(maxreg->dev, "Failed to set EN mode: %d\n", ret); 626 + return ret; 627 + } 628 + 629 + /* Set the latency between output voltage change and SBBx voltage ramp start */ 630 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_B, 631 + MAX77675_LAT_MODE_BIT, 632 + FIELD_PREP(MAX77675_LAT_MODE_BIT, cfg->voltage_change_latency)); 633 + if (ret) { 634 + dev_err(maxreg->dev, "Failed to set latency mode: %d\n", ret); 635 + return ret; 636 + } 637 + 638 + /* Set drive strength */ 639 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_A, 640 + MAX77675_DRV_SBB_MASK, 641 + FIELD_PREP(MAX77675_DRV_SBB_MASK, cfg->drv_sbb_strength)); 642 + if (ret) { 643 + dev_err(maxreg->dev, "Failed to set drive strength: %d\n", ret); 644 + return ret; 645 + } 646 + 647 + /* Set DVS slew rate */ 648 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_B, 649 + MAX77675_DVS_SLEW_BIT, 650 + FIELD_PREP(MAX77675_DVS_SLEW_BIT, cfg->dvs_slew_rate)); 651 + if (ret) { 652 + dev_err(maxreg->dev, "Failed to set DVS slew rate: %d\n", ret); 653 + return ret; 654 + } 655 + 656 + /* Set debounce time for EN pin */ 657 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A, 658 + MAX77675_DBEN_EN_BIT, 659 + FIELD_PREP(MAX77675_DBEN_EN_BIT, cfg->debounce_time)); 660 + if (ret) { 661 + dev_err(maxreg->dev, "Failed to set EN debounce time: %d\n", ret); 662 + return ret; 663 + } 664 + 665 + /* Set manual reset time (MRT) for EN pin */ 666 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A, 667 + MAX77675_MRT_MASK, 668 + FIELD_PREP(MAX77675_MRT_MASK, cfg->manual_reset_time)); 669 + if (ret) { 670 + dev_err(maxreg->dev, "Failed to set manual reset time: %d\n", ret); 671 + return ret; 672 + } 673 + 674 + /* Enable or disable internal pull-up resistor on EN pin */ 675 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A, 676 + MAX77675_PU_DIS_BIT, 677 + FIELD_PREP(MAX77675_PU_DIS_BIT, cfg->en_pullup_disable)); 678 + if (ret) { 679 + dev_err(maxreg->dev, "Failed to set EN pull-up disable: %d\n", ret); 680 + return ret; 681 + } 682 + 683 + /* Request main bias to enter low-power mode */ 684 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A, 685 + MAX77675_BIAS_LPM_BIT, 686 + FIELD_PREP(MAX77675_BIAS_LPM_BIT, cfg->bias_low_power_request)); 687 + if (ret) { 688 + dev_err(maxreg->dev, "Failed to set bias low-power request: %d\n", ret); 689 + return ret; 690 + } 691 + 692 + /* Force SIMO internal LDO to always supply 1.8V */ 693 + ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A, 694 + MAX77675_SIMO_CH_DIS_BIT, 695 + FIELD_PREP(MAX77675_SIMO_CH_DIS_BIT, cfg->simo_ldo_always_on)); 696 + if (ret) { 697 + dev_err(maxreg->dev, "Failed to set SIMO internal LDO always-on: %d\n", ret); 698 + return ret; 699 + } 700 + 701 + return 0; 702 + } 703 + 704 + static int max77675_parse_en_mode(struct device *dev, 705 + struct device_node *np, 706 + u8 *en_mode) 707 + { 708 + static const char * const en_modes[] = {"push-button", "slide-switch", "logic"}; 709 + const char *str; 710 + int index; 711 + 712 + *en_mode = MAX77675_EN_SLIDE_SWITCH; 713 + 714 + if (of_property_read_string(np, "adi,en-mode", &str)) 715 + return 0; 716 + 717 + index = match_string(en_modes, ARRAY_SIZE(en_modes), str); 718 + if (index < 0) { 719 + dev_err(dev, "Invalid 'adi,en-mode' value '%s'\n", str); 720 + return -EINVAL; 721 + } 722 + 723 + *en_mode = index; 724 + 725 + return 0; 726 + } 727 + 728 + static int max77675_parse_voltage_change_latency(struct device *dev, 729 + struct device_node *np, 730 + u8 *latency_mode) 731 + { 732 + u32 val; 733 + 734 + *latency_mode = MAX77675_HIGH_LATENCY_MODE; 735 + 736 + if (!of_property_read_u32(np, "adi,voltage-change-latency-us", &val)) { 737 + switch (val) { 738 + case 10: 739 + *latency_mode = MAX77675_LOW_LATENCY_MODE; 740 + break; 741 + case 100: 742 + *latency_mode = MAX77675_HIGH_LATENCY_MODE; 743 + break; 744 + default: 745 + dev_err(dev, "Invalid voltage-change-latency-us value: %u\n", val); 746 + return -EINVAL; 747 + } 748 + } 749 + 750 + return 0; 751 + } 752 + 753 + static int max77675_parse_manual_reset_time(struct device *dev, 754 + struct device_node *np, 755 + u8 *reset_time) 756 + { 757 + u32 val; 758 + 759 + *reset_time = MAX77675_MRT_4S; 760 + 761 + if (!of_property_read_u32(np, "reset-time-sec", &val)) { 762 + switch (val) { 763 + case 4: 764 + *reset_time = MAX77675_MRT_4S; 765 + break; 766 + case 8: 767 + *reset_time = MAX77675_MRT_8S; 768 + break; 769 + case 12: 770 + *reset_time = MAX77675_MRT_12S; 771 + break; 772 + case 16: 773 + *reset_time = MAX77675_MRT_16S; 774 + break; 775 + default: 776 + dev_err(dev, "Invalid reset-time-sec value: %u\n", val); 777 + return -EINVAL; 778 + } 779 + } 780 + 781 + return 0; 782 + } 783 + 784 + static int max77675_parse_dvs_slew_rate(struct device *dev, struct device_node *np, u8 *slew_rate) 785 + { 786 + u32 val; 787 + 788 + /* Set default: 5 mV/us */ 789 + *slew_rate = MAX77675_DVS_SLEW_5MV_PER_US; 790 + 791 + if (!of_property_read_u32(np, "adi,dvs-slew-rate-mv-per-us", &val)) { 792 + switch (val) { 793 + case 5: 794 + *slew_rate = MAX77675_DVS_SLEW_5MV_PER_US; 795 + break; 796 + case 10: 797 + *slew_rate = MAX77675_DVS_SLEW_10MV_PER_US; 798 + break; 799 + default: 800 + dev_err(dev, "Invalid dvs-slew-rate-mv-per-us value: %u\n", val); 801 + return -EINVAL; 802 + } 803 + } 804 + 805 + return 0; 806 + } 807 + 808 + static int max77675_parse_drv_sbb_strength(struct device *dev, struct device_node *np, u8 *strength) 809 + { 810 + static const char * const strength_names[] = {"max", "high", "low", "min"}; 811 + const char *str; 812 + int index; 813 + 814 + /* Set default: maximum drive strength */ 815 + *strength = MAX77675_DRV_SBB_STRENGTH_MAX; 816 + 817 + if (of_property_read_string(np, "adi,drv-sbb-strength", &str)) 818 + return 0; 819 + 820 + index = match_string(strength_names, ARRAY_SIZE(strength_names), str); 821 + if (index < 0) { 822 + dev_err(dev, "Invalid 'adi,drv-sbb-strength' value: '%s'\n", str); 823 + return -EINVAL; 824 + } 825 + 826 + *strength = index; 827 + 828 + return 0; 829 + } 830 + 831 + static int max77675_parse_debounce_time_us(struct device *dev, 832 + struct device_node *np, 833 + u8 *debounce_time) 834 + { 835 + u32 val; 836 + 837 + *debounce_time = MAX77675_DBEN_100US; 838 + 839 + if (!of_property_read_u32(np, "input-debounce", &val)) { 840 + switch (val) { 841 + case 100: 842 + *debounce_time = MAX77675_DBEN_100US; 843 + break; 844 + case 30000: 845 + *debounce_time = MAX77675_DBEN_30000US; 846 + break; 847 + default: 848 + dev_err(dev, "Invalid input-debounce value: %u\n", val); 849 + return -EINVAL; 850 + } 851 + } 852 + 853 + return 0; 854 + } 855 + 856 + static int max77675_parse_config(struct max77675_regulator *maxreg) 857 + { 858 + struct device_node *np = maxreg->dev->of_node; 859 + struct max77675_config *cfg = &maxreg->config; 860 + int ret; 861 + 862 + /* EN pin mode */ 863 + ret = max77675_parse_en_mode(maxreg->dev, np, &cfg->en_mode); 864 + if (ret < 0) 865 + return ret; 866 + 867 + /* voltage change latency */ 868 + ret = max77675_parse_voltage_change_latency(maxreg->dev, np, &cfg->voltage_change_latency); 869 + if (ret < 0) 870 + return ret; 871 + 872 + /* drive strength */ 873 + ret = max77675_parse_drv_sbb_strength(maxreg->dev, np, &cfg->drv_sbb_strength); 874 + if (ret < 0) 875 + return ret; 876 + 877 + /* dvs slew rate */ 878 + ret = max77675_parse_dvs_slew_rate(maxreg->dev, np, &cfg->dvs_slew_rate); 879 + if (ret < 0) 880 + return ret; 881 + 882 + /* Debounce time for EN pin */ 883 + ret = max77675_parse_debounce_time_us(maxreg->dev, np, &cfg->debounce_time); 884 + if (ret < 0) 885 + return ret; 886 + 887 + /* Manual reset time for EN pin */ 888 + ret = max77675_parse_manual_reset_time(maxreg->dev, np, &cfg->manual_reset_time); 889 + if (ret < 0) 890 + return ret; 891 + 892 + /* Disable internal pull-up resistor on EN pin */ 893 + cfg->en_pullup_disable = of_property_read_bool(np, "bias-disable"); 894 + 895 + /* Request low-power mode for main bias */ 896 + cfg->bias_low_power_request = of_property_read_bool(np, "adi,bias-low-power-request"); 897 + 898 + /* Force internal LDO to always supply 1.8V */ 899 + cfg->simo_ldo_always_on = of_property_read_bool(np, "adi,simo-ldo-always-on"); 900 + 901 + return ret; 902 + } 903 + 904 + static int max77675_init_event(struct max77675_regulator *maxreg) 905 + { 906 + unsigned int ercflag, int_glbl; 907 + int ret; 908 + 909 + ret = regmap_read(maxreg->regmap, MAX77675_REG_ERCF_GLBL, &ercflag); 910 + if (ret) { 911 + dev_err(maxreg->dev, "Failed to read CID register: %d\n", ret); 912 + return ret; 913 + } 914 + 915 + ret = regmap_read(maxreg->regmap, MAX77675_REG_INT_GLBL, &int_glbl); 916 + if (ret) { 917 + dev_err(maxreg->dev, "Failed to read INT_GLBL register: %d\n", ret); 918 + return ret; 919 + } 920 + 921 + if (ercflag & MAX77675_SFT_CRST_F_BIT) 922 + dev_dbg(maxreg->dev, "Software Cold Reset Flag is set\n"); 923 + 924 + if (ercflag & MAX77675_SFT_OFF_F_BIT) 925 + dev_dbg(maxreg->dev, "Software Off Flag is set\n"); 926 + 927 + if (ercflag & MAX77675_MRST_BIT) 928 + dev_dbg(maxreg->dev, "Manual Reset Timer Flag is set\n"); 929 + 930 + if (ercflag & MAX77675_UVLO_BIT) 931 + dev_dbg(maxreg->dev, "Undervoltage Lockout Flag is set\n"); 932 + 933 + if (ercflag & MAX77675_OVLO_BIT) 934 + dev_dbg(maxreg->dev, "Overvoltage Lockout Flag is set\n"); 935 + 936 + if (ercflag & MAX77675_TOVLD_BIT) 937 + dev_dbg(maxreg->dev, "Thermal Overload Flag is set\n"); 938 + 939 + if (int_glbl & MAX77675_INT_SBB3_F_BIT) 940 + dev_dbg(maxreg->dev, "SBB3 Channel Fault Interrupt occurred\n"); 941 + 942 + if (int_glbl & MAX77675_INT_SBB2_F_BIT) 943 + dev_dbg(maxreg->dev, "SBB2 Channel Fault Interrupt occurred\n"); 944 + 945 + if (int_glbl & MAX77675_INT_SBB1_F_BIT) 946 + dev_dbg(maxreg->dev, "SBB1 Channel Fault Interrupt occurred\n"); 947 + 948 + if (int_glbl & MAX77675_INT_SBB0_F_BIT) 949 + dev_dbg(maxreg->dev, "SBB0 Channel Fault Interrupt occurred\n"); 950 + 951 + if (int_glbl & MAX77675_INT_TJAL2_R_BIT) 952 + dev_dbg(maxreg->dev, "Thermal Alarm 2 Rising Interrupt occurred\n"); 953 + 954 + if (int_glbl & MAX77675_INT_TJAL1_R_BIT) 955 + dev_dbg(maxreg->dev, "Thermal Alarm 1 Rising Interrupt occurred\n"); 956 + 957 + if (int_glbl & MAX77675_INT_EN_R_BIT) 958 + dev_dbg(maxreg->dev, "nEN Rising Edge Interrupt occurred\n"); 959 + 960 + if (int_glbl & MAX77675_INT_EN_F_BIT) 961 + dev_dbg(maxreg->dev, "nEN Falling Edge Interrupt occurred\n"); 962 + 963 + return 0; 964 + } 965 + 966 + static int max77675_regulator_probe(struct i2c_client *client) 967 + { 968 + struct max77675_regulator *maxreg; 969 + struct regulator_config config = {}; 970 + int i, ret; 971 + 972 + maxreg = devm_kzalloc(&client->dev, sizeof(*maxreg), GFP_KERNEL); 973 + if (!maxreg) 974 + return -ENOMEM; 975 + 976 + maxreg->dev = &client->dev; 977 + 978 + maxreg->regmap = devm_regmap_init_i2c(client, &max77675_regmap_config); 979 + if (IS_ERR(maxreg->regmap)) 980 + return dev_err_probe(maxreg->dev, 981 + PTR_ERR(maxreg->regmap), 982 + "Failed to init regmap\n"); 983 + 984 + ret = max77675_init_event(maxreg); 985 + if (ret < 0) 986 + return dev_err_probe(maxreg->dev, ret, "Failed to init event\n"); 987 + 988 + ret = max77675_parse_config(maxreg); 989 + if (ret < 0) 990 + return dev_err_probe(maxreg->dev, ret, "Failed to parse config\n"); 991 + 992 + ret = max77675_apply_config(maxreg); 993 + if (ret < 0) 994 + return dev_err_probe(maxreg->dev, ret, "Failed to apply config\n"); 995 + 996 + config.dev = &client->dev; 997 + config.regmap = maxreg->regmap; 998 + config.driver_data = maxreg; 999 + 1000 + struct device_node *regulators_np __free(device_node) = 1001 + of_get_child_by_name(client->dev.of_node, "regulators"); 1002 + if (!regulators_np) { 1003 + dev_err(maxreg->dev, "No 'regulators' subnode found in DT\n"); 1004 + return -EINVAL; 1005 + } 1006 + 1007 + for (i = 0; i < MAX77675_ID_NUM_MAX; i++) { 1008 + const struct regulator_desc *desc = &max77675_regulators[i]; 1009 + struct regulator_dev *rdev; 1010 + 1011 + struct device_node *child_np __free(device_node) = 1012 + of_get_child_by_name(regulators_np, desc->name); 1013 + if (!child_np) { 1014 + dev_warn(maxreg->dev, "No DT node for regulator %s\n", desc->name); 1015 + continue; 1016 + } 1017 + 1018 + config.of_node = child_np; 1019 + 1020 + rdev = devm_regulator_register(&client->dev, desc, &config); 1021 + if (IS_ERR(rdev)) { 1022 + return dev_err_probe(maxreg->dev, PTR_ERR(rdev), 1023 + "Failed to register regulator %d (%s)\n", 1024 + i, desc->name); 1025 + } 1026 + } 1027 + 1028 + return 0; 1029 + } 1030 + 1031 + static const struct i2c_device_id max77675_i2c_id[] = { 1032 + { "max77675", 0 }, 1033 + { } 1034 + }; 1035 + MODULE_DEVICE_TABLE(i2c, max77675_i2c_id); 1036 + 1037 + static const struct of_device_id __maybe_unused max77675_of_match[] = { 1038 + { .compatible = "adi,max77675", }, 1039 + { } 1040 + }; 1041 + MODULE_DEVICE_TABLE(of, max77675_of_match); 1042 + 1043 + static struct i2c_driver max77675_regulator_driver = { 1044 + .driver = { 1045 + .name = "max77675", 1046 + .of_match_table = of_match_ptr(max77675_of_match), 1047 + }, 1048 + .probe = max77675_regulator_probe, 1049 + .id_table = max77675_i2c_id, 1050 + }; 1051 + 1052 + module_i2c_driver(max77675_regulator_driver); 1053 + 1054 + MODULE_DESCRIPTION("MAX77675 Regulator Driver"); 1055 + MODULE_AUTHOR("Joan Na <joan.na@analog.com>"); 1056 + MODULE_LICENSE("GPL");