1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2020 Google Inc 4 * Copyright 2025 Linaro Ltd. 5 * 6 * Samsung S2MPG1x ACPM driver 7 */ 8 9 #include <linux/array_size.h> 10 #include <linux/bitops.h> 11 #include <linux/device.h> 12 #include <linux/firmware/samsung/exynos-acpm-protocol.h> 13 #include <linux/mfd/samsung/core.h> 14 #include <linux/mfd/samsung/rtc.h> 15 #include <linux/mfd/samsung/s2mpg10.h> 16 #include <linux/mod_devicetable.h> 17 #include <linux/module.h> 18 #include <linux/of.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm.h> 21 #include <linux/property.h> 22 #include <linux/regmap.h> 23 #include "sec-core.h" 24 25 #define ACPM_ADDR_BITS 8 26 #define ACPM_MAX_BULK_DATA 8 27 28 struct sec_pmic_acpm_platform_data { 29 int device_type; 30 31 unsigned int acpm_chan_id; 32 u8 speedy_channel; 33 34 const struct regmap_config *regmap_cfg_common; 35 const struct regmap_config *regmap_cfg_pmic; 36 const struct regmap_config *regmap_cfg_rtc; 37 const struct regmap_config *regmap_cfg_meter; 38 }; 39 40 static const struct regmap_range s2mpg10_common_registers[] = { 41 regmap_reg_range(0x00, 0x02), /* CHIP_ID_M, INT, INT_MASK */ 42 regmap_reg_range(0x0a, 0x0c), /* Speedy control */ 43 regmap_reg_range(0x1a, 0x2a), /* Debug */ 44 }; 45 46 static const struct regmap_range s2mpg10_common_ro_registers[] = { 47 regmap_reg_range(0x00, 0x01), /* CHIP_ID_M, INT */ 48 regmap_reg_range(0x28, 0x2a), /* Debug */ 49 }; 50 51 static const struct regmap_range s2mpg10_common_nonvolatile_registers[] = { 52 regmap_reg_range(0x00, 0x00), /* CHIP_ID_M */ 53 regmap_reg_range(0x02, 0x02), /* INT_MASK */ 54 regmap_reg_range(0x0a, 0x0c), /* Speedy control */ 55 }; 56 57 static const struct regmap_range s2mpg10_common_precious_registers[] = { 58 regmap_reg_range(0x01, 0x01), /* INT */ 59 }; 60 61 static const struct regmap_access_table s2mpg10_common_wr_table = { 62 .yes_ranges = s2mpg10_common_registers, 63 .n_yes_ranges = ARRAY_SIZE(s2mpg10_common_registers), 64 .no_ranges = s2mpg10_common_ro_registers, 65 .n_no_ranges = ARRAY_SIZE(s2mpg10_common_ro_registers), 66 }; 67 68 static const struct regmap_access_table s2mpg10_common_rd_table = { 69 .yes_ranges = s2mpg10_common_registers, 70 .n_yes_ranges = ARRAY_SIZE(s2mpg10_common_registers), 71 }; 72 73 static const struct regmap_access_table s2mpg10_common_volatile_table = { 74 .no_ranges = s2mpg10_common_nonvolatile_registers, 75 .n_no_ranges = ARRAY_SIZE(s2mpg10_common_nonvolatile_registers), 76 }; 77 78 static const struct regmap_access_table s2mpg10_common_precious_table = { 79 .yes_ranges = s2mpg10_common_precious_registers, 80 .n_yes_ranges = ARRAY_SIZE(s2mpg10_common_precious_registers), 81 }; 82 83 static const struct regmap_config s2mpg10_regmap_config_common = { 84 .name = "common", 85 .reg_bits = ACPM_ADDR_BITS, 86 .val_bits = 8, 87 .max_register = S2MPG10_COMMON_SPD_DEBUG4, 88 .wr_table = &s2mpg10_common_wr_table, 89 .rd_table = &s2mpg10_common_rd_table, 90 .volatile_table = &s2mpg10_common_volatile_table, 91 .precious_table = &s2mpg10_common_precious_table, 92 .num_reg_defaults_raw = S2MPG10_COMMON_SPD_DEBUG4 + 1, 93 .cache_type = REGCACHE_FLAT, 94 }; 95 96 static const struct regmap_range s2mpg10_pmic_registers[] = { 97 regmap_reg_range(0x00, 0xf6), /* All PMIC registers */ 98 }; 99 100 static const struct regmap_range s2mpg10_pmic_ro_registers[] = { 101 regmap_reg_range(0x00, 0x05), /* INTx */ 102 regmap_reg_range(0x0c, 0x0f), /* STATUSx PWRONSRC OFFSRC */ 103 regmap_reg_range(0xc7, 0xc7), /* GPIO input */ 104 }; 105 106 static const struct regmap_range s2mpg10_pmic_nonvolatile_registers[] = { 107 regmap_reg_range(0x06, 0x0b), /* INTxM */ 108 }; 109 110 static const struct regmap_range s2mpg10_pmic_precious_registers[] = { 111 regmap_reg_range(0x00, 0x05), /* INTx */ 112 }; 113 114 static const struct regmap_access_table s2mpg10_pmic_wr_table = { 115 .yes_ranges = s2mpg10_pmic_registers, 116 .n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_registers), 117 .no_ranges = s2mpg10_pmic_ro_registers, 118 .n_no_ranges = ARRAY_SIZE(s2mpg10_pmic_ro_registers), 119 }; 120 121 static const struct regmap_access_table s2mpg10_pmic_rd_table = { 122 .yes_ranges = s2mpg10_pmic_registers, 123 .n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_registers), 124 }; 125 126 static const struct regmap_access_table s2mpg10_pmic_volatile_table = { 127 .no_ranges = s2mpg10_pmic_nonvolatile_registers, 128 .n_no_ranges = ARRAY_SIZE(s2mpg10_pmic_nonvolatile_registers), 129 }; 130 131 static const struct regmap_access_table s2mpg10_pmic_precious_table = { 132 .yes_ranges = s2mpg10_pmic_precious_registers, 133 .n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_precious_registers), 134 }; 135 136 static const struct regmap_config s2mpg10_regmap_config_pmic = { 137 .name = "pmic", 138 .reg_bits = ACPM_ADDR_BITS, 139 .val_bits = 8, 140 .max_register = S2MPG10_PMIC_LDO_SENSE4, 141 .wr_table = &s2mpg10_pmic_wr_table, 142 .rd_table = &s2mpg10_pmic_rd_table, 143 .volatile_table = &s2mpg10_pmic_volatile_table, 144 .precious_table = &s2mpg10_pmic_precious_table, 145 .num_reg_defaults_raw = S2MPG10_PMIC_LDO_SENSE4 + 1, 146 .cache_type = REGCACHE_FLAT, 147 }; 148 149 static const struct regmap_range s2mpg10_rtc_registers[] = { 150 regmap_reg_range(0x00, 0x2b), /* All RTC registers */ 151 }; 152 153 static const struct regmap_range s2mpg10_rtc_volatile_registers[] = { 154 regmap_reg_range(0x01, 0x01), /* RTC_UPDATE */ 155 regmap_reg_range(0x05, 0x0c), /* Time / date */ 156 }; 157 158 static const struct regmap_access_table s2mpg10_rtc_rd_table = { 159 .yes_ranges = s2mpg10_rtc_registers, 160 .n_yes_ranges = ARRAY_SIZE(s2mpg10_rtc_registers), 161 }; 162 163 static const struct regmap_access_table s2mpg10_rtc_volatile_table = { 164 .yes_ranges = s2mpg10_rtc_volatile_registers, 165 .n_yes_ranges = ARRAY_SIZE(s2mpg10_rtc_volatile_registers), 166 }; 167 168 static const struct regmap_config s2mpg10_regmap_config_rtc = { 169 .name = "rtc", 170 .reg_bits = ACPM_ADDR_BITS, 171 .val_bits = 8, 172 .max_register = S2MPG10_RTC_OSC_CTRL, 173 .rd_table = &s2mpg10_rtc_rd_table, 174 .volatile_table = &s2mpg10_rtc_volatile_table, 175 .num_reg_defaults_raw = S2MPG10_RTC_OSC_CTRL + 1, 176 .cache_type = REGCACHE_FLAT, 177 }; 178 179 static const struct regmap_range s2mpg10_meter_registers[] = { 180 regmap_reg_range(0x00, 0x21), /* Meter config */ 181 regmap_reg_range(0x40, 0x8a), /* Meter data */ 182 regmap_reg_range(0xee, 0xee), /* Offset */ 183 regmap_reg_range(0xf1, 0xf1), /* Trim */ 184 }; 185 186 static const struct regmap_range s2mpg10_meter_ro_registers[] = { 187 regmap_reg_range(0x40, 0x8a), /* Meter data */ 188 }; 189 190 static const struct regmap_access_table s2mpg10_meter_wr_table = { 191 .yes_ranges = s2mpg10_meter_registers, 192 .n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_registers), 193 .no_ranges = s2mpg10_meter_ro_registers, 194 .n_no_ranges = ARRAY_SIZE(s2mpg10_meter_ro_registers), 195 }; 196 197 static const struct regmap_access_table s2mpg10_meter_rd_table = { 198 .yes_ranges = s2mpg10_meter_registers, 199 .n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_registers), 200 }; 201 202 static const struct regmap_access_table s2mpg10_meter_volatile_table = { 203 .yes_ranges = s2mpg10_meter_ro_registers, 204 .n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_ro_registers), 205 }; 206 207 static const struct regmap_config s2mpg10_regmap_config_meter = { 208 .name = "meter", 209 .reg_bits = ACPM_ADDR_BITS, 210 .val_bits = 8, 211 .max_register = S2MPG10_METER_BUCK_METER_TRIM3, 212 .wr_table = &s2mpg10_meter_wr_table, 213 .rd_table = &s2mpg10_meter_rd_table, 214 .volatile_table = &s2mpg10_meter_volatile_table, 215 .num_reg_defaults_raw = S2MPG10_METER_BUCK_METER_TRIM3 + 1, 216 .cache_type = REGCACHE_FLAT, 217 }; 218 219 struct sec_pmic_acpm_shared_bus_context { 220 const struct acpm_handle *acpm; 221 unsigned int acpm_chan_id; 222 u8 speedy_channel; 223 }; 224 225 enum sec_pmic_acpm_accesstype { 226 SEC_PMIC_ACPM_ACCESSTYPE_COMMON = 0x00, 227 SEC_PMIC_ACPM_ACCESSTYPE_PMIC = 0x01, 228 SEC_PMIC_ACPM_ACCESSTYPE_RTC = 0x02, 229 SEC_PMIC_ACPM_ACCESSTYPE_METER = 0x0a, 230 SEC_PMIC_ACPM_ACCESSTYPE_WLWP = 0x0b, 231 SEC_PMIC_ACPM_ACCESSTYPE_TRIM = 0x0f, 232 }; 233 234 struct sec_pmic_acpm_bus_context { 235 struct sec_pmic_acpm_shared_bus_context *shared; 236 enum sec_pmic_acpm_accesstype type; 237 }; 238 239 static int sec_pmic_acpm_bus_write(void *context, const void *data, 240 size_t count) 241 { 242 struct sec_pmic_acpm_bus_context *ctx = context; 243 const struct acpm_handle *acpm = ctx->shared->acpm; 244 const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops; 245 size_t val_count = count - BITS_TO_BYTES(ACPM_ADDR_BITS); 246 const u8 *d = data; 247 const u8 *vals = &d[BITS_TO_BYTES(ACPM_ADDR_BITS)]; 248 u8 reg; 249 250 if (val_count < 1 || val_count > ACPM_MAX_BULK_DATA) 251 return -EINVAL; 252 253 reg = d[0]; 254 255 return pmic_ops->bulk_write(acpm, ctx->shared->acpm_chan_id, ctx->type, reg, 256 ctx->shared->speedy_channel, val_count, vals); 257 } 258 259 static int sec_pmic_acpm_bus_read(void *context, const void *reg_buf, size_t reg_size, 260 void *val_buf, size_t val_size) 261 { 262 struct sec_pmic_acpm_bus_context *ctx = context; 263 const struct acpm_handle *acpm = ctx->shared->acpm; 264 const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops; 265 const u8 *r = reg_buf; 266 u8 reg; 267 268 if (reg_size != BITS_TO_BYTES(ACPM_ADDR_BITS) || !val_size || 269 val_size > ACPM_MAX_BULK_DATA) 270 return -EINVAL; 271 272 reg = r[0]; 273 274 return pmic_ops->bulk_read(acpm, ctx->shared->acpm_chan_id, ctx->type, reg, 275 ctx->shared->speedy_channel, val_size, val_buf); 276 } 277 278 static int sec_pmic_acpm_bus_reg_update_bits(void *context, unsigned int reg, unsigned int mask, 279 unsigned int val) 280 { 281 struct sec_pmic_acpm_bus_context *ctx = context; 282 const struct acpm_handle *acpm = ctx->shared->acpm; 283 const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops; 284 285 return pmic_ops->update_reg(acpm, ctx->shared->acpm_chan_id, ctx->type, reg & 0xff, 286 ctx->shared->speedy_channel, val, mask); 287 } 288 289 static const struct regmap_bus sec_pmic_acpm_regmap_bus = { 290 .write = sec_pmic_acpm_bus_write, 291 .read = sec_pmic_acpm_bus_read, 292 .reg_update_bits = sec_pmic_acpm_bus_reg_update_bits, 293 .max_raw_read = ACPM_MAX_BULK_DATA, 294 .max_raw_write = ACPM_MAX_BULK_DATA, 295 }; 296 297 static struct regmap *sec_pmic_acpm_regmap_init(struct device *dev, 298 struct sec_pmic_acpm_shared_bus_context *shared_ctx, 299 enum sec_pmic_acpm_accesstype type, 300 const struct regmap_config *cfg, bool do_attach) 301 { 302 struct sec_pmic_acpm_bus_context *ctx; 303 struct regmap *regmap; 304 305 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 306 if (!ctx) 307 return ERR_PTR(-ENOMEM); 308 309 ctx->shared = shared_ctx; 310 ctx->type = type; 311 312 regmap = devm_regmap_init(dev, &sec_pmic_acpm_regmap_bus, ctx, cfg); 313 if (IS_ERR(regmap)) 314 return dev_err_cast_probe(dev, regmap, "regmap init (%s) failed\n", cfg->name); 315 316 if (do_attach) { 317 int ret; 318 319 ret = regmap_attach_dev(dev, regmap, cfg); 320 if (ret) 321 return dev_err_ptr_probe(dev, ret, "regmap attach (%s) failed\n", 322 cfg->name); 323 } 324 325 return regmap; 326 } 327 328 static int sec_pmic_acpm_probe(struct platform_device *pdev) 329 { 330 struct regmap *regmap_common, *regmap_pmic, *regmap; 331 const struct sec_pmic_acpm_platform_data *pdata; 332 struct sec_pmic_acpm_shared_bus_context *shared_ctx; 333 const struct acpm_handle *acpm; 334 struct device *dev = &pdev->dev; 335 int ret, irq; 336 337 pdata = device_get_match_data(dev); 338 if (!pdata) 339 return dev_err_probe(dev, -ENODEV, "unsupported device type\n"); 340 341 acpm = devm_acpm_get_by_node(dev, dev->parent->of_node); 342 if (IS_ERR(acpm)) 343 return dev_err_probe(dev, PTR_ERR(acpm), "failed to get acpm\n"); 344 345 irq = platform_get_irq(pdev, 0); 346 if (irq < 0) 347 return irq; 348 349 shared_ctx = devm_kzalloc(dev, sizeof(*shared_ctx), GFP_KERNEL); 350 if (!shared_ctx) 351 return -ENOMEM; 352 353 shared_ctx->acpm = acpm; 354 shared_ctx->acpm_chan_id = pdata->acpm_chan_id; 355 shared_ctx->speedy_channel = pdata->speedy_channel; 356 357 regmap_common = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_COMMON, 358 pdata->regmap_cfg_common, true); 359 if (IS_ERR(regmap_common)) 360 return PTR_ERR(regmap_common); 361 362 regmap_pmic = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_PMIC, 363 pdata->regmap_cfg_pmic, false); 364 if (IS_ERR(regmap_pmic)) 365 return PTR_ERR(regmap_pmic); 366 367 regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_RTC, 368 pdata->regmap_cfg_rtc, true); 369 if (IS_ERR(regmap)) 370 return PTR_ERR(regmap); 371 372 regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_METER, 373 pdata->regmap_cfg_meter, true); 374 if (IS_ERR(regmap)) 375 return PTR_ERR(regmap); 376 377 ret = sec_pmic_probe(dev, pdata->device_type, irq, regmap_pmic, NULL); 378 if (ret) 379 return ret; 380 381 if (device_property_read_bool(dev, "wakeup-source")) 382 devm_device_init_wakeup(dev); 383 384 return 0; 385 } 386 387 static void sec_pmic_acpm_shutdown(struct platform_device *pdev) 388 { 389 sec_pmic_shutdown(&pdev->dev); 390 } 391 392 static const struct sec_pmic_acpm_platform_data s2mpg10_data = { 393 .device_type = S2MPG10, 394 .acpm_chan_id = 2, 395 .speedy_channel = 0, 396 .regmap_cfg_common = &s2mpg10_regmap_config_common, 397 .regmap_cfg_pmic = &s2mpg10_regmap_config_pmic, 398 .regmap_cfg_rtc = &s2mpg10_regmap_config_rtc, 399 .regmap_cfg_meter = &s2mpg10_regmap_config_meter, 400 }; 401 402 static const struct of_device_id sec_pmic_acpm_of_match[] = { 403 { .compatible = "samsung,s2mpg10-pmic", .data = &s2mpg10_data, }, 404 { }, 405 }; 406 MODULE_DEVICE_TABLE(of, sec_pmic_acpm_of_match); 407 408 static struct platform_driver sec_pmic_acpm_driver = { 409 .driver = { 410 .name = "sec-pmic-acpm", 411 .pm = pm_sleep_ptr(&sec_pmic_pm_ops), 412 .of_match_table = sec_pmic_acpm_of_match, 413 }, 414 .probe = sec_pmic_acpm_probe, 415 .shutdown = sec_pmic_acpm_shutdown, 416 }; 417 module_platform_driver(sec_pmic_acpm_driver); 418 419 MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 420 MODULE_DESCRIPTION("ACPM driver for the Samsung S2MPG1x"); 421 MODULE_LICENSE("GPL"); 422