@@ -1030,6 +1030,32 @@ config MFD_MT6397
accessing the device; additional drivers must be enabled in order
to use the functionality of the device.
+config MFD_MT6685
+ tristate "MT6685 SPMI PMIC"
+ depends on OF
+ depends on SPMI
+ select REGMAP_SPMI
+ select REGMAP_IRQ
+ help
+ This enables support for the Mediatek SPMI PMICs.
+ These PMICs are currently used with the Mediatek series of
+ SoCs. Note, that this will only be useful paired with descriptions
+ of the independent functions as children nodes in the device tree.
+
+config MFD_MTK_SPMI_PMIC
+ tristate "Mediatek SPMI PMICs"
+ depends on OF
+ depends on SPMI
+ select REGMAP_SPMI
+ help
+ This enables support for the Mediatek SPMI PMICs.
+ These PMICs are currently used with the MT63xx series of
+ SoCs. Note, that this will only be useful paired with descriptions
+ of the independent functions as children nodes in the device tree.
+
+ Say M here if you want to include support for the SPMI PMIC
+ series as a module. The module will be called "mtk-spmi-pmic".
+
config MFD_MENF21BMC
tristate "MEN 14F021P00 Board Management Controller Support"
depends on I2C
@@ -182,6 +182,8 @@ obj-$(CONFIG_MFD_MT6360) += mt6360-core.o
obj-$(CONFIG_MFD_MT6370) += mt6370.o
mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o
obj-$(CONFIG_MFD_MT6397) += mt6397.o
+obj-$(CONFIG_MFD_MT6685) += mt6685-core.o
+obj-$(CONFIG_MFD_MTK_SPMI_PMIC) += mtk-spmi-pmic.o
pcf50633-objs := pcf50633-core.o pcf50633-irq.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/spmi.h>
+
+static const struct mfd_cell mt6685_devs[] = {
+ {
+ .name = "mt6685-clkbuf",
+ .of_compatible = "mediatek,mt6685-clkbuf",
+ }, {
+ .name = "mt6685-tb-clkbuf",
+ .of_compatible = "mediatek,mt6685-tb-clkbuf",
+ }, {
+ .name = "mt6685-rtc",
+ .of_compatible = "mediatek,mt6685-rtc",
+ }, {
+ .name = "mt6685-audclk",
+ .of_compatible = "mediatek,mt6685-audclk",
+ }, {
+ .name = "mt6685-consys",
+ .of_compatible = "mediatek,mt6685-consys",
+ }, {
+ .name = "mt6685-gps",
+ .of_compatible = "mediatek,mt6685-gps",
+ }
+};
+
+static const struct regmap_config spmi_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x2000,
+ .fast_io = true,
+ .use_single_read = true,
+ .use_single_write = true
+};
+
+static int mt6685_spmi_probe(struct spmi_device *sdev) {
+ int ret;
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&sdev->dev, "Failed to init mt6685 regmap: %ld\n", PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ ret = devm_mfd_add_devices(&sdev->dev, -1, mt6685_devs,
+ ARRAY_SIZE(mt6685_devs), NULL, 0, NULL);
+ if (ret) {
+ dev_err(&sdev->dev, "Failed to add child devices: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id mt6685_id_table[] = {
+ { .compatible = "mediatek,mt6685", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mt6685_id_table);
+
+static struct spmi_driver mt6685_spmi_driver = {
+ .probe = mt6685_spmi_probe,
+ .driver = {
+ .name = "mt6685",
+ .of_match_table = mt6685_id_table,
+ },
+};
+module_spmi_driver(mt6685_spmi_driver);
+
+MODULE_DESCRIPTION("Mediatek SPMI MT6685 Clock IC driver");
+MODULE_AUTHOR("Lu Tang <lu.tang@mediatek.com>"); MODULE_LICENSE("GPL");
@@ -0,0 +1,518 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/mt6363/core.h>
+#include <linux/mfd/mt6363/registers.h> #include
+<linux/mfd/mt6373/core.h> #include <linux/mfd/mt6373/registers.h>
+#include <linux/module.h> #include <linux/mutex.h> #include
+<linux/of_device.h> #include <linux/of_platform.h> #include
+<linux/of_irq.h> #include <linux/regmap.h> #include <linux/spmi.h>
+
+#define MTK_SPMI_PMIC_REG_WIDTH 8
+#define PMIC_SWCID 0xB
+#define PMIC_MT6316_SWCID 0x20B
+#define RCS_INT_DONE 0x41B
+
+struct irq_top_t {
+ int hwirq_base;
+ unsigned int num_int_regs;
+ unsigned int en_reg;
+ unsigned int en_reg_shift;
+ unsigned int sta_reg;
+ unsigned int sta_reg_shift;
+ unsigned int top_offset;
+};
+
+struct mtk_spmi_pmic_data {
+ const struct mfd_cell *cells;
+ int cell_size;
+ unsigned int num_top;
+ unsigned int num_pmic_irqs;
+ unsigned short top_int_status_reg;
+ struct irq_top_t *pmic_ints;
+ unsigned int cid_addr;
+};
+
+struct pmic_core {
+ struct device *dev;
+ struct spmi_device *sdev;
+ struct regmap *regmap;
+ u16 chip_id;
+ int irq;
+ bool *enable_hwirq;
+ bool *cache_hwirq;
+ struct mutex irqlock;
+ struct irq_domain *irq_domain;
+ const struct mtk_spmi_pmic_data *chip_data; };
+
+static const struct resource mt6363_regulators_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VCN15_OC, "VCN15"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VCN13_OC, "VCN13"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VRF09_OC, "VRF09"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VRF12_OC, "VRF12"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VRF13_OC, "VRF13"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VRF18_OC, "VRF18"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VRFIO18_OC, "VRFIO18"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VSRAM_MDFE_OC, "VSRAM_MDFE"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VTREF18_OC, "VTREF18"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VSRAM_APU_OC, "VSRAM_APU"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VAUX18_OC, "VAUX18"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VEMC_OC, "VEMC"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VUFS12_OC, "VUFS12"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VUFS18_OC, "VUFS18"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VIO18_OC, "VIO18"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VIO075_OC, "VIO075"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VA12_1_OC, "VA12_1"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VA12_2_OC, "VA12_2"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VA15_OC, "VA15"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_VM18_OC, "VM18"), };
+
+static const struct resource mt6363_keys_resources[] = {
+ DEFINE_RES_IRQ(MT6363_IRQ_PWRKEY),
+ DEFINE_RES_IRQ(MT6363_IRQ_HOMEKEY),
+ DEFINE_RES_IRQ(MT6363_IRQ_PWRKEY_R),
+ DEFINE_RES_IRQ(MT6363_IRQ_HOMEKEY_R),
+};
+
+static const struct resource mt6363_lvsys_notify_resources[] = {
+ /* MT6363 LVSYS interrupt name is contrary,
+ * we name LVSYS_R to MT6363_IRQ_NI_LVSYS_INT_FALLING;
+ * LVSYS_F to MT6363_IRQ_NI_LVSYS_INT_RISING
+ */
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_NI_LVSYS_INT_FALLING, "LVSYS_R"),
+ DEFINE_RES_IRQ_NAMED(MT6363_IRQ_NI_LVSYS_INT_RISING, "LVSYS_F"), };
+
+static const struct resource mt6373_regulators_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VUSB_OC, "VUSB"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VAUX18_OC, "VAUX18"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VRF13_AIF_OC, "VRF13_AIF"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VRF18_AIF_OC, "VRF18_AIF"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VRFIO18_AIF_OC, "VRFIO18_AIF"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VCN33_1_OC, "VCN33_1"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VCN33_2_OC, "VCN33_2"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VCN33_3_OC, "VCN33_3"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VCN18IO_OC, "VCN18IO"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VRF09_AIF_OC, "VRF09_AIF"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VRF12_AIF_OC, "VRF12_AIF"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VANT18_OC, "VANT18"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VSRAM_DIGRF_AIF_OC, "VSRAM_DIGRF_AIF"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VEFUSE_OC, "VEFUSE"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VMCH_OC, "VMCH"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VMC_OC, "VMC"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VIBR_OC, "VIBR"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VIO28_OC, "VIO28"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VFP_OC, "VFP"),
+ DEFINE_RES_IRQ_NAMED(MT6373_IRQ_VTP_OC, "VTP"), };
+
+static const struct mfd_cell mt6363_devs[] = {
+ {
+ .name = "mt6363-auxadc",
+ .of_compatible = "mediatek,mt6363-auxadc",
+ }, {
+ .name = "mtk-dynamic-loading-throttling",
+ .of_compatible = "mediatek,mt6363-dynamic_loading_throttling",
+ }, {
+ .name = "mt6363-efuse",
+ .of_compatible = "mediatek,mt6363-efuse",
+ }, {
+ .name = "mt6363-regulator",
+ .num_resources = ARRAY_SIZE(mt6363_regulators_resources),
+ .resources = mt6363_regulators_resources,
+ .of_compatible = "mediatek,mt6363-regulator",
+ }, {
+ .name = "mtk-pmic-keys",
+ .num_resources = ARRAY_SIZE(mt6363_keys_resources),
+ .resources = mt6363_keys_resources,
+ .of_compatible = "mediatek,mt6363-keys"
+ }, {
+ .name = "mt6363-consys",
+ .of_compatible = "mediatek,mt6363-consys",
+ }, {
+ .name = "mt6363-lvsys-notify",
+ .num_resources = ARRAY_SIZE(mt6363_lvsys_notify_resources),
+ .resources = mt6363_lvsys_notify_resources,
+ .of_compatible = "mediatek,mt6363-lvsys-notify",
+ }, {
+ .name = "mt6363-pinctrl",
+ .of_compatible = "mediatek,mt6363-pinctrl",
+ },
+};
+
+static const struct mfd_cell mt6373_devs[] = {
+ {
+ .name = "mt6373-regulator",
+ .num_resources = ARRAY_SIZE(mt6373_regulators_resources),
+ .resources = mt6373_regulators_resources,
+ .of_compatible = "mediatek,mt6373-regulator",
+ }, {
+ .name = "mt6373-auxadc",
+ .of_compatible = "mediatek,mt6373-auxadc",
+ }, {
+ .name = "mt6373-efuse",
+ .of_compatible = "mediatek,mt6373-efuse",
+ }, {
+ .name = "mt6373-consys",
+ .of_compatible = "mediatek,mt6373-consys",
+ }, {
+ .name = "mt6373-pinctrl",
+ .of_compatible = "mediatek,mt6373-pinctrl",
+ },
+};
+
+static struct irq_top_t mt6363_ints[] = {
+ MT6363_TOP_GEN(BUCK),
+ MT6363_TOP_GEN(LDO),
+ MT6363_TOP_GEN(PSC),
+ MT6363_TOP_GEN(MISC),
+ MT6363_TOP_GEN(HK),
+ MT6363_TOP_GEN(BM),
+};
+
+
+static struct irq_top_t mt6373_ints[] = {
+ MT6373_TOP_GEN(BUCK),
+ MT6373_TOP_GEN(LDO),
+ MT6373_TOP_GEN(MISC),
+};
+
+static const struct mtk_spmi_pmic_data mt6316_data = {
+ .num_pmic_irqs = 0,
+ .cid_addr = PMIC_MT6316_SWCID,
+};
+
+static const struct mtk_spmi_pmic_data mt6363_data = {
+ .cells = mt6363_devs,
+ .cell_size = ARRAY_SIZE(mt6363_devs),
+ .num_top = ARRAY_SIZE(mt6363_ints),
+ .num_pmic_irqs = MT6363_IRQ_NR,
+ .top_int_status_reg = MT6363_TOP_INT_STATUS1,
+ .pmic_ints = mt6363_ints,
+};
+
+static const struct mtk_spmi_pmic_data mt6373_data = {
+ .cells = mt6373_devs,
+ .cell_size = ARRAY_SIZE(mt6373_devs),
+ .num_top = ARRAY_SIZE(mt6373_ints),
+ .num_pmic_irqs = MT6373_IRQ_NR,
+ .top_int_status_reg = MT6373_TOP_INT_STATUS1,
+ .pmic_ints = mt6373_ints,
+};
+
+static void mtk_spmi_pmic_irq_enable(struct irq_data *data) {
+ unsigned int hwirq = irqd_to_hwirq(data);
+ struct pmic_core *core = irq_data_get_irq_chip_data(data);
+
+ core->enable_hwirq[hwirq] = true;
+}
+
+static void mtk_spmi_pmic_irq_disable(struct irq_data *data) {
+ unsigned int hwirq = irqd_to_hwirq(data);
+ struct pmic_core *core = irq_data_get_irq_chip_data(data);
+
+ core->enable_hwirq[hwirq] = false;
+}
+
+static void mtk_spmi_pmic_irq_lock(struct irq_data *data) {
+ struct pmic_core *core = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&core->irqlock);
+}
+
+static void mtk_spmi_pmic_irq_sync_unlock(struct irq_data *data) {
+ unsigned int i, top_gp, gp_offset, en_reg, int_regs, shift;
+ struct irq_top_t *pmic_int;
+ struct pmic_core *core = irq_data_get_irq_chip_data(data);
+ const struct mtk_spmi_pmic_data *chip_data = core->chip_data;
+
+ for (i = 0; i < chip_data->num_pmic_irqs; i++) {
+ if (core->enable_hwirq[i] == core->cache_hwirq[i])
+ continue;
+
+ /* Find out the IRQ group */
+ top_gp = 0;
+ while ((top_gp + 1) < chip_data->num_top &&
+ i >= chip_data->pmic_ints[top_gp + 1].hwirq_base)
+ top_gp++;
+
+ pmic_int = &(chip_data->pmic_ints[top_gp]);
+ /* Find the IRQ registers */
+ gp_offset = i - pmic_int->hwirq_base;
+ int_regs = gp_offset / MTK_SPMI_PMIC_REG_WIDTH;
+ shift = gp_offset % MTK_SPMI_PMIC_REG_WIDTH;
+ en_reg = pmic_int->en_reg + (pmic_int->en_reg_shift * int_regs);
+
+ regmap_update_bits(core->regmap, en_reg, BIT(shift),
+ core->enable_hwirq[i] << shift);
+ core->cache_hwirq[i] = core->enable_hwirq[i];
+ }
+ mutex_unlock(&core->irqlock);
+}
+
+static struct irq_chip mtk_spmi_pmic_irq_chip = {
+ .name = "spmi-pmic-irq",
+ .flags = IRQCHIP_SKIP_SET_WAKE,
+ .irq_enable = mtk_spmi_pmic_irq_enable,
+ .irq_disable = mtk_spmi_pmic_irq_disable,
+ .irq_bus_lock = mtk_spmi_pmic_irq_lock,
+ .irq_bus_sync_unlock = mtk_spmi_pmic_irq_sync_unlock, };
+
+static void mtk_spmi_pmic_irq_sp_handler(struct pmic_core *core,
+ unsigned int top_gp)
+{
+ unsigned int irq_status = 0, sta_reg, status;
+ unsigned int hwirq, virq;
+ int ret, i, j;
+ struct irq_top_t *pmic_int;
+ const struct mtk_spmi_pmic_data *chip_data = core->chip_data;
+
+ for (i = 0; i < chip_data->pmic_ints[top_gp].num_int_regs; i++) {
+ pmic_int = &(chip_data->pmic_ints[top_gp]);
+ sta_reg = pmic_int->sta_reg + (pmic_int->sta_reg_shift * i);
+
+ ret = regmap_read(core->regmap, sta_reg, &irq_status);
+ if (ret) {
+ dev_err(core->dev,
+ "Failed to read irq status: %d\n", ret);
+ return;
+ }
+
+ if (!irq_status)
+ continue;
+
+ status = irq_status;
+ do {
+ j = __ffs(status);
+
+ hwirq = pmic_int->hwirq_base + MTK_SPMI_PMIC_REG_WIDTH * i + j;
+
+ virq = irq_find_mapping(core->irq_domain, hwirq);
+ dev_info(core->dev, "[%x]Reg[0x%x]=0x%x,hwirq=%d\n",
+ core->chip_id, sta_reg, irq_status, hwirq);
+ if (virq)
+ handle_nested_irq(virq);
+
+ status &= ~BIT(j);
+ } while (status);
+
+ regmap_write(core->regmap, sta_reg, irq_status);
+ }
+}
+
+static irqreturn_t mtk_spmi_pmic_irq_handler(int irq, void *data) {
+ int ret;
+ unsigned int bit, i, top_irq_status = 0;
+ struct pmic_core *core = data;
+ const struct mtk_spmi_pmic_data *chip_data = core->chip_data;
+
+ ret = regmap_read(core->regmap, chip_data->top_int_status_reg,
+ &top_irq_status);
+ if (ret) {
+ dev_err(core->dev,
+ "Failed to read status from the device, ret=%d\n", ret);
+ return IRQ_NONE;
+ }
+
+ dev_info(core->dev, "top_irq_sts:0x%x\n", top_irq_status);
+ for (i = 0; i < chip_data->num_top; i++) {
+ bit = BIT(chip_data->pmic_ints[i].top_offset);
+ if (top_irq_status & bit)
+ mtk_spmi_pmic_irq_sp_handler(core, i);
+ }
+
+ ret = regmap_write(core->regmap, RCS_INT_DONE, 1);
+ if (ret) {
+ dev_err(core->dev,
+ "Failed to clear RCS flag, ret=%d\n", ret);
+ return IRQ_NONE;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int mtk_spmi_pmic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct pmic_core *core = d->host_data;
+
+ irq_set_chip_data(irq, core);
+ irq_set_chip_and_handler(irq, &mtk_spmi_pmic_irq_chip,
+ handle_level_irq);
+ irq_set_nested_thread(irq, 1);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops pmic_irq_domain_ops = {
+ .map = mtk_spmi_pmic_irq_domain_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int mtk_spmi_pmic_irq_init(struct pmic_core *core) {
+ int i, j, ret;
+ unsigned int en_reg, sta_reg;
+ const struct mtk_spmi_pmic_data *chip_data = core->chip_data;
+
+ mutex_init(&core->irqlock);
+ core->enable_hwirq = devm_kcalloc(core->dev,
+ chip_data->num_pmic_irqs,
+ sizeof(bool), GFP_KERNEL);
+ if (!core->enable_hwirq)
+ return -ENOMEM;
+
+ core->cache_hwirq = devm_kcalloc(core->dev,
+ chip_data->num_pmic_irqs,
+ sizeof(bool), GFP_KERNEL);
+ if (!core->cache_hwirq)
+ return -ENOMEM;
+
+ /* Disable all interrupt for initializing */
+ for (i = 0; i < chip_data->num_top; i++) {
+ for (j = 0; j < chip_data->pmic_ints[i].num_int_regs; j++) {
+ en_reg = chip_data->pmic_ints[i].en_reg +
+ chip_data->pmic_ints[i].en_reg_shift * j;
+ regmap_write(core->regmap, en_reg, 0);
+ sta_reg = chip_data->pmic_ints[i].sta_reg +
+ chip_data->pmic_ints[i].sta_reg_shift * j;
+ regmap_write(core->regmap, sta_reg, 0xFF);
+ }
+ }
+ regmap_write(core->regmap, RCS_INT_DONE, 1);
+
+ core->irq_domain = irq_domain_add_linear(core->dev->of_node,
+ chip_data->num_pmic_irqs,
+ &pmic_irq_domain_ops,
+ core);
+ if (!core->irq_domain) {
+ dev_err(core->dev, "Could not create IRQ domain\n");
+ return -ENODEV;
+ }
+
+ ret = devm_request_threaded_irq(core->dev, core->irq, NULL,
+ mtk_spmi_pmic_irq_handler, IRQF_ONESHOT,
+ mtk_spmi_pmic_irq_chip.name, core);
+ if (ret) {
+ dev_err(core->dev, "Failed to register IRQ=%d, ret=%d\n",
+ core->irq, ret);
+ return ret;
+ }
+
+ enable_irq_wake(core->irq);
+ return ret;
+}
+
+static const struct regmap_config spmi_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0xffff,
+ .fast_io = true,
+};
+
+static int mtk_spmi_pmic_probe(struct spmi_device *sdev) {
+ int ret;
+ unsigned int id;
+ struct device_node *np = sdev->dev.of_node;
+ struct pmic_core *core;
+ const struct mtk_spmi_pmic_data *chip_data;
+
+ core = devm_kzalloc(&sdev->dev, sizeof(*core), GFP_KERNEL);
+ if (!core)
+ return -ENOMEM;
+
+ core->sdev = sdev;
+ core->dev = &sdev->dev;
+ chip_data = (struct mtk_spmi_pmic_data *)of_device_get_match_data(&sdev->dev);
+ if (!chip_data)
+ return -ENODEV;
+
+ core->chip_data = chip_data;
+ core->regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
+ if (IS_ERR(core->regmap))
+ return PTR_ERR(core->regmap);
+ if (chip_data->cid_addr)
+ ret = regmap_read(core->regmap, chip_data->cid_addr, &id);
+ else
+ ret = regmap_read(core->regmap, PMIC_SWCID, &id);
+ if (ret || id == 0) {
+ dev_err(&sdev->dev, "Failed to read chip id: %d\n", ret);
+ return ret;
+ }
+
+ core->chip_id = id;
+
+ if (chip_data->num_pmic_irqs) {
+ core->irq = of_irq_get(np, 0);
+ if (core->irq < 0)
+ dev_err(&sdev->dev, "Failed to get irq(%d)\n", core->irq);
+
+ ret = mtk_spmi_pmic_irq_init(core);
+ if (ret)
+ dev_err(&sdev->dev, "IRQ_init failed(%d)\n", core->irq);
+
+ ret = devm_mfd_add_devices(&sdev->dev, -1, chip_data->cells,
+ chip_data->cell_size, NULL, 0,
+ core->irq_domain);
+ if (ret) {
+ irq_domain_remove(core->irq_domain);
+ dev_err(&sdev->dev, "Failed to add mfd devices: %d\n", ret);
+ return ret;
+ }
+ } else {
+ ret = devm_of_platform_populate(&sdev->dev);
+ if (ret) {
+ dev_err(&sdev->dev, "Failed to platform populate: %d\n", ret);
+ return ret;
+ }
+ }
+
+ device_init_wakeup(&sdev->dev, true);
+
+ dev_dbg(&sdev->dev, "probe chip id=0x%x done\n", core->chip_id);
+
+ return ret;
+}
+
+static const struct of_device_id mtk_spmi_pmic_of_match[] = {
+ { .compatible = "mediatek,mt6316", .data = &mt6316_data, },
+ { .compatible = "mediatek,mt6363", .data = &mt6363_data, },
+ { .compatible = "mediatek,mt6373", .data = &mt6373_data, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mtk_spmi_pmic_of_match);
+
+static struct spmi_driver mtk_spmi_pmic_driver = {
+ .driver = {
+ .name = "mtk-spmi-pmic",
+ .of_match_table = of_match_ptr(mtk_spmi_pmic_of_match),
+ },
+ .probe = mtk_spmi_pmic_probe,
+};
+module_spmi_driver(mtk_spmi_pmic_driver);
+
+MODULE_DESCRIPTION("Mediatek SPMI PMIC driver");
+MODULE_ALIAS("spmi:spmi-pmic"); MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Argus Lin <argus.lin@mediatek.com>");
+MODULE_AUTHOR("Jeter Chen <jeter.chen@mediatek.com>");
+MODULE_AUTHOR("Lu Tang <lu.tang@mediatek.com>");
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MFD_MT6363_CORE_H__
+#define __MFD_MT6363_CORE_H__
+
+#define MT6363_REG_WIDTH 8
+
+enum mt6363_irq_top_status_shift {
+ MT6363_BUCK_TOP = 0,
+ MT6363_LDO_TOP,
+ MT6363_PSC_TOP,
+ MT6363_MISC_TOP,
+ MT6363_HK_TOP,
+ MT6363_SCK_TOP,
+ MT6363_BM_TOP,
+ MT6363_AUD_TOP,
+};
+
+enum mt6363_irq_numbers {
+ MT6363_IRQ_VS2_OC = 0,
+ MT6363_IRQ_VBUCK1_OC,
+ MT6363_IRQ_VBUCK2_OC,
+ MT6363_IRQ_VBUCK3_OC,
+ MT6363_IRQ_VBUCK4_OC,
+ MT6363_IRQ_VBUCK5_OC,
+ MT6363_IRQ_VBUCK6_OC,
+ MT6363_IRQ_VBUCK7_OC,
+ MT6363_IRQ_VS1_OC,
+ MT6363_IRQ_VS3_OC,
+ MT6363_IRQ_VCN15_OC = 16,
+ MT6363_IRQ_VCN13_OC,
+ MT6363_IRQ_VRF09_OC,
+ MT6363_IRQ_VRF12_OC,
+ MT6363_IRQ_VRF13_OC,
+ MT6363_IRQ_VRF18_OC,
+ MT6363_IRQ_VRFIO18_OC,
+ MT6363_IRQ_VSRAM_DIGRF_OC,
+ MT6363_IRQ_VSRAM_MDFE_OC,
+ MT6363_IRQ_VSRAM_MODEM_OC,
+ MT6363_IRQ_VTREF18_OC,
+ MT6363_IRQ_VSRAM_CPUB_OC,
+ MT6363_IRQ_VSRAM_CPUM_OC,
+ MT6363_IRQ_VSRAM_CPUL_OC,
+ MT6363_IRQ_VSRAM_APU_OC,
+ MT6363_IRQ_VAUX18_OC,
+ MT6363_IRQ_VEMC_OC,
+ MT6363_IRQ_VUFS12_OC,
+ MT6363_IRQ_VUFS18_OC,
+ MT6363_IRQ_VIO18_OC,
+ MT6363_IRQ_VIO075_OC,
+ MT6363_IRQ_VA12_1_OC,
+ MT6363_IRQ_VA12_2_OC,
+ MT6363_IRQ_VA15_OC,
+ MT6363_IRQ_VM18_OC,
+ MT6363_IRQ_PWRKEY = 48,
+ MT6363_IRQ_HOMEKEY,
+ MT6363_IRQ_HOMEKEY_2,
+ MT6363_IRQ_PWRKEY_R,
+ MT6363_IRQ_HOMEKEY_R,
+ MT6363_IRQ_HOMEKEY_2_R,
+ MT6363_IRQ_NI_LVSYS_INT_FALLING,
+ MT6363_IRQ_NI_LVSYS_INT_RISING,
+ MT6363_IRQ_CHRDET_LEVEL,
+ MT6363_IRQ_CHRDET_EDGE,
+ MT6363_IRQ_RCS0 = 64,
+ MT6363_IRQ_SPMI_CMD_ALERT,
+ MT6363_IRQ_BM_PROTREG = 70,
+ MT6363_IRQ_BUCK_PROTREG = 72,
+ MT6363_IRQ_LDO_PROTREG,
+ MT6363_IRQ_PSC_PROTREG,
+ MT6363_IRQ_PLT_PROTREG,
+ MT6363_IRQ_HK_PROTREG,
+ MT6363_IRQ_TOP_PROTREG = 79,
+ MT6363_IRQ_BAT_H,
+ MT6363_IRQ_BAT_L,
+ MT6363_IRQ_BAT2_H,
+ MT6363_IRQ_BAT2_L,
+ MT6363_IRQ_BAT_TEMP_H,
+ MT6363_IRQ_BAT_TEMP_L,
+ MT6363_IRQ_THR_H,
+ MT6363_IRQ_THR_L,
+ MT6363_IRQ_AUXADC_IMP,
+ MT6363_IRQ_NAG_C_DLTV,
+ MT6363_IRQ_FG_BAT_H = 88,
+ MT6363_IRQ_FG_BAT_L,
+ MT6363_IRQ_FG_CUR_H,
+ MT6363_IRQ_FG_CUR_L,
+ MT6363_IRQ_FG_ZCV,
+ MT6363_IRQ_FG_N_CHARGE_L = 95,
+ MT6363_IRQ_FG_IAVG_H,
+ MT6363_IRQ_FG_IAVG_L,
+ MT6363_IRQ_FG_DISCHARGE = 99,
+ MT6363_IRQ_FG_CHARGE,
+ MT6363_IRQ_BATON_LV = 104,
+ MT6363_IRQ_BATON_BAT_IN = 106,
+ MT6363_IRQ_BATON_BAT_OUT,
+ MT6363_IRQ_NR = 108,
+};
+
+#define MT6363_IRQ_BUCK_BASE MT6363_IRQ_VS2_OC #define
+MT6363_IRQ_LDO_BASE MT6363_IRQ_VCN15_OC #define MT6363_IRQ_PSC_BASE
+MT6363_IRQ_PWRKEY #define MT6363_IRQ_MISC_BASE MT6363_IRQ_RCS0 #define
+MT6363_IRQ_HK_BASE MT6363_IRQ_BAT_H #define MT6363_IRQ_BM_BASE
+MT6363_IRQ_FG_BAT_H
+
+#define MT6363_IRQ_BUCK_BITS \
+ (MT6363_IRQ_VS3_OC - MT6363_IRQ_BUCK_BASE + 1) #define
+MT6363_IRQ_LDO_BITS \
+ (MT6363_IRQ_VM18_OC - MT6363_IRQ_LDO_BASE + 1) #define
+MT6363_IRQ_PSC_BITS \
+ (MT6363_IRQ_CHRDET_EDGE - MT6363_IRQ_PSC_BASE + 1) #define
+MT6363_IRQ_MISC_BITS \
+ (MT6363_IRQ_TOP_PROTREG - MT6363_IRQ_MISC_BASE + 1) #define
+MT6363_IRQ_HK_BITS \
+ (MT6363_IRQ_NAG_C_DLTV - MT6363_IRQ_HK_BASE + 1) #define
+MT6363_IRQ_BM_BITS \
+ (MT6363_IRQ_BATON_BAT_OUT - MT6363_IRQ_BM_BASE + 1)
+
+#define MT6363_TOP_GEN(sp) \
+{ \
+ .hwirq_base = MT6363_IRQ_##sp##_BASE, \
+ .num_int_regs = ((MT6363_IRQ_##sp##_BITS - 1) / MT6363_REG_WIDTH) + 1, \
+ .en_reg = MT6363_##sp##_TOP_INT_CON0, \
+ .en_reg_shift = 0x3, \
+ .sta_reg = MT6363_##sp##_TOP_INT_STATUS0, \
+ .sta_reg_shift = 0x1, \
+ .top_offset = MT6363_##sp##_TOP, \
+}
+
+#endif /* __MFD_MT6363_CORE_H__ */
new file mode 100644
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+
+#ifndef __MFD_MT6363_REGISTERS_H__
+#define __MFD_MT6363_REGISTERS_H__
+
+/* PMIC Registers */
+#define MT6363_TOPSTATUS (0x1e)
+#define MT6363_MISC_TOP_INT_CON0 (0x37)
+#define MT6363_MISC_TOP_INT_STATUS0 (0x43)
+#define MT6363_TOP_INT_STATUS1 (0x4e)
+#define MT6363_PSC_TOP_INT_CON0 (0x90f)
+#define MT6363_PSC_TOP_INT_STATUS0 (0x91b)
+#define MT6363_STRUP_CON11 (0xa0e)
+#define MT6363_STRUP_CON12 (0xa0f)
+#define MT6363_PCHR_VREF_ANA_CON1 (0xa89)
+#define MT6363_PCHR_VREF_ANA_CON2 (0xa8a)
+#define MT6363_BM_TOP_INT_CON0 (0xc24)
+#define MT6363_BM_TOP_INT_STATUS0 (0xc36)
+#define MT6363_HK_TOP_INT_CON0 (0xf92)
+#define MT6363_HK_TOP_INT_STATUS0 (0xf9e)
+#define MT6363_BUCK_TOP_INT_CON0 (0x1411)
+#define MT6363_BUCK_TOP_INT_STATUS0 (0x141d)
+#define MT6363_LDO_TOP_INT_CON0 (0x1b11)
+#define MT6363_LDO_TOP_INT_STATUS0 (0x1b29)
+
+/* voter */
+#define MT6363_BUCK_VS2_VOTER_CON0 (0x149a)
+#define MT6363_BUCK_VS2_VOTER_CON0_SET (0x149b)
+#define MT6363_BUCK_VS2_VOTER_CON0_CLR (0x149c)
+#define MT6363_BUCK_VS2_VOTER_CON1 (0x149d)
+#define MT6363_BUCK_VS2_VOTER_CON1_SET (0x149e)
+#define MT6363_BUCK_VS2_VOTER_CON1_CLR (0x149f)
+#define MT6363_BUCK_VS2_VOTER_CFG (0x14a0)
+#define MT6363_BUCK_VS1_VOTER_CON0 (0x189a)
+#define MT6363_BUCK_VS1_VOTER_CON0_SET (0x189b)
+#define MT6363_BUCK_VS1_VOTER_CON0_CLR (0x189c)
+#define MT6363_BUCK_VS1_VOTER_CON1 (0x189d)
+#define MT6363_BUCK_VS1_VOTER_CON1_SET (0x189e)
+#define MT6363_BUCK_VS1_VOTER_CON1_CLR (0x189f)
+#define MT6363_BUCK_VS1_VOTER_CFG (0x18a0)
+#define MT6363_BUCK_VS3_VOTER_CON0 (0x191a)
+#define MT6363_BUCK_VS3_VOTER_CON0_SET (0x191b)
+#define MT6363_BUCK_VS3_VOTER_CON0_CLR (0x191c)
+#define MT6363_BUCK_VS3_VOTER_CON1 (0x191d)
+#define MT6363_BUCK_VS3_VOTER_CON1_SET (0x191e)
+#define MT6363_BUCK_VS3_VOTER_CON1_CLR (0x191f)
+#define MT6363_BUCK_VS3_VOTER_CFG (0x1920)
+
+#define MT6363_CHRDET_DEB_ADDR MT6363_TOPSTATUS
+#define MT6363_CHRDET_DEB_MASK (0x1)
+#define MT6363_CHRDET_DEB_SHIFT (2)
+#define MT6363_RG_VBB_UVLO_VTHL_ADDR MT6363_PCHR_VREF_ANA_CON1
+#define MT6363_RG_VBB_UVLO_VTHL_MASK (0xF)
+#define MT6363_RG_VBB_UVLO_VTHL_SHIFT (0)
+#define MT6363_RG_VSYS_UVLO_VTHL_ADDR MT6363_PCHR_VREF_ANA_CON2
+#define MT6363_RG_VSYS_UVLO_VTHL_MASK (0xF)
+#define MT6363_RG_VSYS_UVLO_VTHL_SHIFT (0)
+
+#define MT6363_AUXADC_ADC0_L (0x1088)
+#define MT6363_AUXADC_ADC3_L (0x108e)
+#define MT6363_AUXADC_ADC4_L (0x1090)
+#define MT6363_AUXADC_ADC11_L (0x109e)
+#define MT6363_AUXADC_ADC38_L (0x10c4)
+#define MT6363_AUXADC_ADC39_L (0x10c6)
+#define MT6363_AUXADC_ADC40_L (0x10c8)
+#define MT6363_AUXADC_ADC_CH12_L (0x10d2)
+#define MT6363_AUXADC_ADC_CH14_L (0x10d8)
+#define MT6363_AUXADC_ADC42_L (0x10dc)
+#define MT6363_AUXADC_RQST0 (0x1108)
+#define MT6363_AUXADC_RQST1 (0x1109)
+#define MT6363_AUXADC_RQST3 (0x110c)
+#define MT6363_SDMADC_RQST0 (0x110e)
+#define MT6363_SDMADC_CON0 (0x11c4)
+#define MT6363_AUXADC_IMP0 (0x1208)
+#define MT6363_AUXADC_IMP1 (0x1209)
+
+/* voter */
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_ADDR \
+ MT6363_BUCK_VS2_VOTER_CON0
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_MASK (0xFF)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_SHIFT (0)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_SET_ADDR \
+ MT6363_BUCK_VS2_VOTER_CON0_SET
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_SET_MASK (0xFF)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_SET_SHIFT (0)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_CLR_ADDR \
+ MT6363_BUCK_VS2_VOTER_CON0_CLR
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_CLR_MASK (0xFF)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_LO_CLR_SHIFT (0)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_ADDR \
+ MT6363_BUCK_VS2_VOTER_CON1
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_MASK (0xF)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_SHIFT (0)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_SET_ADDR \
+ MT6363_BUCK_VS2_VOTER_CON1_SET
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_SET_MASK (0xF)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_SET_SHIFT (0)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_CLR_ADDR \
+ MT6363_BUCK_VS2_VOTER_CON1_CLR
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_CLR_MASK (0xF)
+#define MT6363_RG_BUCK_VS2_VOTER_EN_HI_CLR_SHIFT (0)
+#define MT6363_RG_BUCK_VS2_VOTER_VOSEL_ADDR \
+ MT6363_BUCK_VS2_VOTER_CFG
+#define MT6363_RG_BUCK_VS2_VOTER_VOSEL_MASK (0xFF)
+#define MT6363_RG_BUCK_VS2_VOTER_VOSEL_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_ADDR \
+ MT6363_BUCK_VS1_VOTER_CON0
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_MASK (0xFF)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_SET_ADDR \
+ MT6363_BUCK_VS1_VOTER_CON0_SET
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_SET_MASK (0xFF)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_SET_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_CLR_ADDR \
+ MT6363_BUCK_VS1_VOTER_CON0_CLR
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_CLR_MASK (0xFF)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_LO_CLR_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_ADDR \
+ MT6363_BUCK_VS1_VOTER_CON1
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_MASK (0xF)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_SET_ADDR \
+ MT6363_BUCK_VS1_VOTER_CON1_SET
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_SET_MASK (0xF)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_SET_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_CLR_ADDR \
+ MT6363_BUCK_VS1_VOTER_CON1_CLR
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_CLR_MASK (0xF)
+#define MT6363_RG_BUCK_VS1_VOTER_EN_HI_CLR_SHIFT (0)
+#define MT6363_RG_BUCK_VS1_VOTER_VOSEL_ADDR \
+ MT6363_BUCK_VS1_VOTER_CFG
+#define MT6363_RG_BUCK_VS1_VOTER_VOSEL_MASK (0xFF)
+#define MT6363_RG_BUCK_VS1_VOTER_VOSEL_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_ADDR \
+ MT6363_BUCK_VS3_VOTER_CON0
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_MASK (0xFF)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_SET_ADDR \
+ MT6363_BUCK_VS3_VOTER_CON0_SET
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_SET_MASK (0xFF)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_SET_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_CLR_ADDR \
+ MT6363_BUCK_VS3_VOTER_CON0_CLR
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_CLR_MASK (0xFF)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_LO_CLR_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_ADDR \
+ MT6363_BUCK_VS3_VOTER_CON1
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_MASK (0xF)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_SET_ADDR \
+ MT6363_BUCK_VS3_VOTER_CON1_SET
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_SET_MASK (0xF)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_SET_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_CLR_ADDR \
+ MT6363_BUCK_VS3_VOTER_CON1_CLR
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_CLR_MASK (0xF)
+#define MT6363_RG_BUCK_VS3_VOTER_EN_HI_CLR_SHIFT (0)
+#define MT6363_RG_BUCK_VS3_VOTER_VOSEL_ADDR \
+ MT6363_BUCK_VS3_VOTER_CFG
+#define MT6363_RG_BUCK_VS3_VOTER_VOSEL_MASK (0xFF)
+#define MT6363_RG_BUCK_VS3_VOTER_VOSEL_SHIFT (0)
+
+#endif /* __MFD_MT6363_REGISTERS_H__ */
+
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MFD_MT6373_CORE_H__
+#define __MFD_MT6373_CORE_H__
+
+#define MT6373_REG_WIDTH 8
+
+enum mt6373_irq_top_status_shift {
+ MT6373_BUCK_TOP = 0,
+ MT6373_LDO_TOP,
+ MT6373_PSC_TOP,
+ MT6373_MISC_TOP,
+ MT6373_HK_TOP,
+ MT6373_SCK_TOP,
+ MT6373_BM_TOP,
+ MT6373_AUD_TOP,
+};
+
+enum mt6373_irq_numbers {
+ MT6373_IRQ_VBUCK0_OC,
+ MT6373_IRQ_VBUCK1_OC,
+ MT6373_IRQ_VBUCK2_OC,
+ MT6373_IRQ_VBUCK3_OC,
+ MT6373_IRQ_VBUCK4_OC,
+ MT6373_IRQ_VBUCK5_OC,
+ MT6373_IRQ_VBUCK6_OC,
+ MT6373_IRQ_VBUCK7_OC,
+ MT6373_IRQ_VBUCK8_OC,
+ MT6373_IRQ_VBUCK9_OC,
+ MT6373_IRQ_VAUD18_OC = 16,
+ MT6373_IRQ_VUSB_OC,
+ MT6373_IRQ_VAUX18_OC,
+ MT6373_IRQ_VRF13_AIF_OC,
+ MT6373_IRQ_VRF18_AIF_OC,
+ MT6373_IRQ_VRFIO18_AIF_OC,
+ MT6373_IRQ_VCN33_1_OC,
+ MT6373_IRQ_VCN33_2_OC,
+ MT6373_IRQ_VCN33_3_OC,
+ MT6373_IRQ_VCN18IO_OC,
+ MT6373_IRQ_VRF09_AIF_OC,
+ MT6373_IRQ_VRF12_AIF_OC,
+ MT6373_IRQ_VANT18_OC,
+ MT6373_IRQ_VSRAM_DIGRF_AIF_OC,
+ MT6373_IRQ_VMDDR_OC,
+ MT6373_IRQ_VEFUSE_OC,
+ MT6373_IRQ_VMCH_OC,
+ MT6373_IRQ_VMC_OC,
+ MT6373_IRQ_VIBR_OC,
+ MT6373_IRQ_VIO28_OC,
+ MT6373_IRQ_VFP_OC,
+ MT6373_IRQ_VTP_OC,
+ MT6373_IRQ_VSIM1_OC,
+ MT6373_IRQ_VSIM2_OC,
+ MT6373_IRQ_RCS0 = 56,
+ MT6373_IRQ_SPMI_CMD_ALERT,
+ MT6373_IRQ_BM_PROTREG = 62,
+ MT6373_IRQ_VRC_PROTREG,
+ MT6373_IRQ_BUCK_PROTREG = 64,
+ MT6373_IRQ_LDO_PROTREG,
+ MT6373_IRQ_PSC_PROTREG,
+ MT6373_IRQ_PLT_PROTREG,
+ MT6373_IRQ_HK_PROTREG,
+ MT6373_IRQ_SCK_PROTREG,
+ MT6373_IRQ_XPP_PROTREG,
+ MT6373_IRQ_TOP_PROTREG,
+ MT6373_IRQ_NR = 72,
+};
+
+#define MT6373_IRQ_BUCK_BASE MT6373_IRQ_VBUCK0_OC #define
+MT6373_IRQ_LDO_BASE MT6373_IRQ_VAUD18_OC #define MT6373_IRQ_MISC_BASE
+MT6373_IRQ_RCS0
+
+#define MT6373_IRQ_BUCK_BITS \
+ (MT6373_IRQ_VBUCK9_OC - MT6373_IRQ_BUCK_BASE + 1) #define
+MT6373_IRQ_LDO_BITS \
+ (MT6373_IRQ_VSIM2_OC - MT6373_IRQ_LDO_BASE + 1) #define
+MT6373_IRQ_MISC_BITS \
+ (MT6373_IRQ_TOP_PROTREG - MT6373_IRQ_MISC_BASE + 1)
+
+#define MT6373_TOP_GEN(sp) \
+{ \
+ .hwirq_base = MT6373_IRQ_##sp##_BASE, \
+ .num_int_regs = ((MT6373_IRQ_##sp##_BITS - 1) / MT6373_REG_WIDTH) + 1, \
+ .en_reg = MT6373_##sp##_TOP_INT_CON0, \
+ .en_reg_shift = 0x3, \
+ .sta_reg = MT6373_##sp##_TOP_INT_STATUS0, \
+ .sta_reg_shift = 0x1, \
+ .top_offset = MT6373_##sp##_TOP, \
+}
+
+#endif /* __MFD_MT6373_CORE_H__ */
new file mode 100644
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+
+#ifndef __MFD_MT6373_REGISTERS_H__
+#define __MFD_MT6373_REGISTERS_H__
+
+/* PMIC Registers */
+#define MT6373_TOPSTATUS 0x1e
+#define MT6373_MISC_TOP_INT_CON0 0x3c
+#define MT6373_MISC_TOP_INT_CON1 0x3f
+#define MT6373_MISC_TOP_INT_STATUS0 0x48
+#define MT6373_MISC_TOP_INT_STATUS1 0x49
+#define MT6373_TOP_INT_MASK_CON0 0x4c
+#define MT6373_TOP_INT_MASK_CON0_SET 0x4d
+#define MT6373_TOP_INT_MASK_CON0_CLR 0x4e
+#define MT6373_TOP_INT_MASK_CON1 0x4f
+#define MT6373_TOP_INT_MASK_CON1_SET 0x50
+#define MT6373_TOP_INT_MASK_CON1_CLR 0x51
+#define MT6373_TOP_INT_STATUS0 0x52
+#define MT6373_TOP_INT_STATUS1 0x53
+#define MT6373_HK_TOP_INT_CON0 0xf92
+#define MT6373_HK_TOP_INT_CON1 0xf95
+#define MT6373_HK_TOP_INT_STATUS0 0xf9e
+#define MT6373_HK_TOP_INT_STATUS1 0xf9f
+#define MT6373_AUXADC_ADC4_L 0x1090
+#define MT6373_AUXADC_ADC38_L 0x10c4
+#define MT6373_AUXADC_ADC39_L 0x10c6
+#define MT6373_AUXADC_ADC40_L 0x10c8
+#define MT6373_AUXADC_ADC_CH12_L 0x10d2
+#define MT6373_AUXADC_ADC_CH12_H 0x10d3
+#define MT6373_AUXADC_RQST0 0x1108
+#define MT6373_AUXADC_RQST1 0x1109
+#define MT6373_AUXADC_RQST3 0x110c
+#define MT6373_SDMADC_RQST0 0x110e
+#define MT6373_SDMADC_CON0 0x11c4
+#define MT6373_BUCK_TOP_INT_CON0 0x1411
+#define MT6373_BUCK_TOP_INT_CON1 0x1414
+#define MT6373_BUCK_TOP_INT_STATUS0 0x141d
+#define MT6373_BUCK_TOP_INT_STATUS1 0x141e
+#define MT6373_LDO_TOP_INT_CON0 0x1b10
+#define MT6373_LDO_TOP_INT_CON1 0x1b13
+#define MT6373_LDO_TOP_INT_CON2 0x1b16
+#define MT6373_LDO_TOP_INT_STATUS0 0x1b22
+#define MT6373_LDO_TOP_INT_STATUS1 0x1b23
+#define MT6373_LDO_TOP_INT_STATUS2 0x1b24
+#define MT6373_LDO_VMCH_CON0 0x1cb1
+#define MT6373_LDO_VMCH_CON1 0x1cb2
+#define MT6373_LDO_VMCH_CON2 0x1cb3
+
+#endif /* __MFD_MT6373_REGISTERS_H__ */