mfd: Add SpacemiT K1-X mfd driver 39/316539/1
authorMichal Wilczynski <m.wilczynski@samsung.com>
Thu, 22 Aug 2024 07:58:40 +0000 (09:58 +0200)
committerMichal Wilczynski <m.wilczynski@samsung.com>
Thu, 22 Aug 2024 11:53:46 +0000 (13:53 +0200)
Mfd driver is a dependecy for the eMMC devices. Port it from the vendor
kernel [1].

[1] - https://github.com/BPI-SINOVOIP/pi-linux.git

Change-Id: If1e09972d79504fc886268cba0c42f5209993a8b
Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com>
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/spacemit-mfd.c [new file with mode: 0644]
include/linux/mfd/spacemit/pm853.h [new file with mode: 0644]
include/linux/mfd/spacemit/spacemit_pmic.h [new file with mode: 0644]
include/linux/mfd/spacemit/spm8821.h [new file with mode: 0644]
include/linux/mfd/spacemit/sy8810l.h [new file with mode: 0644]

index 68d71b4b55bd350af0e5cefbd1713ca206d131ca..bdcca15cf66579e84c4bcada42f046a54b9e67b6 100644 (file)
@@ -2218,6 +2218,16 @@ config MFD_QCOM_PM8008
          under it in the device tree. Additional drivers must be enabled in
          order to use the functionality of the device.
 
+config MFD_SPACEMIT_PMIC
+       tristate "Spacemit Power Management IC"
+       depends on I2C && OF
+       depends on ARCH_SPACEMIT
+       select MFD_CORE
+       select REGMAP_I2C
+       select REGMAP_IRQ
+       help
+         Select this option to get support for the SPACEMIT Power Management ICs.
+
 menu "Multimedia Capabilities Port drivers"
        depends on ARCH_SA1100
 
index c66f07edcd0e6273ef1a9eac702bc674eb1cbb32..f55a96ea179d94b2b2b242b0b6be899c41e9712c 100644 (file)
@@ -284,3 +284,4 @@ rsmu-i2c-objs                       := rsmu_core.o rsmu_i2c.o
 rsmu-spi-objs                  := rsmu_core.o rsmu_spi.o
 obj-$(CONFIG_MFD_RSMU_I2C)     += rsmu-i2c.o
 obj-$(CONFIG_MFD_RSMU_SPI)     += rsmu-spi.o
+obj-$(CONFIG_MFD_SPACEMIT_PMIC) += spacemit-mfd.o
diff --git a/drivers/mfd/spacemit-mfd.c b/drivers/mfd/spacemit-mfd.c
new file mode 100644 (file)
index 0000000..cca9f60
--- /dev/null
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/reboot.h>
+#include <linux/ioport.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/mfd/spacemit/spacemit_pmic.h>
+
+SPM8821_REGMAP_CONFIG;
+SPM8821_IRQS_DESC;
+SPM8821_IRQ_CHIP_DESC;
+SPM8821_POWER_KEY_RESOURCES_DESC;
+SPM8821_RTC_RESOURCES_DESC;
+SPM8821_MFD_CELL;
+SPM8821_MFD_MATCH_DATA;
+
+PM853_MFD_CELL;
+PM853_REGMAP_CONFIG;
+PM853_MFD_MATCH_DATA;
+
+SY8810L_MFD_CELL;
+SY8810L_REGMAP_CONFIG;
+SY8810L_MFD_MATCH_DATA;
+
+static const struct of_device_id spacemit_pmic_of_match[] = {
+       { .compatible = "spacemit,spm8821" , .data = (void *)&spm8821_mfd_match_data },
+       { .compatible = "spacemit,pm853" , .data = (void *)&pm853_mfd_match_data },
+       { .compatible = "spacemit,sy8810l" , .data = (void *)&sy8810l_mfd_match_data },
+       { },
+};
+MODULE_DEVICE_TABLE(of, spacemit_pmic_of_match);
+
+struct mfd_match_data *match_data;
+
+static void spacemit_pm_power_off(void)
+{
+       int ret;
+       struct spacemit_pmic *pmic = (struct spacemit_pmic *)match_data->ptr;
+
+       ret = regmap_update_bits(pmic->regmap, match_data->shutdown.reg,
+                       match_data->shutdown.bit, match_data->shutdown.bit);
+       if (ret) {
+               pr_err("Failed to shutdown device!\n");
+       }
+
+       while (1) {
+               asm volatile ("wfi");
+       }
+
+       return;
+}
+
+static int spacemit_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
+{
+       int ret;
+       struct spacemit_pmic *pmic = (struct spacemit_pmic *)match_data->ptr;
+
+       ret = regmap_update_bits(pmic->regmap, match_data->reboot.reg,
+                       match_data->reboot.bit, match_data->reboot.bit);
+       if (ret) {
+               pr_err("Failed to reboot device!\n");
+       }
+
+       while (1) {
+               asm volatile ("wfi");
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block spacemit_restart_handler = {
+       .notifier_call = spacemit_restart_notify,
+       .priority = 0,
+};
+
+static int spacemit_prepare_sub_pmic(struct spacemit_pmic *pmic)
+{
+       struct i2c_client *client = pmic->i2c;
+       struct spacemit_sub_pmic *sub = pmic->sub;
+
+       sub->power_page_addr = pmic->i2c->addr + 1;
+
+       sub->power_page = i2c_new_dummy_device(client->adapter,
+                       sub->power_page_addr);
+       if (sub->power_page == NULL)
+               return -ENODEV;
+
+       sub->power_regmap = devm_regmap_init_i2c(sub->power_page,
+                       pmic->regmap_cfg);
+       if (IS_ERR(sub->power_regmap))
+               return PTR_ERR(sub->power_regmap);
+
+       regcache_cache_bypass(sub->power_regmap, true);
+
+       i2c_set_clientdata(sub->power_page, pmic);
+
+       return 0;
+}
+
+static int spacemit_pmic_probe(struct i2c_client *client)
+{
+       int ret;
+       int nr_cells;
+       struct device_node *np;
+       struct spacemit_pmic *pmic;
+       const struct mfd_cell *cells;
+       const struct of_device_id *of_id;
+
+       pmic = devm_kzalloc(&client->dev, sizeof(*pmic), GFP_KERNEL);
+       if (!pmic) {
+               pr_err("%s:%d, err\n", __func__, __LINE__);
+               return -ENOMEM;
+       }
+
+       of_id = of_match_device(client->dev.driver->of_match_table, &client->dev);
+       if (!of_id) {
+               pr_err("Unable to match OF ID\n");
+               return -ENODEV;
+       }
+
+       /* find the property in device node */
+       np = of_find_compatible_node(NULL, NULL, of_id->compatible);
+       if (!np)
+               return 0;
+
+       of_node_put(np);
+
+       match_data = (struct mfd_match_data *)of_id->data;
+       match_data->ptr = (void *)pmic;
+
+       pmic->regmap_cfg = match_data->regmap_cfg;
+       pmic->regmap_irq_chip = match_data->regmap_irq_chip;
+       cells = match_data->mfd_cells;
+       nr_cells = match_data->nr_cells;
+
+       if (strcmp(match_data->name, "pm853") == 0) {
+               pmic->sub = devm_kzalloc(&client->dev, sizeof(struct spacemit_sub_pmic), GFP_KERNEL);
+               if (!pmic->sub)
+                       return -ENOMEM;
+
+       }
+
+       pmic->i2c = client;
+
+       i2c_set_clientdata(client, pmic);
+
+       pmic->regmap = devm_regmap_init_i2c(client, pmic->regmap_cfg);
+       if (IS_ERR(pmic->regmap)) {
+               pr_err("%s:%d, regmap initialization failed\n",
+                               __func__, __LINE__);
+               return PTR_ERR(pmic->regmap);
+       }
+
+       regcache_cache_bypass(pmic->regmap, true);
+
+       /* prepare sub pmic */
+       if (pmic->sub) {
+               ret = spacemit_prepare_sub_pmic(pmic);
+               if (ret < 0) {
+                       pr_err("failed to prepare sub pmic %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (!client->irq) {
+               pr_warn("%s:%d, No interrupt supported\n",
+                               __func__, __LINE__);
+       } else {
+               if (pmic->regmap_irq_chip) {
+                       ret = regmap_add_irq_chip(pmic->regmap, client->irq, IRQF_ONESHOT, -1,
+                               pmic->regmap_irq_chip, &pmic->irq_data);
+                       if (ret) {
+                               pr_err("failed to add irqchip %d\n", ret);
+                               return ret;
+                       }
+               }
+
+               dev_pm_set_wake_irq(&client->dev, client->irq);
+               device_init_wakeup(&client->dev, true);
+       }
+
+       ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
+                             cells, nr_cells, NULL, 0,
+                             regmap_irq_get_domain(pmic->irq_data));
+       if (ret) {
+               pr_err("failed to add MFD devices %d\n", ret);
+               return -EINVAL;
+       }
+
+       if (match_data->shutdown.reg)
+               pm_power_off = spacemit_pm_power_off;
+
+       if (match_data->reboot.reg) {
+               ret = register_restart_handler(&spacemit_restart_handler);
+               if (ret)
+                       pr_warn("failed to register rst handler, %d\n", ret);
+       }
+
+       return 0;
+}
+
+static void spacemit_pmic_remove(struct i2c_client *client)
+{
+       /* !TODO */
+}
+
+static void spacemit_pmic_shutdown(struct i2c_client *client)
+{
+       /* !TODO */
+}
+
+static struct i2c_driver spacemit_pmic_i2c_driver = {
+       .driver = {
+               .name = "spacemit-pmic",
+               .of_match_table = spacemit_pmic_of_match,
+       },
+       .probe    = spacemit_pmic_probe,
+       .remove   = spacemit_pmic_remove,
+       .shutdown = spacemit_pmic_shutdown,
+};
+
+static int spacemit_mfd_init(void)
+{
+       int ret = i2c_add_driver(&spacemit_pmic_i2c_driver);
+       return ret;
+}
+subsys_initcall(spacemit_mfd_init);
+
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/spacemit/pm853.h b/include/linux/mfd/spacemit/pm853.h
new file mode 100644 (file)
index 0000000..173d78e
--- /dev/null
@@ -0,0 +1,328 @@
+#ifndef __PM853_H__
+#define __PM853_H__
+
+enum PM853_reg {
+       PM853_ID_DCDC1,
+       PM853_ID_DCDC2,
+       PM853_ID_DCDC3,
+       PM853_ID_DCDC4,
+       PM853_ID_DCDC5,
+       PM853_ID_LDO1,
+       PM853_ID_LDO2,
+       PM853_ID_LDO3,
+       PM853_ID_LDO4,
+       PM853_ID_LDO5,
+       PM853_ID_LDO6,
+       PM853_ID_LDO7,
+       PM853_ID_LDO8,
+       PM853_ID_LDO9,
+       PM853_ID_LDO10,
+       PM853_ID_LDO11,
+       PM853_ID_LDO12,
+       PM853_ID_LDO13,
+       PM853_ID_LDO14,
+       PM853_ID_LDO15,
+       PM853_ID_LDO16,
+       PM853_ID_LDO17,
+       PM853_ID_LDO18,
+       PM853_ID_LDO19,
+       PM853_ID_LDO20,
+       PM853_ID_LDO21,
+       PM853_ID_LDO22,
+       PM853_ID_LDO5_SW,
+};
+
+#define PM853_LDO_BUCK_EN_REG0         0x11
+#define PM853_LDO_BUCK_EN_REG1         0x12
+#define PM853_LDO_BUCK_EN_REG2         0x13
+#define PM853_LDO_BUCK_EN_REG3         0x14
+
+#define PM853_BUCK1_EN_MSK             0x1
+#define PM853_BUCK2_EN_MSK             0x2
+#define PM853_BUCK3_EN_MSK             0x4
+#define PM853_BUCK4_EN_MSK             0x8
+#define PM853_BUCK5_EN_MSK             0x10
+
+#define PM853_LDO1_EN_MSK              0x20
+#define PM853_LDO2_EN_MSK              0x40
+#define PM853_LDO3_EN_MSK              0x80
+#define PM853_LDO4_EN_MSK              0x1
+#define PM853_LDO5_EN_MSK              0x2
+#define PM853_LDO6_EN_MSK              0x4
+#define PM853_LDO7_EN_MSK              0x8
+#define PM853_LDO8_EN_MSK              0x10
+#define PM853_LDO9_EN_MSK              0x20
+#define PM853_LDO10_EN_MSK             0x40
+#define PM853_LDO11_EN_MSK             0x80
+#define PM853_LDO12_EN_MSK             0x1
+#define PM853_LDO13_EN_MSK             0x2
+#define PM853_LDO14_EN_MSK             0x4
+#define PM853_LDO15_EN_MSK             0x8
+#define PM853_LDO16_EN_MSK             0x10
+#define PM853_LDO17_EN_MSK             0x20
+#define PM853_LDO18_EN_MSK             0x40
+#define PM853_LDO19_EN_MSK             0x80
+#define PM853_LDO20_EN_MSK             0x1
+#define PM853_LDO21_EN_MSK             0x2
+#define PM853_LDO22_EN_MSK             0x4
+#define PM853_SW_EN_MSK                        0x8
+
+
+#define PM853_BUCK1_VSEL_REG           0x30
+#define PM853_BUCK2_VSEL_REG           0x50
+#define PM853_BUCK3_VSEL_REG           0x60
+#define PM853_BUCK4_VSEL_REG           0x80
+#define PM853_BUCK5_VSEL_REG           0x90
+
+#define PM853_BUCK1_VSEL_MSK           0x7f
+#define PM853_BUCK2_VSEL_MSK           0x7f
+#define PM853_BUCK3_VSEL_MSK           0x7f
+#define PM853_BUCK4_VSEL_MSK           0x7f
+#define PM853_BUCK5_VSEL_MSK           0x7f
+
+#define PM853_LDO_VSEL_MSK             0xf
+#define PM853_LDO1_VSEL_REG            0xb1
+#define PM853_LDO2_VSEL_REG            0xb4
+#define PM853_LDO3_VSEL_REG            0xb7
+#define PM853_LDO4_VSEL_REG            0xba
+#define PM853_LDO5_VSEL_REG            0xbd
+#define PM853_LDO6_VSEL_REG            0xc0
+#define PM853_LDO7_VSEL_REG            0xc3
+#define PM853_LDO8_VSEL_REG            0xc6
+#define PM853_LDO9_VSEL_REG            0xc9
+#define PM853_LDO10_VSEL_REG           0xcc
+#define PM853_LDO11_VSEL_REG           0xcf
+#define PM853_LDO12_VSEL_REG           0xd2
+#define PM853_LDO13_VSEL_REG           0xd5
+#define PM853_LDO14_VSEL_REG           0xd8
+#define PM853_LDO15_VSEL_REG           0xdb
+#define PM853_LDO16_VSEL_REG           0xde
+#define PM853_LDO17_VSEL_REG           0xe1
+#define PM853_LDO18_VSEL_REG           0xe4
+#define PM853_LDO19_VSEL_REG           0xe7
+#define PM853_LDO20_VSEL_REG           0xea
+#define PM853_LDO21_VSEL_REG           0xed
+#define PM853_LDO22_VSEL_REG           0xf0
+
+#define SPACEMIT_PM853_MAX_REG         0xf1
+
+#define PM853_MFD_CELL \
+       static const struct mfd_cell pm853[] = {                                \
+               {                                                               \
+                       .name = "spacemit-regulator@pm853",                     \
+                       .of_compatible = "pmic,regulator,pm853",                \
+               },                                                              \
+       };
+
+#define PM853_REGMAP_CONFIG    \
+       static const struct regmap_config pm853_regmap_config = {       \
+               .reg_bits = 8,  \
+               .val_bits = 8,  \
+               .max_register = SPACEMIT_PM853_MAX_REG,                 \
+               .cache_type = REGCACHE_RBTREE,  \
+       };
+
+/* regulator configuration */
+#define PM853_DESC(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr) \
+       SPM8XX_DESC_COMMON(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr,  \
+                       &pmic_dcdc_ldo_ops)
+
+#define PM853_DESC_SWITCH(_id, _match, _supply, _ereg, _emask)                \
+        SPM8XX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,     \
+        0, 0, &pmic_switch_ops)
+
+#define PM853_BUCK_LINER_RANGE1                                                \
+static const struct linear_range pm853_buck_ranges1[] = {              \
+        REGULATOR_LINEAR_RANGE(480000, 0x0, 0x50, 10000),              \
+        REGULATOR_LINEAR_RANGE(1320000, 0x51, 0x7F, 40000),            \
+};
+
+#define PM853_BUCK_LINER_RANGE2                                                \
+static const struct linear_range pm853_buck_ranges2[] = {              \
+        REGULATOR_LINEAR_RANGE(600000, 0x0, 0x50, 12500),              \
+        REGULATOR_LINEAR_RANGE(1650000, 0x51, 0x7F, 50000),            \
+};
+
+#define PM853_LDO_LINER_RANGE1                                         \
+static const struct linear_range pm853_ldo_ranges1[] = {               \
+        REGULATOR_LINEAR_RANGE(1200000, 0x0, 0x6, 100000),             \
+        REGULATOR_LINEAR_RANGE(1850000, 0x7, 0x8, 50000),              \
+        REGULATOR_LINEAR_RANGE(2750000, 0x9, 0xc, 50000),              \
+        REGULATOR_LINEAR_RANGE(3000000, 13, 14, 100000),               \
+        REGULATOR_LINEAR_RANGE(3300000, 15, 15, 0),            \
+};
+
+#define PM853_LDO_LINER_RANGE2                                         \
+static const struct linear_range pm853_ldo_ranges2[] = {               \
+        REGULATOR_LINEAR_RANGE(1600000, 0x0, 0x3, 100000),             \
+};
+
+#define PM853_LDO_LINER_RANGE3                                         \
+static const struct linear_range pm853_ldo_ranges3[] = {               \
+        REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xf, 50000),              \
+};
+
+#define PM853_LDO_LINER_RANGE4                                         \
+static const struct linear_range pm853_ldo_ranges4[] = {               \
+        REGULATOR_LINEAR_RANGE(1000000, 0x0, 0x7, 50000),              \
+};
+
+#define PM853_REGULATOR_DESC           \
+static const struct regulator_desc pm853_reg[] = {     \
+       /* BUCK */              \
+       PM853_DESC(PM853_ID_DCDC1, "DCDC_REG1", "vcc_sys",              \
+                       128, PM853_BUCK1_VSEL_REG, PM853_BUCK1_VSEL_MSK,        \
+                       PM853_LDO_BUCK_EN_REG0, PM853_BUCK1_EN_MSK,             \
+                       pm853_buck_ranges1),    \
+       \
+       PM853_DESC(PM853_ID_DCDC2, "DCDC_REG2", "vcc_sys",              \
+                       128, PM853_BUCK2_VSEL_REG, PM853_BUCK2_VSEL_MSK,        \
+                       PM853_LDO_BUCK_EN_REG0, PM853_BUCK2_EN_MSK,             \
+                       pm853_buck_ranges2),    \
+       \
+       PM853_DESC(PM853_ID_DCDC3, "DCDC_REG3", "vcc_sys",              \
+                       128, PM853_BUCK3_VSEL_REG, PM853_BUCK3_VSEL_MSK,        \
+                       PM853_LDO_BUCK_EN_REG0, PM853_BUCK3_EN_MSK,             \
+                       pm853_buck_ranges2),    \
+       \
+       PM853_DESC(PM853_ID_DCDC4, "DCDC_REG4", "vcc_sys",              \
+                       128, PM853_BUCK4_VSEL_REG, PM853_BUCK4_VSEL_MSK,        \
+                       PM853_LDO_BUCK_EN_REG0, PM853_BUCK4_EN_MSK,             \
+                       pm853_buck_ranges1),    \
+       \
+       PM853_DESC(PM853_ID_DCDC5, "DCDC_REG5", "vcc_sys",              \
+                       128, PM853_BUCK5_VSEL_REG, PM853_BUCK5_VSEL_MSK,        \
+                       PM853_LDO_BUCK_EN_REG0, PM853_BUCK5_EN_MSK,             \
+                       pm853_buck_ranges2),    \
+       \
+       /* ALDO */      \
+       PM853_DESC(PM853_ID_LDO1, "LDO_REG1", "vcc_sys",                        \
+                       16, PM853_LDO1_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG0, PM853_LDO1_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO2, "LDO_REG2", "vcc_sys",                        \
+                       16, PM853_LDO2_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG0, PM853_LDO2_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO3, "LDO_REG3", "vcc_sys",                        \
+                       16, PM853_LDO3_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG0, PM853_LDO3_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO4, "LDO_REG4", "vcc_sys",                        \
+                       16, PM853_LDO4_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO4_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO5, "LDO_REG5", "vcc_sys",                        \
+                       4, PM853_LDO5_VSEL_REG, PM853_LDO_VSEL_MSK,             \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO5_EN_MSK,              \
+                       pm853_ldo_ranges2),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO6, "LDO_REG6", "vcc_sys",                        \
+                       16, PM853_LDO6_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO6_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO7, "LDO_REG7", "dcdc2",                  \
+                       16, PM853_LDO7_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO7_EN_MSK,              \
+                       pm853_ldo_ranges3),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO8, "LDO_REG8", "vcc_sys",                        \
+                       16, PM853_LDO8_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO8_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO9, "LDO_REG9", "vcc_sys",                        \
+                       16, PM853_LDO9_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO9_EN_MSK,              \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO10, "LDO_REG10", "vcc_sys",                      \
+                       16, PM853_LDO10_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO10_EN_MSK,             \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO11, "LDO_REG11", "dcdc2",                        \
+                       16, PM853_LDO11_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG1, PM853_LDO11_EN_MSK,             \
+                       pm853_ldo_ranges3),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO12, "LDO_REG12", "vcc_sys",                      \
+                       16, PM853_LDO12_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO12_EN_MSK,             \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO13, "LDO_REG13", "vcc_sys",                      \
+                       16, PM853_LDO13_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO13_EN_MSK,             \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO14, "LDO_REG14", "vcc_sys",                      \
+                       16, PM853_LDO14_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO14_EN_MSK,             \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO15, "LDO_REG15", "dcdc2",                        \
+                       16, PM853_LDO15_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO15_EN_MSK,             \
+                       pm853_ldo_ranges3),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO16, "LDO_REG16", "vcc_sys",                      \
+                       16, PM853_LDO16_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO16_EN_MSK,             \
+                       pm853_ldo_ranges1),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO17, "LDO_REG17", "dcdc5",                        \
+                       8, PM853_LDO17_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO17_EN_MSK,             \
+                       pm853_ldo_ranges4),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO18, "LDO_REG18", "dcdc2",                        \
+                       16, PM853_LDO18_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO18_EN_MSK,             \
+                       pm853_ldo_ranges3),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO19, "LDO_REG19", "dcdc5",                        \
+                       8, PM853_LDO19_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG2, PM853_LDO19_EN_MSK,             \
+                       pm853_ldo_ranges4),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO20, "LDO_REG20", "dcdc5",                        \
+                       8, PM853_LDO20_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG3, PM853_LDO20_EN_MSK,             \
+                       pm853_ldo_ranges4),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO21, "LDO_REG21", "dcdc2",                        \
+                       16, PM853_LDO21_VSEL_REG, PM853_LDO_VSEL_MSK,           \
+                       PM853_LDO_BUCK_EN_REG3, PM853_LDO21_EN_MSK,             \
+                       pm853_ldo_ranges3),                                     \
+       \
+       PM853_DESC(PM853_ID_LDO22, "LDO_REG22", "dcdc5",                        \
+                       8, PM853_LDO22_VSEL_REG, PM853_LDO_VSEL_MSK,            \
+                       PM853_LDO_BUCK_EN_REG3, PM853_LDO22_EN_MSK,             \
+                       pm853_ldo_ranges4),                                     \
+       \
+       /* PWR SWITCH */        \
+       PM853_DESC_SWITCH(PM853_ID_LDO5_SW, "SWITCH_REG1", "vcc_sys", PM853_LDO_BUCK_EN_REG3, PM853_SW_EN_MSK),         \
+};
+
+#define PM853_MFD_MATCH_DATA                           \
+static struct mfd_match_data pm853_mfd_match_data = {  \
+       .regmap_cfg = &pm853_regmap_config,             \
+       .mfd_cells = pm853,                             \
+       .nr_cells = ARRAY_SIZE(pm853),                  \
+       .name = "pm853",                                \
+};
+
+#define PM853_REGULATOR_MATCH_DATA                                     \
+static struct regulator_match_data pm853_regulator_match_data = {      \
+       .desc = pm853_reg,                                              \
+       .nr_desc = ARRAY_SIZE(pm853_reg),                               \
+       .name = "pm853",                                                \
+};
+
+#endif
diff --git a/include/linux/mfd/spacemit/spacemit_pmic.h b/include/linux/mfd/spacemit/spacemit_pmic.h
new file mode 100644 (file)
index 0000000..f878198
--- /dev/null
@@ -0,0 +1,319 @@
+#ifndef __SPACEMIT_PMIC_H__
+#define __SPACEMIT_PMIC_H__
+
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
+
+/**
+ * this is only used for pm853
+ */
+struct spacemit_sub_pmic {
+       struct i2c_client *power_page;
+       struct regmap *power_regmap;
+       unsigned short power_page_addr;
+};
+
+struct spacemit_pmic {
+       struct i2c_client               *i2c;
+       struct regmap_irq_chip_data     *irq_data;
+       struct regmap                   *regmap;
+       const struct regmap_config      *regmap_cfg;
+       const struct regmap_irq_chip    *regmap_irq_chip;
+       /**
+        * this is only used for pm853
+        */
+       struct spacemit_sub_pmic *sub;
+};
+
+/* pinctrl */
+struct pin_func_desc {
+       const char *name;
+       unsigned char pin_id;
+       unsigned char func_reg;
+       unsigned char func_mask;
+       unsigned char en_val;
+       unsigned char ha_sub;
+       unsigned char sub_reg;
+       unsigned char sub_mask;
+       unsigned char sube_val;
+};
+
+struct pin_config_desc {
+       unsigned int pin_id;
+       /* input config desc */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } input;
+
+       /* output config desc */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } output;
+
+       /* pull-down desc */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } pup;
+
+       /* deb */
+       struct {
+               unsigned char reg;
+               unsigned char timemsk;
+
+               struct {
+                       unsigned char msk;
+               } en;
+       } deb;
+
+       /* OD */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } od;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } itype;
+};
+
+/* rtc */
+union rtc_ctl_desc {
+       unsigned char val;
+       struct {
+               unsigned char crystal_en:1;
+               unsigned char out_32k_en:1;
+               unsigned char rtc_en:1;
+               unsigned char rtc_clk_sel:1;
+               unsigned char tick_type:1;
+               unsigned char alarm_en:1;
+               unsigned char tick_en:1;
+               unsigned char reserved:1;
+       } bits;
+};
+
+struct rtc_regdesc {
+       /* seconds */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } cnt_s;
+
+       /* mini */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } cnt_mi;
+
+       /* hour */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } cnt_h;
+
+       /* day */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } cnt_d;
+
+       /* mounth */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } cnt_mo;
+
+       /* year */
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } cnt_y;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } rtc_sec_a;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } rtc_sec_b;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } rtc_sec_c;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } rtc_sec_d;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } alarm_s;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } alarm_mi;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } alarm_h;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } alarm_d;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } alarm_mo;
+
+       struct {
+               unsigned char reg;
+               unsigned char msk;
+       } alarm_y;
+
+       struct  {
+               unsigned char reg;
+       } rtc_ctl;
+};
+
+/* mfd: match data */
+struct mfd_match_data {
+       const struct regmap_config *regmap_cfg;
+       const struct regmap_irq_chip *regmap_irq_chip;
+       const struct mfd_cell *mfd_cells;
+       int nr_cells;
+       const char *name;
+       void *ptr;
+
+       /* shutdown - reboot support */
+       struct {
+               unsigned char reg;
+               unsigned char bit;
+       } shutdown;
+
+       struct {
+               unsigned int reg;
+               unsigned char bit;
+       } reboot;
+};
+
+/* regulator: match data */
+struct regulator_match_data {
+       int nr_desc;
+       const struct regulator_desc *desc;
+       const char *name;
+};
+
+/* pinctrl: match data */
+struct pinctrl_match_data {
+       int nr_pin_mux;
+       const char **pinmux_funcs;
+       int nr_pin_fuc_desc;
+       const struct pin_func_desc *pinfunc_desc;
+       int nr_pin_conf_desc;
+       const struct pin_config_desc *pinconf_desc;
+       const char *name;
+};
+
+/* common regulator defination */
+#define SPM8XX_DESC_COMMON(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr, _ops)       \
+       {                                                               \
+               .name           = (_match),                             \
+               .supply_name    = (_supply),                            \
+               .of_match       = of_match_ptr(_match),                 \
+               .regulators_node = of_match_ptr("regulators"),          \
+               .ops            = _ops,                 \
+               .type           = REGULATOR_VOLTAGE,                    \
+               .id             = (_id),                                \
+               .n_voltages     = (_nv),                                \
+               .owner          = THIS_MODULE,                          \
+               .vsel_reg       = (_vr),                                \
+               .vsel_mask      = (_vm),                                \
+               .enable_reg     = (_er),                                \
+               .enable_mask    = (_em),                                \
+               .volt_table     = NULL,                                 \
+               .linear_ranges  = (_lr),                                \
+               .n_linear_ranges        = ARRAY_SIZE(_lr),              \
+       }
+
+#define SPM8XX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,    \
+       _enval, _disval, _ops)                                          \
+       {                                                               \
+               .name           = (_match),                             \
+               .supply_name    = (_supply),                            \
+               .of_match       = of_match_ptr(_match),                 \
+               .regulators_node = of_match_ptr("regulators"),          \
+               .type           = REGULATOR_VOLTAGE,                    \
+               .id             = (_id),                                \
+               .enable_reg     = (_ereg),                              \
+               .enable_mask    = (_emask),                             \
+               .enable_val     = (_enval),                             \
+               .disable_val     = (_disval),                           \
+               .owner          = THIS_MODULE,                          \
+               .ops            = _ops                                  \
+       }
+
+#define SPM8XX_DESC_PIN_FUNC_COM(_pin_id, _match, _ereg, _emask,       \
+       _enval, _hsub, _subreg, _submask, _subenval                     \
+       )                                                               \
+       {                                                               \
+               .name           = (_match),                             \
+               .pin_id         = (_pin_id),                            \
+               .func_reg       = (_ereg),                              \
+               .func_mask      = (_emask),                             \
+               .en_val         = (_enval),                             \
+               .ha_sub         = (_hsub),                              \
+               .sub_reg        = (_subreg),                            \
+               .sub_mask       = (_submask),                           \
+               .sube_val       = (_subenval),                          \
+       }
+
+#define SPM8XX_DESC_PIN_CONFIG_COM(_pin_id, _ireg, _imsk, _oreg, _omsk,                \
+       _pureg, _pumsk, _debreg, _debtmsk, _debemsk, _odreg, _odmsk,            \
+       _itypereg, _itypemsk                                                    \
+       )                                                       \
+       {                                                       \
+               .pin_id = (_pin_id),                            \
+               .input = {                                      \
+                       .reg = (_ireg),                         \
+                       .msk = (_imsk),                         \
+               },                                              \
+               .output = {                                     \
+                       .reg = (_oreg),                         \
+                       .msk = (_omsk),                         \
+               },                                              \
+               .pup = {                                        \
+                       .reg = (_pureg),                        \
+                       .msk = (_pumsk),                        \
+               },                                              \
+               .deb = {                                        \
+                       .reg = (_debreg),                       \
+                       .timemsk = (_debtmsk),                  \
+                       .en.msk = (_debemsk)                    \
+               },                                              \
+               .od = {                                         \
+                       .reg = (_odreg),                        \
+                       .msk = (_odmsk),                        \
+               },                                              \
+               .itype = {                                      \
+                       .reg = (_itypereg),                     \
+                       .msk = (_itypemsk),                     \
+               },                                              \
+       }
+
+#include "spm8821.h"
+#include "pm853.h"
+#include "sy8810l.h"
+
+#endif /* __SPACEMIT_PMIC_H__ */
diff --git a/include/linux/mfd/spacemit/spm8821.h b/include/linux/mfd/spacemit/spm8821.h
new file mode 100644 (file)
index 0000000..a1e3b00
--- /dev/null
@@ -0,0 +1,807 @@
+#ifndef __SMP8821_H__
+#define __SMP8821_H__
+
+enum SPM8821_reg {
+       SPM8821_ID_DCDC1,
+       SPM8821_ID_DCDC2,
+       SPM8821_ID_DCDC3,
+       SPM8821_ID_DCDC4,
+       SPM8821_ID_DCDC5,
+       SPM8821_ID_DCDC6,
+       SPM8821_ID_LDO1,
+       SPM8821_ID_LDO2,
+       SPM8821_ID_LDO3,
+       SPM8821_ID_LDO4,
+       SPM8821_ID_LDO5,
+       SPM8821_ID_LDO6,
+       SPM8821_ID_LDO7,
+       SPM8821_ID_LDO8,
+       SPM8821_ID_LDO9,
+       SPM8821_ID_LDO10,
+       SPM8821_ID_LDO11,
+       SPM8821_ID_SWITCH1,
+};
+
+#define SPACEMIT_SPM8821_MAX_REG       0xA8
+
+#define SPM8821_BUCK_VSEL_MASK         0xff
+#define SMP8821_BUCK_EN_MASK           0x1
+
+#define SPM8821_BUCK1_CTRL_REG         0x47
+#define SPM8821_BUCK2_CTRL_REG         0x4a
+#define SPM8821_BUCK3_CTRL_REG         0x4d
+#define SPM8821_BUCK4_CTRL_REG         0x50
+#define SPM8821_BUCK5_CTRL_REG         0x53
+#define SPM8821_BUCK6_CTRL_REG         0x56
+
+#define SPM8821_BUCK1_VSEL_REG         0x48
+#define SPM8821_BUCK2_VSEL_REG         0x4b
+#define SPM8821_BUCK3_VSEL_REG         0x4e
+#define SPM8821_BUCK4_VSEL_REG         0x51
+#define SPM8821_BUCK5_VSEL_REG         0x54
+#define SPM8821_BUCK6_VSEL_REG         0x57
+
+#define SPM8821_ALDO1_CTRL_REG         0x5b
+#define SPM8821_ALDO2_CTRL_REG         0x5e
+#define SPM8821_ALDO3_CTRL_REG         0x61
+#define SPM8821_ALDO4_CTRL_REG         0x64
+
+#define SPM8821_ALDO1_VOLT_REG         0x5c
+#define SPM8821_ALDO2_VOLT_REG         0x5f
+#define SPM8821_ALDO3_VOLT_REG         0x62
+#define SPM8821_ALDO4_VOLT_REG         0x65
+
+#define SPM8821_ALDO_EN_MASK           0x1
+#define SPM8821_ALDO_VSEL_MASK         0x7f
+
+#define SPM8821_DLDO1_CTRL_REG         0x67
+#define SPM8821_DLDO2_CTRL_REG         0x6a
+#define SPM8821_DLDO3_CTRL_REG         0x6d
+#define SPM8821_DLDO4_CTRL_REG         0x70
+#define SPM8821_DLDO5_CTRL_REG         0x73
+#define SPM8821_DLDO6_CTRL_REG         0x76
+#define SPM8821_DLDO7_CTRL_REG         0x79
+
+#define SPM8821_DLDO1_VOLT_REG         0x68
+#define SPM8821_DLDO2_VOLT_REG         0x6b
+#define SPM8821_DLDO3_VOLT_REG         0x6e
+#define SPM8821_DLDO4_VOLT_REG         0x71
+#define SPM8821_DLDO5_VOLT_REG         0x74
+#define SPM8821_DLDO6_VOLT_REG         0x77
+#define SPM8821_DLDO7_VOLT_REG         0x7a
+
+#define SPM8821_DLDO_EN_MASK           0x1
+#define SPM8821_DLDO_VSEL_MASK         0x7f
+
+#define SPM8821_SWITCH_CTRL_REG                0x59
+#define SPM8821_SWTICH_EN_MASK         0x1
+
+#define SPM8821_PWR_CTRL2              0x7e
+#define SPM8821_SW_SHUTDOWN_BIT_MSK    0x4
+#define SPM8821_SW_RESET_BIT_MSK       0x2
+
+#define SPM8821_REGMAP_CONFIG  \
+       static const struct regmap_config spm8821_regmap_config = {     \
+               .reg_bits = 8,  \
+               .val_bits = 8,  \
+               .max_register = SPACEMIT_SPM8821_MAX_REG,       \
+               .cache_type = REGCACHE_RBTREE,  \
+       };
+
+/* regulator configuration */
+#define SPM8821_DESC(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr)       \
+       SPM8XX_DESC_COMMON(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr,  \
+                       &pmic_dcdc_ldo_ops)
+
+#define SPM8821_DESC_SWITCH(_id, _match, _supply, _ereg, _emask)       \
+       SPM8XX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,     \
+       0, 0, &pmic_switch_ops)
+
+
+#define SPM8821_BUCK_LINER_RANGE                                       \
+static const struct linear_range spm8821_buck_ranges[] = {             \
+        REGULATOR_LINEAR_RANGE(500000, 0x0, 0xaa, 5000),               \
+        REGULATOR_LINEAR_RANGE(1375000, 0xab, 0xfe, 25000),            \
+};
+
+
+#define SPM8821_LDO_LINER_RANGE                                                \
+static const struct linear_range spm8821_ldo_ranges[] = {              \
+        REGULATOR_LINEAR_RANGE(500000, 0xb, 0x7f, 25000),              \
+};
+
+#define SPM8821_REGULATOR_DESC         \
+static const struct regulator_desc spm8821_reg[] = {   \
+       /* BUCK */              \
+       SPM8821_DESC(SPM8821_ID_DCDC1, "DCDC_REG1", "vcc_sys",          \
+                       255, SPM8821_BUCK1_VSEL_REG, SPM8821_BUCK_VSEL_MASK,    \
+                       SPM8821_BUCK1_CTRL_REG, SMP8821_BUCK_EN_MASK,           \
+                       spm8821_buck_ranges),   \
+       \
+       SPM8821_DESC(SPM8821_ID_DCDC2, "DCDC_REG2", "vcc_sys",          \
+                       255, SPM8821_BUCK2_VSEL_REG, SPM8821_BUCK_VSEL_MASK,    \
+                       SPM8821_BUCK2_CTRL_REG, SMP8821_BUCK_EN_MASK,   \
+                       spm8821_buck_ranges),   \
+       \
+       SPM8821_DESC(SPM8821_ID_DCDC3, "DCDC_REG3", "vcc_sys",          \
+                       255, SPM8821_BUCK3_VSEL_REG, SPM8821_BUCK_VSEL_MASK,    \
+                       SPM8821_BUCK3_CTRL_REG, SMP8821_BUCK_EN_MASK,   \
+                       spm8821_buck_ranges),   \
+       \
+       SPM8821_DESC(SPM8821_ID_DCDC4, "DCDC_REG4", "vcc_sys",  \
+                       255, SPM8821_BUCK4_VSEL_REG, SPM8821_BUCK_VSEL_MASK,    \
+                       SPM8821_BUCK4_CTRL_REG, SMP8821_BUCK_EN_MASK,   \
+                       spm8821_buck_ranges),   \
+       \
+       SPM8821_DESC(SPM8821_ID_DCDC5, "DCDC_REG5", "vcc_sys",          \
+                       255, SPM8821_BUCK5_VSEL_REG, SPM8821_BUCK_VSEL_MASK,    \
+                       SPM8821_BUCK5_CTRL_REG, SMP8821_BUCK_EN_MASK,   \
+                       spm8821_buck_ranges),   \
+       \
+       SPM8821_DESC(SPM8821_ID_DCDC6, "DCDC_REG6", "vcc_sys",  \
+                       255, SPM8821_BUCK6_VSEL_REG, SPM8821_BUCK_VSEL_MASK,    \
+                       SPM8821_BUCK6_CTRL_REG, SMP8821_BUCK_EN_MASK,   \
+                       spm8821_buck_ranges),   \
+       /* ALDO */      \
+       SPM8821_DESC(SPM8821_ID_LDO1, "LDO_REG1", "vcc_sys",    \
+                       128, SPM8821_ALDO1_VOLT_REG, SPM8821_ALDO_VSEL_MASK,    \
+                       SPM8821_ALDO1_CTRL_REG, SPM8821_ALDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO2, "LDO_REG2", "vcc_sys",    \
+                       128, SPM8821_ALDO2_VOLT_REG, SPM8821_ALDO_VSEL_MASK,    \
+                       SPM8821_ALDO2_CTRL_REG, SPM8821_ALDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO3, "LDO_REG3", "vcc_sys",    \
+                       128, SPM8821_ALDO3_VOLT_REG, SPM8821_ALDO_VSEL_MASK,    \
+                       SPM8821_ALDO3_CTRL_REG, SPM8821_ALDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO4, "LDO_REG4", "vcc_sys",    \
+                       128, SPM8821_ALDO4_VOLT_REG, SPM8821_ALDO_VSEL_MASK,    \
+                       SPM8821_ALDO4_CTRL_REG, SPM8821_ALDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       /* DLDO */      \
+       SPM8821_DESC(SPM8821_ID_LDO5, "LDO_REG5", "dcdc5",              \
+                       128, SPM8821_DLDO1_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO1_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO6, "LDO_REG6", "dcdc5",      \
+                       128, SPM8821_DLDO2_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO2_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO7, "LDO_REG7", "dcdc5",              \
+                       128, SPM8821_DLDO3_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO3_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO8, "LDO_REG8", "dcdc5",              \
+                       128, SPM8821_DLDO4_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO4_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO9, "LDO_REG9", "dcdc5",              \
+                       128, SPM8821_DLDO5_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO5_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO10, "LDO_REG10", "dcdc5",            \
+                       128, SPM8821_DLDO6_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO6_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       SPM8821_DESC(SPM8821_ID_LDO11, "LDO_REG11", "dcdc5",            \
+                       128, SPM8821_DLDO7_VOLT_REG, SPM8821_DLDO_VSEL_MASK,    \
+                       SPM8821_DLDO7_CTRL_REG, SPM8821_DLDO_EN_MASK, spm8821_ldo_ranges),      \
+       \
+       /* PWR SWITCH */        \
+       SPM8821_DESC_SWITCH(SPM8821_ID_SWITCH1, "SWITCH_REG1", "vcc_sys", SPM8821_SWITCH_CTRL_REG, SPM8821_SWTICH_EN_MASK),             \
+};
+
+/* gpio set */
+#define SPM8821_PINMUX_DESC            \
+const char* spm8821_pinmux_functions[] = {     \
+       "gpioin", "gpioout", "exten", "pwrctrl",        \
+       "sleep", "nreset", "adcin"                      \
+};
+
+#define SPM8821_PINFUNC_DESC   \
+static const struct pin_func_desc spm8821_pinfunc_desc[] = {   \
+       /* PIN0 gpioin */                               \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "gpioin", 0x8, 0x3, 0, 0, 0, 0, 0),                         \
+       /* PIN0 gpioout*/                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "gpioout", 0x8, 0x3, 1, 0, 0, 0, 0),                        \
+       /* PIN0 exten */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "exten", 0x8, 0x3, 0x3, 1, 0xa, 0x7, 0x0),                  \
+       /* PIN0 pwrctrl */                                      \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "pwrctrl", 0x8, 0x3, 0x3, 1, 0xa, 0x7, 0x1),                \
+       /* PIN0 sleep */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "sleep", 0x8, 0x3, 0x3, 1, 0xa, 0x7, 0x2),                  \
+       /* PIN0 nreset */                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "nreset", 0x8, 0x3, 0x3, 1, 0xa, 0x7, 0x3),         \
+       /* PIN0 adcin */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(0, "adcin", 0x8, 0x3, 0x3, 1, 0xa, 0x7, 0x4),                  \
+       /* PIN1 gpioin */                               \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "gpioin", 0x8, 0xc, 0, 0, 0, 0, 0),                         \
+       /* PIN1 gpioout*/                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "gpioout", 0x8, 0xc, 1, 0, 0, 0, 0),                        \
+       /* PIN1 exten */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "exten", 0x8, 0xc, 0x3, 1, 0xa, 0x38, 0x0),         \
+       /* PIN1 pwrctrl */                                      \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "pwrctrl", 0x8, 0xc, 0x3, 1, 0xa, 0x38, 0x1),               \
+       /* PIN1 sleep */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "sleep", 0x8, 0xc, 0x3, 1, 0xa, 0x38, 0x2),         \
+       /* PIN1 nreset */                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "nreset", 0x8, 0xc, 0x3, 1, 0xa, 0x38, 0x3),                \
+       /* PIN1 adcin */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(1, "adcin", 0x8, 0xc, 0x3, 1, 0xa, 0x38, 0x4),         \
+       /* PIN2 gpioin */                               \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "gpioin", 0x8, 0x30, 0, 0, 0, 0, 0),                        \
+       /* PIN2 gpioout*/                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "gpioout", 0x8, 0x30, 1, 0, 0, 0, 0),                       \
+       /* PIN2 exten */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "exten", 0x8, 0x30, 0x3, 1, 0xb, 0x7, 0x0),         \
+       /* PIN2 pwrctrl */                                      \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "pwrctrl", 0x8, 0x30, 0x3, 1, 0xb, 0x7, 0x1),               \
+       /* PIN2 sleep */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "sleep", 0x8, 0x30, 0x3, 1, 0xb, 0x7, 0x2),         \
+       /* PIN2 nreset */                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "nreset", 0x8, 0x30, 0x3, 1, 0xb, 0x7, 0x3),                \
+       /* PIN2 adcin */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(2, "adcin", 0x8, 0x30, 0x3, 1, 0xb, 0x7, 0x4),         \
+       /* PIN3 gpioin */                               \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "gpioin", 0x9, 0x3, 0, 0, 0, 0, 0),                 \
+       /* PIN3 gpioout*/                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "gpioout", 0x9, 0x3, 1, 0, 0, 0, 0),                        \
+       /* PIN3 exten */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "exten", 0x9, 0x3, 0x3, 1, 0xb, 0x38, 0x0),         \
+       /* PIN3 pwrctrl */                                      \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "pwrctrl", 0x9, 0x3, 0x3, 1, 0xb, 0x38, 0x1),               \
+       /* PIN3 sleep */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "sleep", 0x9, 0x3, 0x3, 1, 0xb, 0x38, 0x2),         \
+       /* PIN3 nreset */                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "nreset", 0x9, 0x3, 0x3, 1, 0xb, 0x38, 0x3),                \
+       /* PIN3 adcin */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(3, "adcin", 0x9, 0x3, 0x3, 1, 0xb, 0x38, 0x4),         \
+       /* PIN4 gpioin */                               \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "gpioin", 0x9, 0xc, 0, 0, 0, 0, 0),                 \
+       /* PIN4 gpioout*/                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "gpioout", 0x9, 0xc, 1, 0, 0, 0, 0),                        \
+       /* PIN4 exten */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "exten", 0x9, 0xc, 0x3, 1, 0xc, 0x7, 0x0),          \
+       /* PIN4 pwrctrl */                                      \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "pwrctrl", 0x9, 0xc, 0x3, 1, 0xc, 0x7, 0x1),                \
+       /* PIN4 sleep */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "sleep", 0x9, 0xc, 0x3, 1, 0xc, 0x7, 0x2),          \
+       /* PIN4 nreset */                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "nreset", 0x9, 0xc, 0x3, 1, 0xc, 0x7, 0x3),         \
+       /* PIN4 adcin */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(4, "adcin", 0x9, 0xc, 0x3, 1, 0xc, 0x7, 0x4),          \
+       /* PIN5 gpioin */                               \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "gpioin", 0x9, 0x30, 0, 0, 0, 0, 0),                        \
+       /* PIN5 gpioout*/                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "gpioout", 0x9, 0x30, 1, 0, 0, 0, 0),                       \
+       /* PIN5 exten */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "exten", 0x9, 0x30, 0x3, 1, 0xc, 0x38, 0x0),                \
+       /* PIN5 pwrctrl */                                      \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "pwrctrl", 0x9, 0x30, 0x3, 1, 0xc, 0x38, 0x1),              \
+       /* PIN5 sleep */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "sleep", 0x9, 0x30, 0x3, 1, 0xc, 0x38, 0x2),                \
+       /* PIN5 nreset */                                       \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "nreset", 0x9, 0x30, 0x3, 1, 0xc, 0x38, 0x3),               \
+       /* PIN5 adcin */                                        \
+       SPM8XX_DESC_PIN_FUNC_COM(5, "adcin", 0x9, 0x30, 0x3, 1, 0xc, 0x38, 0x4),                \
+};
+
+#define SPM8821_PIN_CINFIG_DESC                                \
+static const struct pin_config_desc spm8821_pinconfig_desc[] = \
+{                                                                                              \
+       SPM8XX_DESC_PIN_CONFIG_COM(0, 0x0, 0x1, 0x1, 0x1, 0x2, 0x3, 0x4, 0xc0, 0x1, 0x5, 0x1, 0x6, 0x3),                \
+       SPM8XX_DESC_PIN_CONFIG_COM(1, 0x0, 0x2, 0x1, 0x2, 0x2, 0xC, 0x4, 0xc0, 0x2, 0x5, 0x2, 0x6, 0xC),                \
+       SPM8XX_DESC_PIN_CONFIG_COM(2, 0x0, 0x4, 0x1, 0x4, 0x2, 0x30, 0x4, 0xc0, 0x4, 0x5, 0x4, 0x6, 0x30),              \
+       SPM8XX_DESC_PIN_CONFIG_COM(3, 0x0, 0x8, 0x1, 0x8, 0x3, 0x3, 0x4, 0xc0, 0x8, 0x5, 0x8, 0x7, 0x3),                \
+       SPM8XX_DESC_PIN_CONFIG_COM(4, 0x0, 0x10, 0x1, 0x10, 0x3, 0xc, 0x4, 0xc0, 0x10, 0x5, 0x10, 0x7, 0xc),            \
+       SPM8XX_DESC_PIN_CONFIG_COM(5, 0x0, 0x20, 0x1, 0x20, 0x3, 0x30, 0x4, 0xc0, 0x20, 0x5, 0x20, 0x7, 0x30),          \
+};
+
+/* irq description */
+enum IRQ_line {
+       /* reg: 0x91 */
+       SPM8821_E_GPI0,
+       SPM8821_E_GPI1,
+       SPM8821_E_GPI2,
+       SPM8821_E_GPI3,
+       SPM8821_E_GPI4,
+       SPM8821_E_GPI5,
+
+       /* reg: 0x92 */
+       SPM8821_E_ADC_TEMP,
+       SPM8821_E_ADC_EOC,
+       SPM8821_E_ADC_EOS,
+       SPM8821_E_WDT_TO,
+       SPM8821_E_ALARM,
+       SPM8821_E_TICK,
+
+       /* reg: 0x93 */
+       SPM8821_E_LDO_OV,
+       SPM8821_E_LDO_UV,
+       SPM8821_E_LDO_SC,
+       SPM8821_E_SW_SC,
+       SPM8821_E_TEMP_WARN,
+       SPM8821_E_TEMP_SEVERE,
+       SPM8821_E_TEMP_CRIT,
+
+       /* reg: 0x94 */
+       SPM8821_E_BUCK1_OV,
+       SPM8821_E_BUCK2_OV,
+       SPM8821_E_BUCK3_OV,
+       SPM8821_E_BUCK4_OV,
+       SPM8821_E_BUCK5_OV,
+       SPM8821_E_BUCK6_OV,
+
+       /* reg: 0x95 */
+       SPM8821_E_BUCK1_UV,
+       SPM8821_E_BUCK2_UV,
+       SPM8821_E_BUCK3_UV,
+       SPM8821_E_BUCK4_UV,
+       SPM8821_E_BUCK5_UV,
+       SPM8821_E_BUCK6_UV,
+
+       /* reg: 0x96 */
+       SPM8821_E_BUCK1_SC,
+       SPM8821_E_BUCK2_SC,
+       SPM8821_E_BUCK3_SC,
+       SPM8821_E_BUCK4_SC,
+       SPM8821_E_BUCK5_SC,
+       SPM8821_E_BUCK6_SC,
+
+       /* reg: 0x97 */
+       SPM8821_E_PWRON_RINTR,
+       SPM8821_E_PWRON_FINTR,
+       SPM8821_E_PWRON_SINTR,
+       SPM8821_E_PWRON_LINTR,
+       SPM8821_E_PWRON_SDINTR,
+       SPM8821_E_VSYS_OV,
+};
+
+#define SPM8821_E_GPI0_MSK     BIT(0)
+#define SPM8821_E_GPI1_MSK     BIT(1)
+#define SPM8821_E_GPI2_MSK     BIT(2)
+#define SPM8821_E_GPI3_MSK     BIT(3)
+#define SPM8821_E_GPI4_MSK     BIT(4)
+#define SPM8821_E_GPI5_MSK     BIT(5)
+
+#define SPM8821_E_ADC_TEMP_MSK BIT(0)
+#define SPM8821_E_ADC_EOC_MSK  BIT(1)
+#define SPM8821_E_ADC_EOS_MSK  BIT(2)
+#define SPM8821_E_WDT_TO_MSK   BIT(3)
+#define SPM8821_E_ALARM_MSK    BIT(4)
+#define SPM8821_E_TICK_MSK     BIT(5)
+
+#define SPM8821_E_LDO_OV_MSK   BIT(0)
+#define SPM8821_E_LDO_UV_MSK   BIT(1)
+#define SPM8821_E_LDO_SC_MSK   BIT(2)
+#define SPM8821_E_SW_SC_MSK    BIT(3)
+#define SPM8821_E_TEMP_WARN_MSK        BIT(4)
+#define SPM8821_E_TEMP_SEVERE_MSK      BIT(5)
+#define SPM8821_E_TEMP_CRIT_MSK                BIT(6)
+
+#define SPM8821_E_BUCK1_OV_MSK BIT(0)
+#define SPM8821_E_BUCK2_OV_MSK BIT(1)
+#define SPM8821_E_BUCK3_OV_MSK BIT(2)
+#define SPM8821_E_BUCK4_OV_MSK BIT(3)
+#define SPM8821_E_BUCK5_OV_MSK BIT(4)
+#define SPM8821_E_BUCK6_OV_MSK BIT(5)
+
+#define SPM8821_E_BUCK1_UV_MSK BIT(0)
+#define SPM8821_E_BUCK2_UV_MSK BIT(1)
+#define SPM8821_E_BUCK3_UV_MSK BIT(2)
+#define SPM8821_E_BUCK4_UV_MSK BIT(3)
+#define SPM8821_E_BUCK5_UV_MSK BIT(4)
+#define SPM8821_E_BUCK6_UV_MSK BIT(5)
+
+#define SPM8821_E_BUCK1_SC_MSK BIT(0)
+#define SPM8821_E_BUCK2_SC_MSK BIT(1)
+#define SPM8821_E_BUCK3_SC_MSK BIT(2)
+#define SPM8821_E_BUCK4_SC_MSK BIT(3)
+#define SPM8821_E_BUCK5_SC_MSK BIT(4)
+#define SPM8821_E_BUCK6_SC_MSK BIT(5)
+
+#define SPM8821_E_PWRON_RINTR_MSK      BIT(0)
+#define SPM8821_E_PWRON_FINTR_MSK      BIT(1)
+#define SPM8821_E_PWRON_SINTR_MSK      BIT(2)
+#define SPM8821_E_PWRON_LINTR_MSK      BIT(3)
+#define SPM8821_E_PWRON_SDINTR_MSK     BIT(4)
+#define SPM8821_E_VSYS_OV_MSK          BIT(5)
+
+#define SPM8821_E_STATUS_REG_BASE      0x91
+#define SPM8821_E_EN_REG_BASE          0x98
+
+#define SPM8821_IRQS_DESC                              \
+static const struct regmap_irq spm8821_irqs[] = {      \
+       [SPM8821_E_GPI0] = {                            \
+               .mask = SPM8821_E_GPI0_MSK,             \
+               .reg_offset = 0,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_GPI1] = {                            \
+               .mask = SPM8821_E_GPI1_MSK,             \
+               .reg_offset = 0,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_GPI2] = {                            \
+               .mask = SPM8821_E_GPI2_MSK,             \
+               .reg_offset = 0,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_GPI3] = {                            \
+               .mask = SPM8821_E_GPI3_MSK,             \
+               .reg_offset = 0,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_GPI4] = {                            \
+               .mask = SPM8821_E_GPI4_MSK,             \
+               .reg_offset = 0,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_GPI5] = {                            \
+               .mask = SPM8821_E_GPI5_MSK,             \
+               .reg_offset = 0,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_ADC_TEMP] = {                        \
+               .mask = SPM8821_E_ADC_TEMP_MSK,         \
+               .reg_offset = 1,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_ADC_EOC] = {                         \
+               .mask = SPM8821_E_ADC_EOC_MSK,          \
+               .reg_offset = 1,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_ADC_EOS] = {                         \
+               .mask = SPM8821_E_ADC_EOS_MSK,          \
+               .reg_offset = 1,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_WDT_TO] = {                          \
+               .mask = SPM8821_E_WDT_TO_MSK,           \
+               .reg_offset = 1,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_ALARM] = {                           \
+               .mask = SPM8821_E_ALARM_MSK,            \
+               .reg_offset = 1,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_TICK] = {                            \
+               .mask = SPM8821_E_TICK_MSK,             \
+               .reg_offset = 1,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_LDO_OV] = {                          \
+               .mask = SPM8821_E_LDO_OV_MSK,           \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_LDO_UV] = {                          \
+               .mask = SPM8821_E_LDO_UV_MSK,           \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_LDO_SC] = {                          \
+               .mask = SPM8821_E_LDO_SC_MSK,           \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_SW_SC] = {                           \
+               .mask = SPM8821_E_SW_SC_MSK,            \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_TEMP_WARN] = {                       \
+               .mask = SPM8821_E_TEMP_WARN_MSK,        \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_TEMP_SEVERE] = {                     \
+               .mask = SPM8821_E_TEMP_SEVERE_MSK,      \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_TEMP_CRIT] = {                       \
+               .mask = SPM8821_E_TEMP_CRIT_MSK,        \
+               .reg_offset = 2,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK1_OV] = {                        \
+               .mask = SPM8821_E_BUCK1_OV_MSK,         \
+               .reg_offset = 3,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK2_OV] = {                        \
+               .mask = SPM8821_E_BUCK2_OV_MSK,         \
+               .reg_offset = 3,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK3_OV] = {                        \
+               .mask = SPM8821_E_BUCK3_OV_MSK,         \
+               .reg_offset = 3,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK4_OV] = {                        \
+               .mask = SPM8821_E_BUCK4_OV_MSK,         \
+               .reg_offset = 3,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK5_OV] = {                        \
+               .mask = SPM8821_E_BUCK5_OV_MSK,         \
+               .reg_offset = 3,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK6_OV] = {                        \
+               .mask = SPM8821_E_BUCK6_OV_MSK,         \
+               .reg_offset = 3,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK1_UV] = {                        \
+               .mask = SPM8821_E_BUCK1_UV_MSK,         \
+               .reg_offset = 4,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK2_UV] = {                        \
+               .mask = SPM8821_E_BUCK2_UV_MSK,         \
+               .reg_offset = 4,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK3_UV] = {                        \
+               .mask = SPM8821_E_BUCK3_UV_MSK,         \
+               .reg_offset = 4,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK4_UV] = {                        \
+               .mask = SPM8821_E_BUCK4_UV_MSK,         \
+               .reg_offset = 4,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK5_UV] = {                        \
+               .mask = SPM8821_E_BUCK5_UV_MSK,         \
+               .reg_offset = 4,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK6_UV] = {                        \
+               .mask = SPM8821_E_BUCK6_UV_MSK,         \
+               .reg_offset = 4,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK1_SC] = {                        \
+               .mask = SPM8821_E_BUCK1_SC_MSK,         \
+               .reg_offset = 5,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK2_SC] = {                        \
+               .mask = SPM8821_E_BUCK2_SC_MSK,         \
+               .reg_offset = 5,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK3_SC] = {                        \
+               .mask = SPM8821_E_BUCK3_SC_MSK,         \
+               .reg_offset = 5,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK4_SC] = {                        \
+               .mask = SPM8821_E_BUCK4_SC_MSK,         \
+               .reg_offset = 5,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK5_SC] = {                        \
+               .mask = SPM8821_E_BUCK5_SC_MSK,         \
+               .reg_offset = 5,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_BUCK6_SC] = {                        \
+               .mask = SPM8821_E_BUCK6_SC_MSK,         \
+               .reg_offset = 5,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_PWRON_RINTR] = {                     \
+               .mask = SPM8821_E_PWRON_RINTR_MSK,      \
+               .reg_offset = 6,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_PWRON_FINTR] = {                     \
+               .mask = SPM8821_E_PWRON_FINTR_MSK,      \
+               .reg_offset = 6,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_PWRON_SINTR] = {                     \
+               .mask = SPM8821_E_PWRON_SINTR_MSK,      \
+               .reg_offset = 6,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_PWRON_LINTR] = {                     \
+               .mask = SPM8821_E_PWRON_LINTR_MSK,      \
+               .reg_offset = 6,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_PWRON_SDINTR] = {                    \
+               .mask = SPM8821_E_PWRON_SDINTR_MSK,     \
+               .reg_offset = 6,                        \
+       },                                              \
+                                                       \
+       [SPM8821_E_VSYS_OV] = {                         \
+               .mask = SPM8821_E_VSYS_OV_MSK,          \
+               .reg_offset = 6,                        \
+       },                                              \
+};
+
+
+#define SPM8821_IRQ_CHIP_DESC                          \
+static const struct regmap_irq_chip spm8821_irq_chip = {       \
+       .name = "spm8821",                                      \
+       .irqs = spm8821_irqs,                                   \
+       .num_irqs = ARRAY_SIZE(spm8821_irqs),                   \
+       .num_regs = 7,                                          \
+       .status_base = SPM8821_E_STATUS_REG_BASE,               \
+       .ack_base = SPM8821_E_STATUS_REG_BASE,                  \
+       .init_ack_masked = true,                                \
+       .unmask_base = SPM8821_E_EN_REG_BASE,                   \
+};
+
+/* power-key */
+#define SPM8821_POWER_KEY_RESOURCES_DESC                       \
+static const struct resource spm8821_pwrkey_resources[] = {    \
+       DEFINE_RES_IRQ(SPM8821_E_PWRON_RINTR),                  \
+       DEFINE_RES_IRQ(SPM8821_E_PWRON_FINTR),                  \
+       DEFINE_RES_IRQ(SPM8821_E_PWRON_SINTR),                  \
+       DEFINE_RES_IRQ(SPM8821_E_PWRON_LINTR),                  \
+};
+
+/* rtc desc */
+#define SPM8821_RTC_RESOURCES_DESC                             \
+static const struct resource spm8821_rtc_resources[] = {       \
+       DEFINE_RES_IRQ(SPM8821_E_ALARM),                        \
+};
+
+#define SPM8821_RTC_REG_DESC                                   \
+static const struct rtc_regdesc spm8821_regdesc = {            \
+       .cnt_s = {                                              \
+               .reg = 0xd,                                     \
+               .msk = 0x3f,                                    \
+       },                                                      \
+                                                               \
+       .cnt_mi = {                                             \
+               .reg = 0xe,                                     \
+               .msk = 0x3f,                                    \
+       },                                                      \
+                                                               \
+       .cnt_h = {                                              \
+               .reg = 0xf,                                     \
+               .msk = 0x1f,                                    \
+       },                                                      \
+                                                               \
+       .cnt_d = {                                              \
+               .reg = 0x10,                                    \
+               .msk = 0x1f,                                    \
+       },                                                      \
+                                                               \
+       .cnt_mo = {                                             \
+               .reg = 0x11,                                    \
+               .msk = 0xf,                                     \
+       },                                                      \
+                                                               \
+       .cnt_y = {                                              \
+               .reg = 0x12,                                    \
+               .msk = 0x3f,                                    \
+       },                                                      \
+                                                               \
+       .rtc_sec_a = {                                          \
+               .reg = 0x19,                                    \
+               .msk = 0xff,                                    \
+       },                                                      \
+                                                               \
+       .rtc_sec_b = {                                          \
+               .reg = 0x1a,                                    \
+               .msk = 0xff,                                    \
+       },                                                      \
+                                                               \
+       .rtc_sec_c = {                                          \
+               .reg = 0x1b,                                    \
+               .msk = 0xff,                                    \
+       },                                                      \
+                                                               \
+       .rtc_sec_d = {                                          \
+               .reg = 0x1c,                                    \
+               .msk = 0xff,                                    \
+       },                                                      \
+                                                               \
+       .alarm_s = {                                            \
+               .reg = 0x13,                                    \
+               .msk = 0x3f,                                    \
+       },                                                      \
+                                                               \
+       .alarm_mi = {                                           \
+               .reg = 0x14,                                    \
+               .msk = 0x3f,                                    \
+       },                                                      \
+                                                               \
+       .alarm_h = {                                            \
+               .reg = 0x15,                                    \
+               .msk = 0x1f,                                    \
+       },                                                      \
+                                                               \
+       .alarm_d = {                                            \
+               .reg = 0x16,                                    \
+               .msk = 0x1f,                                    \
+       },                                                      \
+                                                               \
+       .alarm_mo = {                                           \
+               .reg = 0x17,                                    \
+               .msk = 0xf,                                     \
+       },                                                      \
+                                                               \
+       .alarm_y = {                                            \
+               .reg = 0x18,                                    \
+               .msk = 0x3f,                                    \
+       },                                                      \
+                                                               \
+       .rtc_ctl = {                                            \
+               .reg = 0x1d,                                    \
+       },                                                      \
+}; 
+
+/* mfd configuration */
+#define SPM8821_MFD_CELL       \
+       static const struct mfd_cell spm8821[] = {                              \
+               {                                                               \
+                       .name = "spacemit-regulator@spm8821",                   \
+                       .of_compatible = "pmic,regulator,spm8821",              \
+               },                                                              \
+               {                                                               \
+                       .name = "spacemit-pinctrl@spm8821",                     \
+                       .of_compatible = "pmic,pinctrl,spm8821",                \
+               },                                                              \
+               {                                                               \
+                       .name = "spacemit-pwrkey@spm8821",                      \
+                       .of_compatible = "pmic,pwrkey,spm8821",                 \
+                       .num_resources = ARRAY_SIZE(spm8821_pwrkey_resources),  \
+                       .resources = &spm8821_pwrkey_resources[0],              \
+               },                                                              \
+               {                                                               \
+                       .name = "spacemit-rtc@spm8821",                         \
+                       .of_compatible = "pmic,rtc,spm8821",                    \
+                       .num_resources = ARRAY_SIZE(spm8821_rtc_resources),     \
+                       .resources = &spm8821_rtc_resources[0],                 \
+               },                                                              \
+       };
+
+#define SPM8821_MFD_MATCH_DATA                                 \
+static struct mfd_match_data spm8821_mfd_match_data = {                \
+       .regmap_cfg = &spm8821_regmap_config,                   \
+       .regmap_irq_chip = &spm8821_irq_chip,                   \
+       .mfd_cells = spm8821,                                   \
+       .nr_cells = ARRAY_SIZE(spm8821),                        \
+       .name = "spm8821",                                      \
+       .shutdown = {                                           \
+               .reg = SPM8821_PWR_CTRL2,                       \
+               .bit = SPM8821_SW_SHUTDOWN_BIT_MSK,             \
+       },                                                      \
+       .reboot = {                                             \
+               .reg = SPM8821_PWR_CTRL2,                       \
+               .bit = SPM8821_SW_RESET_BIT_MSK,                \
+       },                                                      \
+};
+
+#define SPM8821_PINCTRL_MATCH_DATA                             \
+static struct pinctrl_match_data spm8821_pinctrl_match_data = {                                \
+       .nr_pin_mux = ARRAY_SIZE(spm8821_pinmux_functions),     \
+       .pinmux_funcs = spm8821_pinmux_functions,               \
+       .nr_pin_fuc_desc = ARRAY_SIZE(spm8821_pinfunc_desc),    \
+       .pinfunc_desc = spm8821_pinfunc_desc,                   \
+       .nr_pin_conf_desc = ARRAY_SIZE(spm8821_pinconfig_desc), \
+       .pinconf_desc = spm8821_pinconfig_desc,                 \
+       .name = "spm8821",                                      \
+};
+
+#define SPM8821_REGULATOR_MATCH_DATA                                   \
+static struct regulator_match_data spm8821_regulator_match_data = {    \
+       .nr_desc = ARRAY_SIZE(spm8821_reg),                             \
+       .desc = spm8821_reg,                                            \
+       .name = "spm8821",                                              \
+};
+
+#endif /* __SPM8821_H__ */
diff --git a/include/linux/mfd/spacemit/sy8810l.h b/include/linux/mfd/spacemit/sy8810l.h
new file mode 100644 (file)
index 0000000..091d444
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef __SY8810L_H__
+#define __SY8810L_H__
+
+enum SY8810L_reg {
+       SY8810L_ID_DCDC1,
+};
+
+#define SPACEMIT_SY8810L_MAX_REG       0x2
+
+#define SY8810L_BUCK_VSEL_MASK         0x3f
+#define SY8810L_BUCK_EN_MASK           0x80
+
+#define SY8810L_BUCK_CTRL_REG          0x1
+#define SY8810L_BUCK_VSEL_REG          0x0
+
+#define SY8810L_REGMAP_CONFIG  \
+       static const struct regmap_config sy8810l_regmap_config = {     \
+               .reg_bits = 8,  \
+               .val_bits = 8,  \
+               .max_register = SPACEMIT_SY8810L_MAX_REG,       \
+               .cache_type = REGCACHE_RBTREE,  \
+       };
+
+/* regulator configuration */
+#define SY8810L_DESC(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr)       \
+       SPM8XX_DESC_COMMON(_id, _match, _supply, _nv, _vr, _vm, _er, _em, _lr,  \
+                       &pmic_dcdc_ldo_ops)
+
+#define SY8810L_BUCK_LINER_RANGE                                       \
+static const struct linear_range sy8810l_buck_ranges[] = {             \
+        REGULATOR_LINEAR_RANGE(600000, 0x0, 0x5a, 10000),              \
+};
+
+#define SY8810L_REGULATOR_DESC         \
+static const struct regulator_desc sy8810l_reg[] = {   \
+       /* BUCK */              \
+       SY8810L_DESC(SY8810L_ID_DCDC1, "EDCDC_REG1", "dcdc1",           \
+                       91, SY8810L_BUCK_VSEL_REG, SY8810L_BUCK_VSEL_MASK,      \
+                       SY8810L_BUCK_CTRL_REG, SY8810L_BUCK_EN_MASK,            \
+                       sy8810l_buck_ranges),   \
+};
+
+/* mfd configuration */
+#define SY8810L_MFD_CELL       \
+       static const struct mfd_cell sy8810l[] = {                              \
+               {                                                               \
+                       .name = "spacemit-regulator@sy8810l",                   \
+                       .of_compatible = "pmic,regulator,sy8810l",              \
+               },                                                              \
+       };
+
+#define SY8810L_MFD_MATCH_DATA                                 \
+static struct mfd_match_data sy8810l_mfd_match_data = {                \
+       .regmap_cfg = &sy8810l_regmap_config,                   \
+       .mfd_cells = sy8810l,                                   \
+       .nr_cells = ARRAY_SIZE(sy8810l),                        \
+       .name = "sy8810l",                                      \
+};
+
+#define SY8810L_REGULATOR_MATCH_DATA                                   \
+static struct regulator_match_data sy8810l_regulator_match_data = {    \
+       .nr_desc = ARRAY_SIZE(sy8810l_reg),                             \
+       .desc = sy8810l_reg,                                            \
+       .name = "sy8810l",                                              \
+};
+
+#endif