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