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

mfd: sec: Add support for S2MPU05 PMIC

Add support for Samsung's S2MPU05 PMIC. It's the primary PMIC used by
Exynos7870 devices. It houses regulators (21 LDOs and 5 BUCKs) and a RTC
clock device.

Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20250301-exynos7870-pmic-regulators-v3-2-808d0b47a564@disroot.org
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Kaustabh Chakraborty and committed by
Lee Jones
ed33479b 07ef6dc9

+274
+12
drivers/mfd/sec-core.c
··· 83 83 { .name = "s2mpu02-regulator", }, 84 84 }; 85 85 86 + static const struct mfd_cell s2mpu05_devs[] = { 87 + { .name = "s2mpu05-regulator", }, 88 + { .name = "s2mps15-rtc", }, 89 + }; 90 + 86 91 static const struct of_device_id sec_dt_match[] = { 87 92 { 88 93 .compatible = "samsung,s5m8767-pmic", ··· 113 108 }, { 114 109 .compatible = "samsung,s2mpu02-pmic", 115 110 .data = (void *)S2MPU02, 111 + }, { 112 + .compatible = "samsung,s2mpu05-pmic", 113 + .data = (void *)S2MPU05, 116 114 }, { 117 115 /* Sentinel */ 118 116 }, ··· 381 373 case S2MPU02: 382 374 sec_devs = s2mpu02_devs; 383 375 num_sec_devs = ARRAY_SIZE(s2mpu02_devs); 376 + break; 377 + case S2MPU05: 378 + sec_devs = s2mpu05_devs; 379 + num_sec_devs = ARRAY_SIZE(s2mpu05_devs); 384 380 break; 385 381 default: 386 382 dev_err(&i2c->dev, "Unsupported device type (%lu)\n",
+34
drivers/mfd/sec-irq.c
··· 14 14 #include <linux/mfd/samsung/s2mps11.h> 15 15 #include <linux/mfd/samsung/s2mps14.h> 16 16 #include <linux/mfd/samsung/s2mpu02.h> 17 + #include <linux/mfd/samsung/s2mpu05.h> 17 18 #include <linux/mfd/samsung/s5m8767.h> 18 19 19 20 static const struct regmap_irq s2mps11_irqs[] = { ··· 226 225 }, 227 226 }; 228 227 228 + static const struct regmap_irq s2mpu05_irqs[] = { 229 + REGMAP_IRQ_REG(S2MPU05_IRQ_PWRONF, 0, S2MPU05_IRQ_PWRONF_MASK), 230 + REGMAP_IRQ_REG(S2MPU05_IRQ_PWRONR, 0, S2MPU05_IRQ_PWRONR_MASK), 231 + REGMAP_IRQ_REG(S2MPU05_IRQ_JIGONBF, 0, S2MPU05_IRQ_JIGONBF_MASK), 232 + REGMAP_IRQ_REG(S2MPU05_IRQ_JIGONBR, 0, S2MPU05_IRQ_JIGONBR_MASK), 233 + REGMAP_IRQ_REG(S2MPU05_IRQ_ACOKF, 0, S2MPU05_IRQ_ACOKF_MASK), 234 + REGMAP_IRQ_REG(S2MPU05_IRQ_ACOKR, 0, S2MPU05_IRQ_ACOKR_MASK), 235 + REGMAP_IRQ_REG(S2MPU05_IRQ_PWRON1S, 0, S2MPU05_IRQ_PWRON1S_MASK), 236 + REGMAP_IRQ_REG(S2MPU05_IRQ_MRB, 0, S2MPU05_IRQ_MRB_MASK), 237 + REGMAP_IRQ_REG(S2MPU05_IRQ_RTC60S, 1, S2MPU05_IRQ_RTC60S_MASK), 238 + REGMAP_IRQ_REG(S2MPU05_IRQ_RTCA1, 1, S2MPU05_IRQ_RTCA1_MASK), 239 + REGMAP_IRQ_REG(S2MPU05_IRQ_RTCA0, 1, S2MPU05_IRQ_RTCA0_MASK), 240 + REGMAP_IRQ_REG(S2MPU05_IRQ_SMPL, 1, S2MPU05_IRQ_SMPL_MASK), 241 + REGMAP_IRQ_REG(S2MPU05_IRQ_RTC1S, 1, S2MPU05_IRQ_RTC1S_MASK), 242 + REGMAP_IRQ_REG(S2MPU05_IRQ_WTSR, 1, S2MPU05_IRQ_WTSR_MASK), 243 + REGMAP_IRQ_REG(S2MPU05_IRQ_INT120C, 2, S2MPU05_IRQ_INT120C_MASK), 244 + REGMAP_IRQ_REG(S2MPU05_IRQ_INT140C, 2, S2MPU05_IRQ_INT140C_MASK), 245 + REGMAP_IRQ_REG(S2MPU05_IRQ_TSD, 2, S2MPU05_IRQ_TSD_MASK), 246 + }; 247 + 229 248 static const struct regmap_irq s5m8767_irqs[] = { 230 249 [S5M8767_IRQ_PWRR] = { 231 250 .reg_offset = 0, ··· 360 339 .ack_base = S2MPU02_REG_INT1, 361 340 }; 362 341 342 + static const struct regmap_irq_chip s2mpu05_irq_chip = { 343 + .name = "s2mpu05", 344 + .irqs = s2mpu05_irqs, 345 + .num_irqs = ARRAY_SIZE(s2mpu05_irqs), 346 + .num_regs = 3, 347 + .status_base = S2MPU05_REG_INT1, 348 + .mask_base = S2MPU05_REG_INT1M, 349 + .ack_base = S2MPU05_REG_INT1, 350 + }; 351 + 363 352 static const struct regmap_irq_chip s5m8767_irq_chip = { 364 353 .name = "s5m8767", 365 354 .irqs = s5m8767_irqs, ··· 413 382 break; 414 383 case S2MPU02: 415 384 sec_irq_chip = &s2mpu02_irq_chip; 385 + break; 386 + case S2MPU05: 387 + sec_irq_chip = &s2mpu05_irq_chip; 416 388 break; 417 389 default: 418 390 dev_err(sec_pmic->dev, "Unknown device type %lu\n",
+1
include/linux/mfd/samsung/core.h
··· 44 44 S2MPS14X, 45 45 S2MPS15X, 46 46 S2MPU02, 47 + S2MPU05, 47 48 }; 48 49 49 50 /**
+44
include/linux/mfd/samsung/irq.h
··· 150 150 /* Masks for interrupts are the same as in s2mps11 */ 151 151 #define S2MPS14_IRQ_TSD_MASK (1 << 2) 152 152 153 + enum s2mpu05_irq { 154 + S2MPU05_IRQ_PWRONF, 155 + S2MPU05_IRQ_PWRONR, 156 + S2MPU05_IRQ_JIGONBF, 157 + S2MPU05_IRQ_JIGONBR, 158 + S2MPU05_IRQ_ACOKF, 159 + S2MPU05_IRQ_ACOKR, 160 + S2MPU05_IRQ_PWRON1S, 161 + S2MPU05_IRQ_MRB, 162 + 163 + S2MPU05_IRQ_RTC60S, 164 + S2MPU05_IRQ_RTCA1, 165 + S2MPU05_IRQ_RTCA0, 166 + S2MPU05_IRQ_SMPL, 167 + S2MPU05_IRQ_RTC1S, 168 + S2MPU05_IRQ_WTSR, 169 + 170 + S2MPU05_IRQ_INT120C, 171 + S2MPU05_IRQ_INT140C, 172 + S2MPU05_IRQ_TSD, 173 + 174 + S2MPU05_IRQ_NR, 175 + }; 176 + 177 + #define S2MPU05_IRQ_PWRONF_MASK BIT(0) 178 + #define S2MPU05_IRQ_PWRONR_MASK BIT(1) 179 + #define S2MPU05_IRQ_JIGONBF_MASK BIT(2) 180 + #define S2MPU05_IRQ_JIGONBR_MASK BIT(3) 181 + #define S2MPU05_IRQ_ACOKF_MASK BIT(4) 182 + #define S2MPU05_IRQ_ACOKR_MASK BIT(5) 183 + #define S2MPU05_IRQ_PWRON1S_MASK BIT(6) 184 + #define S2MPU05_IRQ_MRB_MASK BIT(7) 185 + 186 + #define S2MPU05_IRQ_RTC60S_MASK BIT(0) 187 + #define S2MPU05_IRQ_RTCA1_MASK BIT(1) 188 + #define S2MPU05_IRQ_RTCA0_MASK BIT(2) 189 + #define S2MPU05_IRQ_SMPL_MASK BIT(3) 190 + #define S2MPU05_IRQ_RTC1S_MASK BIT(4) 191 + #define S2MPU05_IRQ_WTSR_MASK BIT(5) 192 + 193 + #define S2MPU05_IRQ_INT120C_MASK BIT(0) 194 + #define S2MPU05_IRQ_INT140C_MASK BIT(1) 195 + #define S2MPU05_IRQ_TSD_MASK BIT(2) 196 + 153 197 enum s5m8767_irq { 154 198 S5M8767_IRQ_PWRR, 155 199 S5M8767_IRQ_PWRF,
+183
include/linux/mfd/samsung/s2mpu05.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (c) 2015 Samsung Electronics Co., Ltd 4 + * Copyright (c) 2025 Kaustabh Chakraborty <kauschluss@disroot.org> 5 + */ 6 + 7 + #ifndef __LINUX_MFD_S2MPU05_H 8 + #define __LINUX_MFD_S2MPU05_H 9 + 10 + /* S2MPU05 registers */ 11 + enum S2MPU05_reg { 12 + S2MPU05_REG_ID, 13 + S2MPU05_REG_INT1, 14 + S2MPU05_REG_INT2, 15 + S2MPU05_REG_INT3, 16 + S2MPU05_REG_INT1M, 17 + S2MPU05_REG_INT2M, 18 + S2MPU05_REG_INT3M, 19 + S2MPU05_REG_ST1, 20 + S2MPU05_REG_ST2, 21 + S2MPU05_REG_PWRONSRC, 22 + S2MPU05_REG_OFFSRC, 23 + S2MPU05_REG_BU_CHG, 24 + S2MPU05_REG_RTC_BUF, 25 + S2MPU05_REG_CTRL1, 26 + S2MPU05_REG_CTRL2, 27 + S2MPU05_REG_ETC_TEST, 28 + S2MPU05_REG_OTP_ADRL, 29 + S2MPU05_REG_OTP_ADRH, 30 + S2MPU05_REG_OTP_DATA, 31 + S2MPU05_REG_MON1SEL, 32 + S2MPU05_REG_MON2SEL, 33 + S2MPU05_REG_CTRL3, 34 + S2MPU05_REG_ETC_OTP, 35 + S2MPU05_REG_UVLO, 36 + S2MPU05_REG_TIME_CTRL1, 37 + S2MPU05_REG_TIME_CTRL2, 38 + S2MPU05_REG_B1CTRL1, 39 + S2MPU05_REG_B1CTRL2, 40 + S2MPU05_REG_B2CTRL1, 41 + S2MPU05_REG_B2CTRL2, 42 + S2MPU05_REG_B2CTRL3, 43 + S2MPU05_REG_B2CTRL4, 44 + S2MPU05_REG_B3CTRL1, 45 + S2MPU05_REG_B3CTRL2, 46 + S2MPU05_REG_B3CTRL3, 47 + S2MPU05_REG_B4CTRL1, 48 + S2MPU05_REG_B4CTRL2, 49 + S2MPU05_REG_B5CTRL1, 50 + S2MPU05_REG_B5CTRL2, 51 + S2MPU05_REG_BUCK_RAMP, 52 + S2MPU05_REG_LDO_DVS1, 53 + S2MPU05_REG_LDO_DVS9, 54 + S2MPU05_REG_LDO_DVS10, 55 + S2MPU05_REG_L1CTRL, 56 + S2MPU05_REG_L2CTRL, 57 + S2MPU05_REG_L3CTRL, 58 + S2MPU05_REG_L4CTRL, 59 + S2MPU05_REG_L5CTRL, 60 + S2MPU05_REG_L6CTRL, 61 + S2MPU05_REG_L7CTRL, 62 + S2MPU05_REG_L8CTRL, 63 + S2MPU05_REG_L9CTRL1, 64 + S2MPU05_REG_L9CTRL2, 65 + S2MPU05_REG_L10CTRL, 66 + S2MPU05_REG_L11CTRL1, 67 + S2MPU05_REG_L11CTRL2, 68 + S2MPU05_REG_L12CTRL, 69 + S2MPU05_REG_L13CTRL, 70 + S2MPU05_REG_L14CTRL, 71 + S2MPU05_REG_L15CTRL, 72 + S2MPU05_REG_L16CTRL, 73 + S2MPU05_REG_L17CTRL1, 74 + S2MPU05_REG_L17CTRL2, 75 + S2MPU05_REG_L18CTRL1, 76 + S2MPU05_REG_L18CTRL2, 77 + S2MPU05_REG_L19CTRL, 78 + S2MPU05_REG_L20CTRL, 79 + S2MPU05_REG_L21CTRL, 80 + S2MPU05_REG_L22CTRL, 81 + S2MPU05_REG_L23CTRL, 82 + S2MPU05_REG_L24CTRL, 83 + S2MPU05_REG_L25CTRL, 84 + S2MPU05_REG_L26CTRL, 85 + S2MPU05_REG_L27CTRL, 86 + S2MPU05_REG_L28CTRL, 87 + S2MPU05_REG_L29CTRL, 88 + S2MPU05_REG_L30CTRL, 89 + S2MPU05_REG_L31CTRL, 90 + S2MPU05_REG_L32CTRL, 91 + S2MPU05_REG_L33CTRL, 92 + S2MPU05_REG_L34CTRL, 93 + S2MPU05_REG_L35CTRL, 94 + S2MPU05_REG_LDO_DSCH1, 95 + S2MPU05_REG_LDO_DSCH2, 96 + S2MPU05_REG_LDO_DSCH3, 97 + S2MPU05_REG_LDO_DSCH4, 98 + S2MPU05_REG_LDO_DSCH5, 99 + S2MPU05_REG_LDO_CTRL1, 100 + S2MPU05_REG_LDO_CTRL2, 101 + S2MPU05_REG_TCXO_CTRL, 102 + S2MPU05_REG_SELMIF, 103 + }; 104 + 105 + /* S2MPU05 regulator ids */ 106 + enum S2MPU05_regulators { 107 + S2MPU05_LDO1, 108 + S2MPU05_LDO2, 109 + S2MPU05_LDO3, 110 + S2MPU05_LDO4, 111 + S2MPU05_LDO5, 112 + S2MPU05_LDO6, 113 + S2MPU05_LDO7, 114 + S2MPU05_LDO8, 115 + S2MPU05_LDO9, 116 + S2MPU05_LDO10, 117 + S2MPU05_LDO11, 118 + S2MPU05_LDO12, 119 + S2MPU05_LDO13, 120 + S2MPU05_LDO14, 121 + S2MPU05_LDO15, 122 + S2MPU05_LDO16, 123 + S2MPU05_LDO17, 124 + S2MPU05_LDO18, 125 + S2MPU05_LDO19, 126 + S2MPU05_LDO20, 127 + S2MPU05_LDO21, 128 + S2MPU05_LDO22, 129 + S2MPU05_LDO23, 130 + S2MPU05_LDO24, 131 + S2MPU05_LDO25, 132 + S2MPU05_LDO26, 133 + S2MPU05_LDO27, 134 + S2MPU05_LDO28, 135 + S2MPU05_LDO29, 136 + S2MPU05_LDO30, 137 + S2MPU05_LDO31, 138 + S2MPU05_LDO32, 139 + S2MPU05_LDO33, 140 + S2MPU05_LDO34, 141 + S2MPU05_LDO35, 142 + S2MPU05_BUCK1, 143 + S2MPU05_BUCK2, 144 + S2MPU05_BUCK3, 145 + S2MPU05_BUCK4, 146 + S2MPU05_BUCK5, 147 + 148 + S2MPU05_REGULATOR_MAX, 149 + }; 150 + 151 + #define S2MPU05_SW_ENABLE_MASK 0x03 152 + 153 + #define S2MPU05_ENABLE_TIME_LDO 128 154 + #define S2MPU05_ENABLE_TIME_BUCK1 110 155 + #define S2MPU05_ENABLE_TIME_BUCK2 110 156 + #define S2MPU05_ENABLE_TIME_BUCK3 110 157 + #define S2MPU05_ENABLE_TIME_BUCK4 150 158 + #define S2MPU05_ENABLE_TIME_BUCK5 150 159 + 160 + #define S2MPU05_LDO_MIN1 800000 161 + #define S2MPU05_LDO_MIN2 1800000 162 + #define S2MPU05_LDO_MIN3 400000 163 + #define S2MPU05_LDO_STEP1 12500 164 + #define S2MPU05_LDO_STEP2 25000 165 + 166 + #define S2MPU05_BUCK_MIN1 400000 167 + #define S2MPU05_BUCK_MIN2 600000 168 + #define S2MPU05_BUCK_STEP1 6250 169 + #define S2MPU05_BUCK_STEP2 12500 170 + 171 + #define S2MPU05_RAMP_DELAY 12000 /* uV/uS */ 172 + 173 + #define S2MPU05_ENABLE_SHIFT 6 174 + #define S2MPU05_ENABLE_MASK (0x03 << S2MPU05_ENABLE_SHIFT) 175 + 176 + #define S2MPU05_LDO_VSEL_MASK 0x3F 177 + #define S2MPU05_BUCK_VSEL_MASK 0xFF 178 + #define S2MPU05_LDO_N_VOLTAGES (S2MPU05_LDO_VSEL_MASK + 1) 179 + #define S2MPU05_BUCK_N_VOLTAGES (S2MPU05_BUCK_VSEL_MASK + 1) 180 + 181 + #define S2MPU05_PMIC_EN_SHIFT 6 182 + 183 + #endif /* __LINUX_MFD_S2MPU05_H */