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