]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mfd: sec: Split into core and transport (i2c) drivers
authorAndré Draszik <andre.draszik@linaro.org>
Wed, 9 Apr 2025 20:37:29 +0000 (21:37 +0100)
committerLee Jones <lee@kernel.org>
Fri, 23 May 2025 07:48:23 +0000 (08:48 +0100)
As a preparation for adding support for Samsung's S2MPG10, which is
connected via SPEEDY / ACPM rather than I2C, split out (move) all
I2C-specific driver code into its own kernel module, sec-i2c, and
make the existing sec-core module be just the transport-agnostic core
driver kernel module.

At the same time, update all defconfigs that reference the old kconfig
symbol name.

While at it, also update file header comments and module description(s)
to drop references to 'mfd', and update comments to be C-style, not
C++.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: André Draszik <andre.draszik@linaro.org>
Link: https://lore.kernel.org/r/20250409-s2mpg10-v4-8-d66d5f39b6bf@linaro.org
Signed-off-by: Lee Jones <lee@kernel.org>
arch/arm/configs/exynos_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/pxa_defconfig
arch/arm64/configs/defconfig
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/sec-core.c
drivers/mfd/sec-core.h
drivers/mfd/sec-i2c.c [new file with mode: 0644]

index 7ad48fdda1dac69a4a9612eabb573729bed7b3a6..251f45be6c14af59263373f21b27b15f42ec7f61 100644 (file)
@@ -167,7 +167,7 @@ CONFIG_MFD_MAX77686=y
 CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8997=y
 CONFIG_MFD_MAX8998=y
-CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_SEC_I2C=y
 CONFIG_MFD_STMPE=y
 CONFIG_STMPE_I2C=y
 CONFIG_MFD_TPS65090=y
index ad037c175fdb0ec8601c9b3607aca0c0e5f3c145..7d06ac5369b1a2f325462f2cf5b54fe22061ca77 100644 (file)
@@ -612,7 +612,7 @@ CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_RK8XX_I2C=y
 CONFIG_MFD_RN5T618=y
-CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_SEC_I2C=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65090=y
index de0ac8f521d7612704ce327e9ac16ab9e999f3d3..064e79baf20da809c9ab1f1fa18282aaba11a41f 100644 (file)
@@ -335,7 +335,7 @@ CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8907=m
 CONFIG_EZX_PCAP=y
 CONFIG_UCB1400_CORE=m
-CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_SEC_I2C=y
 CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65090=y
 CONFIG_MFD_TPS6586X=y
index 5bb8f09422a22116781169611482179b10798c14..f021fb29683be1a10720d7e6415daea771647879 100644 (file)
@@ -769,7 +769,7 @@ CONFIG_MFD_MT6397=y
 CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_RK8XX_I2C=y
 CONFIG_MFD_RK8XX_SPI=y
-CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_SEC_I2C=y
 CONFIG_MFD_SL28CPLD=y
 CONFIG_RZ_MTU3=y
 CONFIG_MFD_TI_AM335X_TSCADC=m
index 96992af22565205716d72db0494c7bf2567b045e..3cde836b3799eb30efe9c88694536be115db3ce5 100644 (file)
@@ -1312,21 +1312,25 @@ config MFD_RN5T618
          functionality of the device.
 
 config MFD_SEC_CORE
-       tristate "Samsung Electronics PMIC Series Support"
+       tristate
+       select MFD_CORE
+       select REGMAP_IRQ
+
+config MFD_SEC_I2C
+       tristate "Samsung Electronics S2MPA/S2MPS1X/S2MPU/S5M series PMICs"
        depends on I2C=y
        depends on OF
-       select MFD_CORE
+       select MFD_SEC_CORE
        select REGMAP_I2C
-       select REGMAP_IRQ
        help
-         Support for the Samsung Electronics PMIC devices coming
-         usually along with Samsung Exynos SoC chipset.
+         Support for the Samsung Electronics PMIC devices with I2C interface
+         coming usually along with Samsung Exynos SoC chipset.
          This driver provides common support for accessing the device,
          additional drivers must be enabled in order to use the functionality
-         of the device
+         of the device.
 
          To compile this driver as a module, choose M here: the
-         module will be called sec-core.
+         module will be called sec-i2c.
          Have in mind that important core drivers (like regulators) depend
          on this driver so building this as a module might require proper
          initial ramdisk or might not boot up as well in certain scenarios.
index 5e5cc279af6036a6b3ea1f1f0feeddf45b85f15c..363ec7eb827a038dcfcc6869d54226cbcbc558c6 100644 (file)
@@ -230,6 +230,7 @@ obj-$(CONFIG_MFD_RK8XX_I2C) += rk8xx-i2c.o
 obj-$(CONFIG_MFD_RK8XX_SPI)    += rk8xx-spi.o
 obj-$(CONFIG_MFD_RN5T618)      += rn5t618.o
 obj-$(CONFIG_MFD_SEC_CORE)     += sec-core.o sec-irq.o
+obj-$(CONFIG_MFD_SEC_I2C)      += sec-i2c.o
 obj-$(CONFIG_MFD_SYSCON)       += syscon.o
 obj-$(CONFIG_MFD_LM3533)       += lm3533-core.o lm3533-ctrlbank.o
 obj-$(CONFIG_MFD_VEXPRESS_SYSREG)      += vexpress-sysreg.o
index 83693686567df61b5e09f7129dc6b01d69156ff3..bb664e052bf5198f2fc83a86bd6e1e72364fb8df 100644 (file)
@@ -1,23 +1,21 @@
 // SPDX-License-Identifier: GPL-2.0+
-//
-// Copyright (c) 2012 Samsung Electronics Co., Ltd
-//              http://www.samsung.com
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *                http://www.samsung.com
+ * Copyright 2025 Linaro Ltd.
+ *
+ * Samsung SxM core driver
+ */
 
 #include <linux/device.h>
 #include <linux/err.h>
-#include <linux/i2c.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
-#include <linux/mfd/samsung/s2mpa01.h>
 #include <linux/mfd/samsung/s2mps11.h>
 #include <linux/mfd/samsung/s2mps13.h>
-#include <linux/mfd/samsung/s2mps14.h>
-#include <linux/mfd/samsung/s2mps15.h>
-#include <linux/mfd/samsung/s2mpu02.h>
-#include <linux/mfd/samsung/s5m8767.h>
-#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pm.h>
@@ -88,144 +86,6 @@ static const struct mfd_cell s2mpu05_devs[] = {
        { .name = "s2mps15-rtc", },
 };
 
-static const struct of_device_id sec_dt_match[] = {
-       {
-               .compatible = "samsung,s5m8767-pmic",
-               .data = (void *)S5M8767X,
-       }, {
-               .compatible = "samsung,s2dos05",
-               .data = (void *)S2DOS05,
-       }, {
-               .compatible = "samsung,s2mps11-pmic",
-               .data = (void *)S2MPS11X,
-       }, {
-               .compatible = "samsung,s2mps13-pmic",
-               .data = (void *)S2MPS13X,
-       }, {
-               .compatible = "samsung,s2mps14-pmic",
-               .data = (void *)S2MPS14X,
-       }, {
-               .compatible = "samsung,s2mps15-pmic",
-               .data = (void *)S2MPS15X,
-       }, {
-               .compatible = "samsung,s2mpa01-pmic",
-               .data = (void *)S2MPA01,
-       }, {
-               .compatible = "samsung,s2mpu02-pmic",
-               .data = (void *)S2MPU02,
-       }, {
-               .compatible = "samsung,s2mpu05-pmic",
-               .data = (void *)S2MPU05,
-       }, {
-               /* Sentinel */
-       },
-};
-MODULE_DEVICE_TABLE(of, sec_dt_match);
-
-static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
-{
-       switch (reg) {
-       case S2MPA01_REG_INT1M:
-       case S2MPA01_REG_INT2M:
-       case S2MPA01_REG_INT3M:
-               return false;
-       default:
-               return true;
-       }
-}
-
-static bool s2mps11_volatile(struct device *dev, unsigned int reg)
-{
-       switch (reg) {
-       case S2MPS11_REG_INT1M:
-       case S2MPS11_REG_INT2M:
-       case S2MPS11_REG_INT3M:
-               return false;
-       default:
-               return true;
-       }
-}
-
-static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
-{
-       switch (reg) {
-       case S2MPU02_REG_INT1M:
-       case S2MPU02_REG_INT2M:
-       case S2MPU02_REG_INT3M:
-               return false;
-       default:
-               return true;
-       }
-}
-
-static const struct regmap_config sec_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-};
-
-static const struct regmap_config s2mpa01_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S2MPA01_REG_LDO_OVCB4,
-       .volatile_reg = s2mpa01_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
-static const struct regmap_config s2mps11_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S2MPS11_REG_L38CTRL,
-       .volatile_reg = s2mps11_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
-static const struct regmap_config s2mps13_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S2MPS13_REG_LDODSCH5,
-       .volatile_reg = s2mps11_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
-static const struct regmap_config s2mps14_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S2MPS14_REG_LDODSCH3,
-       .volatile_reg = s2mps11_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
-static const struct regmap_config s2mps15_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S2MPS15_REG_LDODSCH4,
-       .volatile_reg = s2mps11_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
-static const struct regmap_config s2mpu02_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S2MPU02_REG_DVSDATA,
-       .volatile_reg = s2mpu02_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
-static const struct regmap_config s5m8767_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-
-       .max_register = S5M8767_REG_LDO28CTRL,
-       .volatile_reg = s2mps11_volatile,
-       .cache_type = REGCACHE_FLAT,
-};
-
 static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
 {
        unsigned int val;
@@ -268,7 +128,7 @@ static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
  * platform data.
  */
 static struct sec_platform_data *
-sec_pmic_i2c_parse_dt_pdata(struct device *dev)
+sec_pmic_parse_dt_pdata(struct device *dev)
 {
        struct sec_platform_data *pd;
 
@@ -283,68 +143,34 @@ sec_pmic_i2c_parse_dt_pdata(struct device *dev)
        return pd;
 }
 
-static int sec_pmic_probe(struct i2c_client *i2c)
+int sec_pmic_probe(struct device *dev, unsigned long device_type,
+                  unsigned int irq, struct regmap *regmap,
+                  struct i2c_client *client)
 {
-       const struct regmap_config *regmap;
        struct sec_platform_data *pdata;
        const struct mfd_cell *sec_devs;
        struct sec_pmic_dev *sec_pmic;
        int ret, num_sec_devs;
 
-       sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev),
-                               GFP_KERNEL);
+       sec_pmic = devm_kzalloc(dev, sizeof(struct sec_pmic_dev), GFP_KERNEL);
        if (sec_pmic == NULL)
                return -ENOMEM;
 
-       i2c_set_clientdata(i2c, sec_pmic);
-       sec_pmic->dev = &i2c->dev;
-       sec_pmic->i2c = i2c;
-       sec_pmic->irq = i2c->irq;
+       dev_set_drvdata(dev, sec_pmic);
+       sec_pmic->dev = dev;
+       sec_pmic->device_type = device_type;
+       sec_pmic->i2c = client;
+       sec_pmic->irq = irq;
+       sec_pmic->regmap_pmic = regmap;
 
-       pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
+       pdata = sec_pmic_parse_dt_pdata(sec_pmic->dev);
        if (IS_ERR(pdata)) {
                ret = PTR_ERR(pdata);
                return ret;
        }
 
-       sec_pmic->device_type = (unsigned long)of_device_get_match_data(sec_pmic->dev);
        sec_pmic->pdata = pdata;
 
-       switch (sec_pmic->device_type) {
-       case S2MPA01:
-               regmap = &s2mpa01_regmap_config;
-               break;
-       case S2MPS11X:
-               regmap = &s2mps11_regmap_config;
-               break;
-       case S2MPS13X:
-               regmap = &s2mps13_regmap_config;
-               break;
-       case S2MPS14X:
-               regmap = &s2mps14_regmap_config;
-               break;
-       case S2MPS15X:
-               regmap = &s2mps15_regmap_config;
-               break;
-       case S5M8767X:
-               regmap = &s5m8767_regmap_config;
-               break;
-       case S2MPU02:
-               regmap = &s2mpu02_regmap_config;
-               break;
-       default:
-               regmap = &sec_regmap_config;
-               break;
-       }
-
-       sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
-       if (IS_ERR(sec_pmic->regmap_pmic)) {
-               ret = PTR_ERR(sec_pmic->regmap_pmic);
-               dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
-                       ret);
-               return ret;
-       }
-
        sec_irq_init(sec_pmic);
 
        pm_runtime_set_active(sec_pmic->dev);
@@ -387,9 +213,9 @@ static int sec_pmic_probe(struct i2c_client *i2c)
                num_sec_devs = ARRAY_SIZE(s2mpu05_devs);
                break;
        default:
-               dev_err(&i2c->dev, "Unsupported device type (%lu)\n",
+               dev_err(sec_pmic->dev, "Unsupported device type %lu\n",
                        sec_pmic->device_type);
-               return -ENODEV;
+               return -EINVAL;
        }
        ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
                                   NULL, 0, NULL);
@@ -401,10 +227,11 @@ static int sec_pmic_probe(struct i2c_client *i2c)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(sec_pmic_probe);
 
-static void sec_pmic_shutdown(struct i2c_client *i2c)
+void sec_pmic_shutdown(struct device *dev)
 {
-       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+       struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev);
        unsigned int reg, mask;
 
        if (!sec_pmic->pdata->manual_poweroff)
@@ -428,11 +255,11 @@ static void sec_pmic_shutdown(struct i2c_client *i2c)
 
        regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
 }
+EXPORT_SYMBOL_GPL(sec_pmic_shutdown);
 
 static int sec_pmic_suspend(struct device *dev)
 {
-       struct i2c_client *i2c = to_i2c_client(dev);
-       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+       struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev);
 
        if (device_may_wakeup(dev))
                enable_irq_wake(sec_pmic->irq);
@@ -452,8 +279,7 @@ static int sec_pmic_suspend(struct device *dev)
 
 static int sec_pmic_resume(struct device *dev)
 {
-       struct i2c_client *i2c = to_i2c_client(dev);
-       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+       struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev);
 
        if (device_may_wakeup(dev))
                disable_irq_wake(sec_pmic->irq);
@@ -462,20 +288,9 @@ static int sec_pmic_resume(struct device *dev)
        return 0;
 }
 
-static DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops,
-                               sec_pmic_suspend, sec_pmic_resume);
-
-static struct i2c_driver sec_pmic_driver = {
-       .driver = {
-                  .name = "sec_pmic",
-                  .pm = pm_sleep_ptr(&sec_pmic_pm_ops),
-                  .of_match_table = sec_dt_match,
-       },
-       .probe = sec_pmic_probe,
-       .shutdown = sec_pmic_shutdown,
-};
-module_i2c_driver(sec_pmic_driver);
+DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
+EXPORT_SYMBOL_GPL(sec_pmic_pm_ops);
 
 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
-MODULE_DESCRIPTION("Core support for the S5M MFD");
+MODULE_DESCRIPTION("Core driver for the Samsung S5M");
 MODULE_LICENSE("GPL");
index b3fded5f02a0ddc09a9508fd49a5d335f7ad0ee7..a0a3488924d96f69373e7569079cfefd0544ca26 100644 (file)
 #ifndef __SEC_CORE_INT_H
 #define __SEC_CORE_INT_H
 
+struct i2c_client;
+
+extern const struct dev_pm_ops sec_pmic_pm_ops;
+
+int sec_pmic_probe(struct device *dev, unsigned long device_type,
+                  unsigned int irq, struct regmap *regmap,
+                  struct i2c_client *client);
+void sec_pmic_shutdown(struct device *dev);
+
 int sec_irq_init(struct sec_pmic_dev *sec_pmic);
 
 #endif /* __SEC_CORE_INT_H */
diff --git a/drivers/mfd/sec-i2c.c b/drivers/mfd/sec-i2c.c
new file mode 100644 (file)
index 0000000..8e3a365
--- /dev/null
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *                http://www.samsung.com
+ * Copyright 2025 Linaro Ltd.
+ *
+ * Samsung SxM I2C driver
+ */
+
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mfd/samsung/core.h>
+#include <linux/mfd/samsung/s2mpa01.h>
+#include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s2mps13.h>
+#include <linux/mfd/samsung/s2mps14.h>
+#include <linux/mfd/samsung/s2mps15.h>
+#include <linux/mfd/samsung/s2mpu02.h>
+#include <linux/mfd/samsung/s5m8767.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regmap.h>
+#include "sec-core.h"
+
+static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S2MPA01_REG_INT1M:
+       case S2MPA01_REG_INT2M:
+       case S2MPA01_REG_INT3M:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static bool s2mps11_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S2MPS11_REG_INT1M:
+       case S2MPS11_REG_INT2M:
+       case S2MPS11_REG_INT3M:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S2MPU02_REG_INT1M:
+       case S2MPU02_REG_INT2M:
+       case S2MPU02_REG_INT3M:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static const struct regmap_config sec_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static const struct regmap_config s2mpa01_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPA01_REG_LDO_OVCB4,
+       .volatile_reg = s2mpa01_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s2mps11_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS11_REG_L38CTRL,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s2mps13_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS13_REG_LDODSCH5,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s2mps14_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS14_REG_LDODSCH3,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s2mps15_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS15_REG_LDODSCH4,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s2mpu02_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPU02_REG_DVSDATA,
+       .volatile_reg = s2mpu02_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s5m8767_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S5M8767_REG_LDO28CTRL,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static int sec_pmic_i2c_probe(struct i2c_client *client)
+{
+       const struct regmap_config *regmap;
+       unsigned long device_type;
+       struct regmap *regmap_pmic;
+       int ret;
+
+       device_type = (unsigned long)of_device_get_match_data(&client->dev);
+
+       switch (device_type) {
+       case S2MPA01:
+               regmap = &s2mpa01_regmap_config;
+               break;
+       case S2MPS11X:
+               regmap = &s2mps11_regmap_config;
+               break;
+       case S2MPS13X:
+               regmap = &s2mps13_regmap_config;
+               break;
+       case S2MPS14X:
+               regmap = &s2mps14_regmap_config;
+               break;
+       case S2MPS15X:
+               regmap = &s2mps15_regmap_config;
+               break;
+       case S5M8767X:
+               regmap = &s5m8767_regmap_config;
+               break;
+       case S2MPU02:
+               regmap = &s2mpu02_regmap_config;
+               break;
+       default:
+               regmap = &sec_regmap_config;
+               break;
+       }
+
+       regmap_pmic = devm_regmap_init_i2c(client, regmap);
+       if (IS_ERR(regmap_pmic)) {
+               ret = PTR_ERR(regmap_pmic);
+               dev_err(&client->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return sec_pmic_probe(&client->dev, device_type, client->irq,
+                             regmap_pmic, client);
+}
+
+static void sec_pmic_i2c_shutdown(struct i2c_client *i2c)
+{
+       sec_pmic_shutdown(&i2c->dev);
+}
+
+static const struct of_device_id sec_pmic_i2c_of_match[] = {
+       {
+               .compatible = "samsung,s5m8767-pmic",
+               .data = (void *)S5M8767X,
+       }, {
+               .compatible = "samsung,s2dos05",
+               .data = (void *)S2DOS05,
+       }, {
+               .compatible = "samsung,s2mps11-pmic",
+               .data = (void *)S2MPS11X,
+       }, {
+               .compatible = "samsung,s2mps13-pmic",
+               .data = (void *)S2MPS13X,
+       }, {
+               .compatible = "samsung,s2mps14-pmic",
+               .data = (void *)S2MPS14X,
+       }, {
+               .compatible = "samsung,s2mps15-pmic",
+               .data = (void *)S2MPS15X,
+       }, {
+               .compatible = "samsung,s2mpa01-pmic",
+               .data = (void *)S2MPA01,
+       }, {
+               .compatible = "samsung,s2mpu02-pmic",
+               .data = (void *)S2MPU02,
+       }, {
+               .compatible = "samsung,s2mpu05-pmic",
+               .data = (void *)S2MPU05,
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match);
+
+static struct i2c_driver sec_pmic_i2c_driver = {
+       .driver = {
+               .name = "sec-pmic-i2c",
+               .pm = pm_sleep_ptr(&sec_pmic_pm_ops),
+               .of_match_table = sec_pmic_i2c_of_match,
+       },
+       .probe = sec_pmic_i2c_probe,
+       .shutdown = sec_pmic_i2c_shutdown,
+};
+module_i2c_driver(sec_pmic_i2c_driver);
+
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("I2C driver for the Samsung S5M");
+MODULE_LICENSE("GPL");