1680ef579SAndré Draszik // SPDX-License-Identifier: GPL-2.0+ 2680ef579SAndré Draszik /* 3680ef579SAndré Draszik * Copyright 2012 Samsung Electronics Co., Ltd 4680ef579SAndré Draszik * http://www.samsung.com 5680ef579SAndré Draszik * Copyright 2025 Linaro Ltd. 6680ef579SAndré Draszik * 7680ef579SAndré Draszik * Samsung SxM I2C driver 8680ef579SAndré Draszik */ 9680ef579SAndré Draszik 10680ef579SAndré Draszik #include <linux/dev_printk.h> 11680ef579SAndré Draszik #include <linux/err.h> 12680ef579SAndré Draszik #include <linux/i2c.h> 13680ef579SAndré Draszik #include <linux/mfd/samsung/core.h> 14680ef579SAndré Draszik #include <linux/mfd/samsung/s2mpa01.h> 15680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps11.h> 16680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps13.h> 17680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps14.h> 18680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps15.h> 19680ef579SAndré Draszik #include <linux/mfd/samsung/s2mpu02.h> 20680ef579SAndré Draszik #include <linux/mfd/samsung/s5m8767.h> 21680ef579SAndré Draszik #include <linux/mod_devicetable.h> 22680ef579SAndré Draszik #include <linux/module.h> 23680ef579SAndré Draszik #include <linux/pm.h> 24aaaeae7eSAndré Draszik #include <linux/property.h> 25680ef579SAndré Draszik #include <linux/regmap.h> 26680ef579SAndré Draszik #include "sec-core.h" 27680ef579SAndré Draszik 28aaaeae7eSAndré Draszik struct sec_pmic_i2c_platform_data { 29aaaeae7eSAndré Draszik const struct regmap_config *regmap_cfg; 30adf91d9eSAndré Draszik int device_type; 31aaaeae7eSAndré Draszik }; 32aaaeae7eSAndré Draszik 33680ef579SAndré Draszik static bool s2mpa01_volatile(struct device *dev, unsigned int reg) 34680ef579SAndré Draszik { 35680ef579SAndré Draszik switch (reg) { 36680ef579SAndré Draszik case S2MPA01_REG_INT1M: 37680ef579SAndré Draszik case S2MPA01_REG_INT2M: 38680ef579SAndré Draszik case S2MPA01_REG_INT3M: 39680ef579SAndré Draszik return false; 40680ef579SAndré Draszik default: 41680ef579SAndré Draszik return true; 42680ef579SAndré Draszik } 43680ef579SAndré Draszik } 44680ef579SAndré Draszik 45680ef579SAndré Draszik static bool s2mps11_volatile(struct device *dev, unsigned int reg) 46680ef579SAndré Draszik { 47680ef579SAndré Draszik switch (reg) { 48680ef579SAndré Draszik case S2MPS11_REG_INT1M: 49680ef579SAndré Draszik case S2MPS11_REG_INT2M: 50680ef579SAndré Draszik case S2MPS11_REG_INT3M: 51680ef579SAndré Draszik return false; 52680ef579SAndré Draszik default: 53680ef579SAndré Draszik return true; 54680ef579SAndré Draszik } 55680ef579SAndré Draszik } 56680ef579SAndré Draszik 57680ef579SAndré Draszik static bool s2mpu02_volatile(struct device *dev, unsigned int reg) 58680ef579SAndré Draszik { 59680ef579SAndré Draszik switch (reg) { 60680ef579SAndré Draszik case S2MPU02_REG_INT1M: 61680ef579SAndré Draszik case S2MPU02_REG_INT2M: 62680ef579SAndré Draszik case S2MPU02_REG_INT3M: 63680ef579SAndré Draszik return false; 64680ef579SAndré Draszik default: 65680ef579SAndré Draszik return true; 66680ef579SAndré Draszik } 67680ef579SAndré Draszik } 68680ef579SAndré Draszik 691cea1b6bSAndré Draszik static const struct regmap_config s2dos05_regmap_config = { 70680ef579SAndré Draszik .reg_bits = 8, 71680ef579SAndré Draszik .val_bits = 8, 72680ef579SAndré Draszik }; 73680ef579SAndré Draszik 74680ef579SAndré Draszik static const struct regmap_config s2mpa01_regmap_config = { 75680ef579SAndré Draszik .reg_bits = 8, 76680ef579SAndré Draszik .val_bits = 8, 77680ef579SAndré Draszik 78680ef579SAndré Draszik .max_register = S2MPA01_REG_LDO_OVCB4, 79680ef579SAndré Draszik .volatile_reg = s2mpa01_volatile, 80680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 81680ef579SAndré Draszik }; 82680ef579SAndré Draszik 83680ef579SAndré Draszik static const struct regmap_config s2mps11_regmap_config = { 84680ef579SAndré Draszik .reg_bits = 8, 85680ef579SAndré Draszik .val_bits = 8, 86680ef579SAndré Draszik 87680ef579SAndré Draszik .max_register = S2MPS11_REG_L38CTRL, 88680ef579SAndré Draszik .volatile_reg = s2mps11_volatile, 89680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 90680ef579SAndré Draszik }; 91680ef579SAndré Draszik 92680ef579SAndré Draszik static const struct regmap_config s2mps13_regmap_config = { 93680ef579SAndré Draszik .reg_bits = 8, 94680ef579SAndré Draszik .val_bits = 8, 95680ef579SAndré Draszik 96680ef579SAndré Draszik .max_register = S2MPS13_REG_LDODSCH5, 97680ef579SAndré Draszik .volatile_reg = s2mps11_volatile, 98680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 99680ef579SAndré Draszik }; 100680ef579SAndré Draszik 101680ef579SAndré Draszik static const struct regmap_config s2mps14_regmap_config = { 102680ef579SAndré Draszik .reg_bits = 8, 103680ef579SAndré Draszik .val_bits = 8, 104680ef579SAndré Draszik 105680ef579SAndré Draszik .max_register = S2MPS14_REG_LDODSCH3, 106680ef579SAndré Draszik .volatile_reg = s2mps11_volatile, 107680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 108680ef579SAndré Draszik }; 109680ef579SAndré Draszik 110680ef579SAndré Draszik static const struct regmap_config s2mps15_regmap_config = { 111680ef579SAndré Draszik .reg_bits = 8, 112680ef579SAndré Draszik .val_bits = 8, 113680ef579SAndré Draszik 114680ef579SAndré Draszik .max_register = S2MPS15_REG_LDODSCH4, 115680ef579SAndré Draszik .volatile_reg = s2mps11_volatile, 116680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 117680ef579SAndré Draszik }; 118680ef579SAndré Draszik 119680ef579SAndré Draszik static const struct regmap_config s2mpu02_regmap_config = { 120680ef579SAndré Draszik .reg_bits = 8, 121680ef579SAndré Draszik .val_bits = 8, 122680ef579SAndré Draszik 123680ef579SAndré Draszik .max_register = S2MPU02_REG_DVSDATA, 124680ef579SAndré Draszik .volatile_reg = s2mpu02_volatile, 125680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 126680ef579SAndré Draszik }; 127680ef579SAndré Draszik 1281cea1b6bSAndré Draszik static const struct regmap_config s2mpu05_regmap_config = { 1291cea1b6bSAndré Draszik .reg_bits = 8, 1301cea1b6bSAndré Draszik .val_bits = 8, 1311cea1b6bSAndré Draszik }; 1321cea1b6bSAndré Draszik 133680ef579SAndré Draszik static const struct regmap_config s5m8767_regmap_config = { 134680ef579SAndré Draszik .reg_bits = 8, 135680ef579SAndré Draszik .val_bits = 8, 136680ef579SAndré Draszik 137680ef579SAndré Draszik .max_register = S5M8767_REG_LDO28CTRL, 138680ef579SAndré Draszik .volatile_reg = s2mps11_volatile, 139680ef579SAndré Draszik .cache_type = REGCACHE_FLAT, 140680ef579SAndré Draszik }; 141680ef579SAndré Draszik 142680ef579SAndré Draszik static int sec_pmic_i2c_probe(struct i2c_client *client) 143680ef579SAndré Draszik { 144aaaeae7eSAndré Draszik const struct sec_pmic_i2c_platform_data *pdata; 145680ef579SAndré Draszik struct regmap *regmap_pmic; 146680ef579SAndré Draszik 147aaaeae7eSAndré Draszik pdata = device_get_match_data(&client->dev); 148aaaeae7eSAndré Draszik if (!pdata) 1491cea1b6bSAndré Draszik return dev_err_probe(&client->dev, -ENODEV, 150aaaeae7eSAndré Draszik "Unsupported device type\n"); 151680ef579SAndré Draszik 152aaaeae7eSAndré Draszik regmap_pmic = devm_regmap_init_i2c(client, pdata->regmap_cfg); 153176a3068SAndré Draszik if (IS_ERR(regmap_pmic)) 154176a3068SAndré Draszik return dev_err_probe(&client->dev, PTR_ERR(regmap_pmic), 155176a3068SAndré Draszik "regmap init failed\n"); 156680ef579SAndré Draszik 157aaaeae7eSAndré Draszik return sec_pmic_probe(&client->dev, pdata->device_type, client->irq, 158680ef579SAndré Draszik regmap_pmic, client); 159680ef579SAndré Draszik } 160680ef579SAndré Draszik 161680ef579SAndré Draszik static void sec_pmic_i2c_shutdown(struct i2c_client *i2c) 162680ef579SAndré Draszik { 163680ef579SAndré Draszik sec_pmic_shutdown(&i2c->dev); 164680ef579SAndré Draszik } 165680ef579SAndré Draszik 166aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2dos05_data = { 167aaaeae7eSAndré Draszik .regmap_cfg = &s2dos05_regmap_config, 168aaaeae7eSAndré Draszik .device_type = S2DOS05 169aaaeae7eSAndré Draszik }; 170aaaeae7eSAndré Draszik 171aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mpa01_data = { 172aaaeae7eSAndré Draszik .regmap_cfg = &s2mpa01_regmap_config, 173aaaeae7eSAndré Draszik .device_type = S2MPA01, 174aaaeae7eSAndré Draszik }; 175aaaeae7eSAndré Draszik 176aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps11_data = { 177aaaeae7eSAndré Draszik .regmap_cfg = &s2mps11_regmap_config, 178aaaeae7eSAndré Draszik .device_type = S2MPS11X, 179aaaeae7eSAndré Draszik }; 180aaaeae7eSAndré Draszik 181aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps13_data = { 182aaaeae7eSAndré Draszik .regmap_cfg = &s2mps13_regmap_config, 183aaaeae7eSAndré Draszik .device_type = S2MPS13X, 184aaaeae7eSAndré Draszik }; 185aaaeae7eSAndré Draszik 186aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps14_data = { 187aaaeae7eSAndré Draszik .regmap_cfg = &s2mps14_regmap_config, 188aaaeae7eSAndré Draszik .device_type = S2MPS14X, 189aaaeae7eSAndré Draszik }; 190aaaeae7eSAndré Draszik 191aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps15_data = { 192aaaeae7eSAndré Draszik .regmap_cfg = &s2mps15_regmap_config, 193aaaeae7eSAndré Draszik .device_type = S2MPS15X, 194aaaeae7eSAndré Draszik }; 195aaaeae7eSAndré Draszik 196aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mpu02_data = { 197aaaeae7eSAndré Draszik .regmap_cfg = &s2mpu02_regmap_config, 198aaaeae7eSAndré Draszik .device_type = S2MPU02, 199aaaeae7eSAndré Draszik }; 200aaaeae7eSAndré Draszik 201aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mpu05_data = { 202aaaeae7eSAndré Draszik .regmap_cfg = &s2mpu05_regmap_config, 203aaaeae7eSAndré Draszik .device_type = S2MPU05, 204aaaeae7eSAndré Draszik }; 205aaaeae7eSAndré Draszik 206aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s5m8767_data = { 207aaaeae7eSAndré Draszik .regmap_cfg = &s5m8767_regmap_config, 208aaaeae7eSAndré Draszik .device_type = S5M8767X, 209aaaeae7eSAndré Draszik }; 210aaaeae7eSAndré Draszik 211680ef579SAndré Draszik static const struct of_device_id sec_pmic_i2c_of_match[] = { 212aaaeae7eSAndré Draszik { .compatible = "samsung,s2dos05", .data = &s2dos05_data, }, 213aaaeae7eSAndré Draszik { .compatible = "samsung,s2mpa01-pmic", .data = &s2mpa01_data, }, 214aaaeae7eSAndré Draszik { .compatible = "samsung,s2mps11-pmic", .data = &s2mps11_data, }, 215aaaeae7eSAndré Draszik { .compatible = "samsung,s2mps13-pmic", .data = &s2mps13_data, }, 216aaaeae7eSAndré Draszik { .compatible = "samsung,s2mps14-pmic", .data = &s2mps14_data, }, 217aaaeae7eSAndré Draszik { .compatible = "samsung,s2mps15-pmic", .data = &s2mps15_data, }, 218aaaeae7eSAndré Draszik { .compatible = "samsung,s2mpu02-pmic", .data = &s2mpu02_data, }, 219aaaeae7eSAndré Draszik { .compatible = "samsung,s2mpu05-pmic", .data = &s2mpu05_data, }, 220aaaeae7eSAndré Draszik { .compatible = "samsung,s5m8767-pmic", .data = &s5m8767_data, }, 221680ef579SAndré Draszik { }, 222680ef579SAndré Draszik }; 223680ef579SAndré Draszik MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match); 224680ef579SAndré Draszik 225680ef579SAndré Draszik static struct i2c_driver sec_pmic_i2c_driver = { 226680ef579SAndré Draszik .driver = { 227680ef579SAndré Draszik .name = "sec-pmic-i2c", 228680ef579SAndré Draszik .pm = pm_sleep_ptr(&sec_pmic_pm_ops), 229680ef579SAndré Draszik .of_match_table = sec_pmic_i2c_of_match, 230680ef579SAndré Draszik }, 231680ef579SAndré Draszik .probe = sec_pmic_i2c_probe, 232680ef579SAndré Draszik .shutdown = sec_pmic_i2c_shutdown, 233680ef579SAndré Draszik }; 234680ef579SAndré Draszik module_i2c_driver(sec_pmic_i2c_driver); 235680ef579SAndré Draszik 236680ef579SAndré Draszik MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 237*217c445cSAndré Draszik MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 238680ef579SAndré Draszik MODULE_DESCRIPTION("I2C driver for the Samsung S5M"); 239680ef579SAndré Draszik MODULE_LICENSE("GPL"); 240