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 I2C driver 8 */ 9 10 #include <linux/dev_printk.h> 11 #include <linux/err.h> 12 #include <linux/i2c.h> 13 #include <linux/mfd/samsung/core.h> 14 #include <linux/mfd/samsung/s2mpa01.h> 15 #include <linux/mfd/samsung/s2mps11.h> 16 #include <linux/mfd/samsung/s2mps13.h> 17 #include <linux/mfd/samsung/s2mps14.h> 18 #include <linux/mfd/samsung/s2mps15.h> 19 #include <linux/mfd/samsung/s2mpu02.h> 20 #include <linux/mfd/samsung/s2mu005.h> 21 #include <linux/mfd/samsung/s5m8767.h> 22 #include <linux/module.h> 23 #include <linux/pm.h> 24 #include <linux/property.h> 25 #include <linux/regmap.h> 26 #include "sec-core.h" 27 28 struct sec_pmic_i2c_platform_data { 29 const struct regmap_config *regmap_cfg; 30 int device_type; 31 }; 32 33 static bool s2mpa01_volatile(struct device *dev, unsigned int reg) 34 { 35 switch (reg) { 36 case S2MPA01_REG_INT1M: 37 case S2MPA01_REG_INT2M: 38 case S2MPA01_REG_INT3M: 39 return false; 40 default: 41 return true; 42 } 43 } 44 45 static bool s2mps11_volatile(struct device *dev, unsigned int reg) 46 { 47 switch (reg) { 48 case S2MPS11_REG_INT1M: 49 case S2MPS11_REG_INT2M: 50 case S2MPS11_REG_INT3M: 51 return false; 52 default: 53 return true; 54 } 55 } 56 57 static bool s2mpu02_volatile(struct device *dev, unsigned int reg) 58 { 59 switch (reg) { 60 case S2MPU02_REG_INT1M: 61 case S2MPU02_REG_INT2M: 62 case S2MPU02_REG_INT3M: 63 return false; 64 default: 65 return true; 66 } 67 } 68 69 static bool s2mu005_volatile(struct device *dev, unsigned int reg) 70 { 71 switch (reg) { 72 case S2MU005_REG_CHGR_INT1M: 73 case S2MU005_REG_FLED_INT1M: 74 case S2MU005_REG_MUIC_INT1M: 75 case S2MU005_REG_MUIC_INT2M: 76 return false; 77 default: 78 return true; 79 } 80 } 81 82 static const struct regmap_config s2dos05_regmap_config = { 83 .reg_bits = 8, 84 .val_bits = 8, 85 }; 86 87 static const struct regmap_config s2mpa01_regmap_config = { 88 .reg_bits = 8, 89 .val_bits = 8, 90 91 .max_register = S2MPA01_REG_LDO_OVCB4, 92 .volatile_reg = s2mpa01_volatile, 93 .cache_type = REGCACHE_FLAT, 94 }; 95 96 static const struct regmap_config s2mps11_regmap_config = { 97 .reg_bits = 8, 98 .val_bits = 8, 99 100 .max_register = S2MPS11_REG_L38CTRL, 101 .volatile_reg = s2mps11_volatile, 102 .cache_type = REGCACHE_FLAT, 103 }; 104 105 static const struct regmap_config s2mps13_regmap_config = { 106 .reg_bits = 8, 107 .val_bits = 8, 108 109 .max_register = S2MPS13_REG_LDODSCH5, 110 .volatile_reg = s2mps11_volatile, 111 .cache_type = REGCACHE_FLAT, 112 }; 113 114 static const struct regmap_config s2mps14_regmap_config = { 115 .reg_bits = 8, 116 .val_bits = 8, 117 118 .max_register = S2MPS14_REG_LDODSCH3, 119 .volatile_reg = s2mps11_volatile, 120 .cache_type = REGCACHE_FLAT, 121 }; 122 123 static const struct regmap_config s2mps15_regmap_config = { 124 .reg_bits = 8, 125 .val_bits = 8, 126 127 .max_register = S2MPS15_REG_LDODSCH4, 128 .volatile_reg = s2mps11_volatile, 129 .cache_type = REGCACHE_FLAT, 130 }; 131 132 static const struct regmap_config s2mpu02_regmap_config = { 133 .reg_bits = 8, 134 .val_bits = 8, 135 136 .max_register = S2MPU02_REG_DVSDATA, 137 .volatile_reg = s2mpu02_volatile, 138 .cache_type = REGCACHE_FLAT, 139 }; 140 141 static const struct regmap_config s2mpu05_regmap_config = { 142 .reg_bits = 8, 143 .val_bits = 8, 144 }; 145 146 static const struct regmap_config s2mu005_regmap_config = { 147 .reg_bits = 8, 148 .val_bits = 8, 149 150 .max_register = S2MU005_REG_MUIC_LDOADC_H, 151 .volatile_reg = s2mu005_volatile, 152 .cache_type = REGCACHE_FLAT_S, 153 }; 154 155 static const struct regmap_config s5m8767_regmap_config = { 156 .reg_bits = 8, 157 .val_bits = 8, 158 159 .max_register = S5M8767_REG_LDO28CTRL, 160 .volatile_reg = s2mps11_volatile, 161 .cache_type = REGCACHE_FLAT, 162 }; 163 164 static int sec_pmic_i2c_probe(struct i2c_client *client) 165 { 166 const struct sec_pmic_i2c_platform_data *pdata; 167 struct regmap *regmap_pmic; 168 169 pdata = device_get_match_data(&client->dev); 170 if (!pdata) 171 return dev_err_probe(&client->dev, -ENODEV, 172 "Unsupported device type\n"); 173 174 regmap_pmic = devm_regmap_init_i2c(client, pdata->regmap_cfg); 175 if (IS_ERR(regmap_pmic)) 176 return dev_err_probe(&client->dev, PTR_ERR(regmap_pmic), 177 "regmap init failed\n"); 178 179 return sec_pmic_probe(&client->dev, pdata->device_type, client->irq, 180 regmap_pmic, client); 181 } 182 183 static void sec_pmic_i2c_shutdown(struct i2c_client *i2c) 184 { 185 sec_pmic_shutdown(&i2c->dev); 186 } 187 188 static const struct sec_pmic_i2c_platform_data s2dos05_data = { 189 .regmap_cfg = &s2dos05_regmap_config, 190 .device_type = S2DOS05 191 }; 192 193 static const struct sec_pmic_i2c_platform_data s2mpa01_data = { 194 .regmap_cfg = &s2mpa01_regmap_config, 195 .device_type = S2MPA01, 196 }; 197 198 static const struct sec_pmic_i2c_platform_data s2mps11_data = { 199 .regmap_cfg = &s2mps11_regmap_config, 200 .device_type = S2MPS11X, 201 }; 202 203 static const struct sec_pmic_i2c_platform_data s2mps13_data = { 204 .regmap_cfg = &s2mps13_regmap_config, 205 .device_type = S2MPS13X, 206 }; 207 208 static const struct sec_pmic_i2c_platform_data s2mps14_data = { 209 .regmap_cfg = &s2mps14_regmap_config, 210 .device_type = S2MPS14X, 211 }; 212 213 static const struct sec_pmic_i2c_platform_data s2mps15_data = { 214 .regmap_cfg = &s2mps15_regmap_config, 215 .device_type = S2MPS15X, 216 }; 217 218 static const struct sec_pmic_i2c_platform_data s2mpu02_data = { 219 .regmap_cfg = &s2mpu02_regmap_config, 220 .device_type = S2MPU02, 221 }; 222 223 static const struct sec_pmic_i2c_platform_data s2mpu05_data = { 224 .regmap_cfg = &s2mpu05_regmap_config, 225 .device_type = S2MPU05, 226 }; 227 228 static const struct sec_pmic_i2c_platform_data s2mu005_data = { 229 .regmap_cfg = &s2mu005_regmap_config, 230 .device_type = S2MU005, 231 }; 232 233 static const struct sec_pmic_i2c_platform_data s5m8767_data = { 234 .regmap_cfg = &s5m8767_regmap_config, 235 .device_type = S5M8767X, 236 }; 237 238 static const struct of_device_id sec_pmic_i2c_of_match[] = { 239 { .compatible = "samsung,s2dos05", .data = &s2dos05_data, }, 240 { .compatible = "samsung,s2mpa01-pmic", .data = &s2mpa01_data, }, 241 { .compatible = "samsung,s2mps11-pmic", .data = &s2mps11_data, }, 242 { .compatible = "samsung,s2mps13-pmic", .data = &s2mps13_data, }, 243 { .compatible = "samsung,s2mps14-pmic", .data = &s2mps14_data, }, 244 { .compatible = "samsung,s2mps15-pmic", .data = &s2mps15_data, }, 245 { .compatible = "samsung,s2mpu02-pmic", .data = &s2mpu02_data, }, 246 { .compatible = "samsung,s2mpu05-pmic", .data = &s2mpu05_data, }, 247 { .compatible = "samsung,s2mu005-pmic", .data = &s2mu005_data, }, 248 { .compatible = "samsung,s5m8767-pmic", .data = &s5m8767_data, }, 249 { }, 250 }; 251 MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match); 252 253 static struct i2c_driver sec_pmic_i2c_driver = { 254 .driver = { 255 .name = "sec-pmic-i2c", 256 .pm = pm_sleep_ptr(&sec_pmic_pm_ops), 257 .of_match_table = sec_pmic_i2c_of_match, 258 }, 259 .probe = sec_pmic_i2c_probe, 260 .shutdown = sec_pmic_i2c_shutdown, 261 }; 262 module_i2c_driver(sec_pmic_i2c_driver); 263 264 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 265 MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 266 MODULE_DESCRIPTION("I2C driver for the Samsung S5M"); 267 MODULE_LICENSE("GPL"); 268