1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2012 Samsung Electronics Co., Ltd 4 * http://www.samsung.com 5 * Copyright 2025 Linaro Ltd. 6 * 7 * Samsung SxM core driver 8 */ 9 10 #include <linux/device.h> 11 #include <linux/err.h> 12 #include <linux/export.h> 13 #include <linux/interrupt.h> 14 #include <linux/mfd/core.h> 15 #include <linux/mfd/samsung/core.h> 16 #include <linux/mfd/samsung/irq.h> 17 #include <linux/mfd/samsung/s2mps11.h> 18 #include <linux/mfd/samsung/s2mps13.h> 19 #include <linux/mfd/samsung/s2mu005.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/pm.h> 23 #include <linux/pm_runtime.h> 24 #include <linux/regmap.h> 25 #include "sec-core.h" 26 27 static const struct resource s5m8767_rtc_resources[] = { 28 DEFINE_RES_IRQ_NAMED(S5M8767_IRQ_RTCA1, "alarm"), 29 }; 30 31 static const struct mfd_cell s5m8767_devs[] = { 32 MFD_CELL_NAME("s5m8767-pmic"), 33 MFD_CELL_RES("s5m-rtc", s5m8767_rtc_resources), 34 MFD_CELL_OF("s5m8767-clk", NULL, NULL, 0, 0, "samsung,s5m8767-clk"), 35 }; 36 37 static const struct mfd_cell s2dos05_devs[] = { 38 MFD_CELL_NAME("s2dos05-regulator"), 39 }; 40 41 static const struct resource s2mpg10_rtc_resources[] = { 42 DEFINE_RES_IRQ_NAMED(S2MPG10_IRQ_RTCA0, "alarm"), 43 }; 44 45 static const struct mfd_cell s2mpg10_devs[] = { 46 MFD_CELL_NAME("s2mpg10-meter"), 47 MFD_CELL_NAME("s2mpg10-regulator"), 48 MFD_CELL_RES("s2mpg10-rtc", s2mpg10_rtc_resources), 49 MFD_CELL_OF("s2mpg10-clk", NULL, NULL, 0, 0, "samsung,s2mpg10-clk"), 50 MFD_CELL_OF("s2mpg10-gpio", NULL, NULL, 0, 0, "samsung,s2mpg10-gpio"), 51 }; 52 53 static const struct mfd_cell s2mpg11_devs[] = { 54 MFD_CELL_NAME("s2mpg11-meter"), 55 MFD_CELL_NAME("s2mpg11-regulator"), 56 MFD_CELL_OF("s2mpg11-gpio", NULL, NULL, 0, 0, "samsung,s2mpg11-gpio"), 57 }; 58 59 static const struct resource s2mps11_rtc_resources[] = { 60 DEFINE_RES_IRQ_NAMED(S2MPS11_IRQ_RTCA0, "alarm"), 61 }; 62 63 static const struct mfd_cell s2mps11_devs[] = { 64 MFD_CELL_NAME("s2mps11-regulator"), 65 MFD_CELL_RES("s2mps14-rtc", s2mps11_rtc_resources), 66 MFD_CELL_OF("s2mps11-clk", NULL, NULL, 0, 0, "samsung,s2mps11-clk"), 67 }; 68 69 static const struct resource s2mps14_rtc_resources[] = { 70 DEFINE_RES_IRQ_NAMED(S2MPS14_IRQ_RTCA0, "alarm"), 71 }; 72 73 static const struct mfd_cell s2mps13_devs[] = { 74 MFD_CELL_NAME("s2mps13-regulator"), 75 MFD_CELL_RES("s2mps13-rtc", s2mps14_rtc_resources), 76 MFD_CELL_OF("s2mps13-clk", NULL, NULL, 0, 0, "samsung,s2mps13-clk"), 77 }; 78 79 static const struct mfd_cell s2mps14_devs[] = { 80 MFD_CELL_NAME("s2mps14-regulator"), 81 MFD_CELL_RES("s2mps14-rtc", s2mps14_rtc_resources), 82 MFD_CELL_OF("s2mps14-clk", NULL, NULL, 0, 0, "samsung,s2mps14-clk"), 83 }; 84 85 static const struct mfd_cell s2mps15_devs[] = { 86 MFD_CELL_NAME("s2mps15-regulator"), 87 MFD_CELL_RES("s2mps15-rtc", s2mps14_rtc_resources), 88 MFD_CELL_OF("s2mps13-clk", NULL, NULL, 0, 0, "samsung,s2mps13-clk"), 89 }; 90 91 static const struct mfd_cell s2mpa01_devs[] = { 92 MFD_CELL_NAME("s2mpa01-pmic"), 93 MFD_CELL_RES("s2mps14-rtc", s2mps14_rtc_resources), 94 }; 95 96 static const struct mfd_cell s2mpu02_devs[] = { 97 MFD_CELL_NAME("s2mpu02-regulator"), 98 }; 99 100 static const struct resource s2mpu05_rtc_resources[] = { 101 DEFINE_RES_IRQ_NAMED(S2MPU05_IRQ_RTCA0, "alarm"), 102 }; 103 104 static const struct mfd_cell s2mpu05_devs[] = { 105 MFD_CELL_NAME("s2mpu05-regulator"), 106 MFD_CELL_RES("s2mps15-rtc", s2mpu05_rtc_resources), 107 }; 108 109 static const struct resource s2mu005_muic_resources[] = { 110 DEFINE_RES_IRQ_NAMED(S2MU005_IRQ_MUIC_ATTACH, "attach"), 111 DEFINE_RES_IRQ_NAMED(S2MU005_IRQ_MUIC_DETACH, "detach"), 112 }; 113 114 static const struct mfd_cell s2mu005_devs[] = { 115 MFD_CELL_NAME("s2mu005-charger"), 116 MFD_CELL_OF("s2mu005-flash", NULL, NULL, 0, 0, "samsung,s2mu005-flash"), 117 MFD_CELL_OF("s2mu005-muic", s2mu005_muic_resources, NULL, 0, 0, "samsung,s2mu005-muic"), 118 MFD_CELL_OF("s2mu005-rgb", NULL, NULL, 0, 0, "samsung,s2mu005-rgb"), 119 }; 120 121 static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic) 122 { 123 unsigned int reg, mask, val; 124 125 switch (sec_pmic->device_type) { 126 case S2MPG10: 127 case S2MPG11: 128 /* For s2mpg1x, the revision is in a different regmap */ 129 return; 130 case S2MU005: 131 reg = S2MU005_REG_ID; 132 mask = S2MU005_ID_MASK; 133 break; 134 default: 135 /* For other device types, REG_ID is always the first register. */ 136 reg = S2MPS11_REG_ID; 137 mask = ~0; 138 } 139 140 if (!regmap_read(sec_pmic->regmap_pmic, reg, &val)) 141 dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", field_get(mask, val)); 142 } 143 144 static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic) 145 { 146 int err; 147 148 if (sec_pmic->device_type != S2MPS13X) 149 return; 150 151 if (sec_pmic->pdata->disable_wrstbi) { 152 /* 153 * If WRSTBI pin is pulled down this feature must be disabled 154 * because each Suspend to RAM will trigger buck voltage reset 155 * to default values. 156 */ 157 err = regmap_update_bits(sec_pmic->regmap_pmic, 158 S2MPS13_REG_WRSTBI, 159 S2MPS13_REG_WRSTBI_MASK, 0x0); 160 if (err) 161 dev_warn(sec_pmic->dev, 162 "Cannot initialize WRSTBI config: %d\n", 163 err); 164 } 165 } 166 167 /* 168 * Only the common platform data elements for s5m8767 are parsed here from the 169 * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and 170 * others have to parse their own platform data elements from device tree. 171 * 172 * The s5m8767 platform data structure is instantiated here and the drivers for 173 * the sub-modules need not instantiate another instance while parsing their 174 * platform data. 175 */ 176 static struct sec_platform_data * 177 sec_pmic_parse_dt_pdata(struct device *dev) 178 { 179 struct sec_platform_data *pd; 180 181 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); 182 if (!pd) 183 return ERR_PTR(-ENOMEM); 184 185 pd->manual_poweroff = of_property_read_bool(dev->of_node, 186 "samsung,s2mps11-acokb-ground"); 187 pd->disable_wrstbi = of_property_read_bool(dev->of_node, 188 "samsung,s2mps11-wrstbi-ground"); 189 return pd; 190 } 191 192 int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq, 193 struct regmap *regmap, struct i2c_client *client) 194 { 195 struct regmap_irq_chip_data *irq_data; 196 struct sec_platform_data *pdata; 197 const struct mfd_cell *sec_devs; 198 struct sec_pmic_dev *sec_pmic; 199 int ret, num_sec_devs; 200 201 sec_pmic = devm_kzalloc(dev, sizeof(*sec_pmic), GFP_KERNEL); 202 if (!sec_pmic) 203 return -ENOMEM; 204 205 dev_set_drvdata(dev, sec_pmic); 206 sec_pmic->dev = dev; 207 sec_pmic->device_type = device_type; 208 sec_pmic->i2c = client; 209 sec_pmic->irq = irq; 210 sec_pmic->regmap_pmic = regmap; 211 212 pdata = sec_pmic_parse_dt_pdata(sec_pmic->dev); 213 if (IS_ERR(pdata)) { 214 ret = PTR_ERR(pdata); 215 return ret; 216 } 217 218 sec_pmic->pdata = pdata; 219 220 irq_data = sec_irq_init(sec_pmic); 221 if (IS_ERR(irq_data)) 222 return PTR_ERR(irq_data); 223 224 dev->coherent_dma_mask = 0; 225 dev->dma_mask = &dev->coherent_dma_mask; 226 227 pm_runtime_set_active(sec_pmic->dev); 228 229 switch (sec_pmic->device_type) { 230 case S5M8767X: 231 sec_devs = s5m8767_devs; 232 num_sec_devs = ARRAY_SIZE(s5m8767_devs); 233 break; 234 case S2DOS05: 235 sec_devs = s2dos05_devs; 236 num_sec_devs = ARRAY_SIZE(s2dos05_devs); 237 break; 238 case S2MPA01: 239 sec_devs = s2mpa01_devs; 240 num_sec_devs = ARRAY_SIZE(s2mpa01_devs); 241 break; 242 case S2MPG10: 243 sec_devs = s2mpg10_devs; 244 num_sec_devs = ARRAY_SIZE(s2mpg10_devs); 245 break; 246 case S2MPG11: 247 sec_devs = s2mpg11_devs; 248 num_sec_devs = ARRAY_SIZE(s2mpg11_devs); 249 break; 250 case S2MPS11X: 251 sec_devs = s2mps11_devs; 252 num_sec_devs = ARRAY_SIZE(s2mps11_devs); 253 break; 254 case S2MPS13X: 255 sec_devs = s2mps13_devs; 256 num_sec_devs = ARRAY_SIZE(s2mps13_devs); 257 break; 258 case S2MPS14X: 259 sec_devs = s2mps14_devs; 260 num_sec_devs = ARRAY_SIZE(s2mps14_devs); 261 break; 262 case S2MPS15X: 263 sec_devs = s2mps15_devs; 264 num_sec_devs = ARRAY_SIZE(s2mps15_devs); 265 break; 266 case S2MPU02: 267 sec_devs = s2mpu02_devs; 268 num_sec_devs = ARRAY_SIZE(s2mpu02_devs); 269 break; 270 case S2MPU05: 271 sec_devs = s2mpu05_devs; 272 num_sec_devs = ARRAY_SIZE(s2mpu05_devs); 273 break; 274 case S2MU005: 275 sec_devs = s2mu005_devs; 276 num_sec_devs = ARRAY_SIZE(s2mu005_devs); 277 break; 278 default: 279 return dev_err_probe(sec_pmic->dev, -EINVAL, 280 "Unsupported device type %d\n", 281 sec_pmic->device_type); 282 } 283 ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, 284 NULL, 0, regmap_irq_get_domain(irq_data)); 285 if (ret) 286 return ret; 287 288 sec_pmic_configure(sec_pmic); 289 sec_pmic_dump_rev(sec_pmic); 290 291 return ret; 292 } 293 EXPORT_SYMBOL_GPL(sec_pmic_probe); 294 295 void sec_pmic_shutdown(struct device *dev) 296 { 297 struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev); 298 unsigned int reg, mask; 299 300 if (!sec_pmic->pdata->manual_poweroff) 301 return; 302 303 switch (sec_pmic->device_type) { 304 case S2MPS11X: 305 reg = S2MPS11_REG_CTRL1; 306 mask = S2MPS11_CTRL1_PWRHOLD_MASK; 307 break; 308 default: 309 /* 310 * Currently only one board with S2MPS11 needs this, so just 311 * ignore the rest. 312 */ 313 dev_warn(sec_pmic->dev, 314 "Unsupported device %d for manual power off\n", 315 sec_pmic->device_type); 316 return; 317 } 318 319 regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0); 320 } 321 EXPORT_SYMBOL_GPL(sec_pmic_shutdown); 322 323 static int sec_pmic_suspend(struct device *dev) 324 { 325 struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev); 326 327 if (device_may_wakeup(dev)) 328 enable_irq_wake(sec_pmic->irq); 329 /* 330 * PMIC IRQ must be disabled during suspend for RTC alarm 331 * to work properly. 332 * When device is woken up from suspend, an 333 * interrupt occurs before resuming I2C bus controller. 334 * The interrupt is handled by regmap_irq_thread which tries 335 * to read RTC registers. This read fails (I2C is still 336 * suspended) and RTC Alarm interrupt is disabled. 337 */ 338 disable_irq(sec_pmic->irq); 339 340 return 0; 341 } 342 343 static int sec_pmic_resume(struct device *dev) 344 { 345 struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev); 346 347 if (device_may_wakeup(dev)) 348 disable_irq_wake(sec_pmic->irq); 349 enable_irq(sec_pmic->irq); 350 351 return 0; 352 } 353 354 DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); 355 EXPORT_SYMBOL_GPL(sec_pmic_pm_ops); 356 357 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); 358 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); 359 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 360 MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 361 MODULE_DESCRIPTION("Core driver for the Samsung S5M"); 362 MODULE_LICENSE("GPL"); 363