xref: /openbmc/linux/drivers/mfd/mt6397-core.c (revision dc0c386e)
11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
26df8dd5cSFlora Fu /*
36df8dd5cSFlora Fu  * Copyright (c) 2014 MediaTek Inc.
46df8dd5cSFlora Fu  * Author: Flora Fu, MediaTek
56df8dd5cSFlora Fu  */
66df8dd5cSFlora Fu 
76df8dd5cSFlora Fu #include <linux/interrupt.h>
87c3f7cd5SJosef Friedl #include <linux/ioport.h>
9*dc0c386eSRob Herring #include <linux/irqdomain.h>
106df8dd5cSFlora Fu #include <linux/module.h>
11*dc0c386eSRob Herring #include <linux/of.h>
12*dc0c386eSRob Herring #include <linux/platform_device.h>
136df8dd5cSFlora Fu #include <linux/regmap.h>
146df8dd5cSFlora Fu #include <linux/mfd/core.h>
1544760cf3SJohn Crispin #include <linux/mfd/mt6323/core.h>
16d9cd0bc6SAngeloGioacchino Del Regno #include <linux/mfd/mt6331/core.h>
17de58cee8SFabien Parent #include <linux/mfd/mt6357/core.h>
182b91c28fSHsin-Hsiung Wang #include <linux/mfd/mt6358/core.h>
19e545b8f3SHsin-Hsiung Wang #include <linux/mfd/mt6359/core.h>
20708cb5ccSHsin-Hsiung Wang #include <linux/mfd/mt6397/core.h>
2144760cf3SJohn Crispin #include <linux/mfd/mt6323/registers.h>
22d9cd0bc6SAngeloGioacchino Del Regno #include <linux/mfd/mt6331/registers.h>
23de58cee8SFabien Parent #include <linux/mfd/mt6357/registers.h>
242b91c28fSHsin-Hsiung Wang #include <linux/mfd/mt6358/registers.h>
25e545b8f3SHsin-Hsiung Wang #include <linux/mfd/mt6359/registers.h>
26708cb5ccSHsin-Hsiung Wang #include <linux/mfd/mt6397/registers.h>
276df8dd5cSFlora Fu 
288391c6cbSJosef Friedl #define MT6323_RTC_BASE		0x8000
298391c6cbSJosef Friedl #define MT6323_RTC_SIZE		0x40
308391c6cbSJosef Friedl 
31de58cee8SFabien Parent #define MT6357_RTC_BASE		0x0588
32de58cee8SFabien Parent #define MT6357_RTC_SIZE		0x3c
33de58cee8SFabien Parent 
34d9cd0bc6SAngeloGioacchino Del Regno #define MT6331_RTC_BASE		0x4000
35d9cd0bc6SAngeloGioacchino Del Regno #define MT6331_RTC_SIZE		0x40
36d9cd0bc6SAngeloGioacchino Del Regno 
372b91c28fSHsin-Hsiung Wang #define MT6358_RTC_BASE		0x0588
382b91c28fSHsin-Hsiung Wang #define MT6358_RTC_SIZE		0x3c
392b91c28fSHsin-Hsiung Wang 
40a5d7ea09SEddie Huang #define MT6397_RTC_BASE		0xe000
41a5d7ea09SEddie Huang #define MT6397_RTC_SIZE		0x3e
42a5d7ea09SEddie Huang 
438391c6cbSJosef Friedl #define MT6323_PWRC_BASE	0x8000
448391c6cbSJosef Friedl #define MT6323_PWRC_SIZE	0x40
458391c6cbSJosef Friedl 
468391c6cbSJosef Friedl static const struct resource mt6323_rtc_resources[] = {
478391c6cbSJosef Friedl 	DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
488391c6cbSJosef Friedl 	DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
498391c6cbSJosef Friedl };
508391c6cbSJosef Friedl 
51de58cee8SFabien Parent static const struct resource mt6357_rtc_resources[] = {
52de58cee8SFabien Parent 	DEFINE_RES_MEM(MT6357_RTC_BASE, MT6357_RTC_SIZE),
53de58cee8SFabien Parent 	DEFINE_RES_IRQ(MT6357_IRQ_RTC),
54de58cee8SFabien Parent };
55de58cee8SFabien Parent 
56d9cd0bc6SAngeloGioacchino Del Regno static const struct resource mt6331_rtc_resources[] = {
57d9cd0bc6SAngeloGioacchino Del Regno 	DEFINE_RES_MEM(MT6331_RTC_BASE, MT6331_RTC_SIZE),
58d9cd0bc6SAngeloGioacchino Del Regno 	DEFINE_RES_IRQ(MT6331_IRQ_STATUS_RTC),
59d9cd0bc6SAngeloGioacchino Del Regno };
60d9cd0bc6SAngeloGioacchino Del Regno 
612b91c28fSHsin-Hsiung Wang static const struct resource mt6358_rtc_resources[] = {
622b91c28fSHsin-Hsiung Wang 	DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),
632b91c28fSHsin-Hsiung Wang 	DEFINE_RES_IRQ(MT6358_IRQ_RTC),
642b91c28fSHsin-Hsiung Wang };
652b91c28fSHsin-Hsiung Wang 
66a5d7ea09SEddie Huang static const struct resource mt6397_rtc_resources[] = {
677c3f7cd5SJosef Friedl 	DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
687c3f7cd5SJosef Friedl 	DEFINE_RES_IRQ(MT6397_IRQ_RTC),
69a5d7ea09SEddie Huang };
70a5d7ea09SEddie Huang 
7134b6677eSMattijs Korpershoek static const struct resource mt6358_keys_resources[] = {
7234b6677eSMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY, "powerkey"),
7334b6677eSMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY, "homekey"),
7434b6677eSMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY_R, "powerkey_r"),
7534b6677eSMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY_R, "homekey_r"),
7634b6677eSMattijs Korpershoek };
7734b6677eSMattijs Korpershoek 
784a901e30SFabien Parent static const struct resource mt6359_keys_resources[] = {
794a901e30SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY, "powerkey"),
804a901e30SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY, "homekey"),
814a901e30SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY_R, "powerkey_r"),
824a901e30SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY_R, "homekey_r"),
834a901e30SFabien Parent };
844a901e30SFabien Parent 
8555d1d154SChen Zhong static const struct resource mt6323_keys_resources[] = {
867addf7e7SMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY, "powerkey"),
877addf7e7SMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"),
8855d1d154SChen Zhong };
8955d1d154SChen Zhong 
90de58cee8SFabien Parent static const struct resource mt6357_keys_resources[] = {
91de58cee8SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY, "powerkey"),
92de58cee8SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY, "homekey"),
93de58cee8SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY_R, "powerkey_r"),
94de58cee8SFabien Parent 	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY_R, "homekey_r"),
95de58cee8SFabien Parent };
96de58cee8SFabien Parent 
97d9cd0bc6SAngeloGioacchino Del Regno static const struct resource mt6331_keys_resources[] = {
98d9cd0bc6SAngeloGioacchino Del Regno 	DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_PWRKEY, "powerkey"),
99d9cd0bc6SAngeloGioacchino Del Regno 	DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_HOMEKEY, "homekey"),
100d9cd0bc6SAngeloGioacchino Del Regno };
101d9cd0bc6SAngeloGioacchino Del Regno 
10255d1d154SChen Zhong static const struct resource mt6397_keys_resources[] = {
1037addf7e7SMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"),
1047addf7e7SMattijs Korpershoek 	DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"),
10555d1d154SChen Zhong };
10655d1d154SChen Zhong 
1078391c6cbSJosef Friedl static const struct resource mt6323_pwrc_resources[] = {
1088391c6cbSJosef Friedl 	DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
1098391c6cbSJosef Friedl };
1108391c6cbSJosef Friedl 
11144760cf3SJohn Crispin static const struct mfd_cell mt6323_devs[] = {
11244760cf3SJohn Crispin 	{
1138391c6cbSJosef Friedl 		.name = "mt6323-rtc",
1148391c6cbSJosef Friedl 		.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
1158391c6cbSJosef Friedl 		.resources = mt6323_rtc_resources,
1168391c6cbSJosef Friedl 		.of_compatible = "mediatek,mt6323-rtc",
1178391c6cbSJosef Friedl 	}, {
11844760cf3SJohn Crispin 		.name = "mt6323-regulator",
11944760cf3SJohn Crispin 		.of_compatible = "mediatek,mt6323-regulator"
120040fc9b1SSean Wang 	}, {
1211cb8af8dSSean Wang 		.name = "mt6323-led",
1221cb8af8dSSean Wang 		.of_compatible = "mediatek,mt6323-led"
12355d1d154SChen Zhong 	}, {
12455d1d154SChen Zhong 		.name = "mtk-pmic-keys",
12555d1d154SChen Zhong 		.num_resources = ARRAY_SIZE(mt6323_keys_resources),
12655d1d154SChen Zhong 		.resources = mt6323_keys_resources,
12755d1d154SChen Zhong 		.of_compatible = "mediatek,mt6323-keys"
1288391c6cbSJosef Friedl 	}, {
1298391c6cbSJosef Friedl 		.name = "mt6323-pwrc",
1308391c6cbSJosef Friedl 		.num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
1318391c6cbSJosef Friedl 		.resources = mt6323_pwrc_resources,
1328391c6cbSJosef Friedl 		.of_compatible = "mediatek,mt6323-pwrc"
1331cb8af8dSSean Wang 	},
13444760cf3SJohn Crispin };
13544760cf3SJohn Crispin 
136de58cee8SFabien Parent static const struct mfd_cell mt6357_devs[] = {
137de58cee8SFabien Parent 	{
138de58cee8SFabien Parent 		.name = "mt6357-regulator",
139de58cee8SFabien Parent 	}, {
140de58cee8SFabien Parent 		.name = "mt6357-rtc",
141de58cee8SFabien Parent 		.num_resources = ARRAY_SIZE(mt6357_rtc_resources),
142de58cee8SFabien Parent 		.resources = mt6357_rtc_resources,
143de58cee8SFabien Parent 		.of_compatible = "mediatek,mt6357-rtc",
144de58cee8SFabien Parent 	}, {
145de58cee8SFabien Parent 		.name = "mtk-pmic-keys",
146de58cee8SFabien Parent 		.num_resources = ARRAY_SIZE(mt6357_keys_resources),
147de58cee8SFabien Parent 		.resources = mt6357_keys_resources,
148de58cee8SFabien Parent 		.of_compatible = "mediatek,mt6357-keys"
149de58cee8SFabien Parent 	},
150de58cee8SFabien Parent };
151de58cee8SFabien Parent 
152d9cd0bc6SAngeloGioacchino Del Regno /* MT6331 is always used in combination with MT6332 */
153d9cd0bc6SAngeloGioacchino Del Regno static const struct mfd_cell mt6331_mt6332_devs[] = {
154d9cd0bc6SAngeloGioacchino Del Regno 	{
155d9cd0bc6SAngeloGioacchino Del Regno 		.name = "mt6331-rtc",
156d9cd0bc6SAngeloGioacchino Del Regno 		.num_resources = ARRAY_SIZE(mt6331_rtc_resources),
157d9cd0bc6SAngeloGioacchino Del Regno 		.resources = mt6331_rtc_resources,
158d9cd0bc6SAngeloGioacchino Del Regno 		.of_compatible = "mediatek,mt6331-rtc",
159d9cd0bc6SAngeloGioacchino Del Regno 	}, {
160d9cd0bc6SAngeloGioacchino Del Regno 		.name = "mt6331-regulator",
161d9cd0bc6SAngeloGioacchino Del Regno 		.of_compatible = "mediatek,mt6331-regulator"
162d9cd0bc6SAngeloGioacchino Del Regno 	}, {
163d9cd0bc6SAngeloGioacchino Del Regno 		.name = "mt6332-regulator",
164d9cd0bc6SAngeloGioacchino Del Regno 		.of_compatible = "mediatek,mt6332-regulator"
165d9cd0bc6SAngeloGioacchino Del Regno 	}, {
166d9cd0bc6SAngeloGioacchino Del Regno 		.name = "mtk-pmic-keys",
167d9cd0bc6SAngeloGioacchino Del Regno 		.num_resources = ARRAY_SIZE(mt6331_keys_resources),
168d9cd0bc6SAngeloGioacchino Del Regno 		.resources = mt6331_keys_resources,
169d9cd0bc6SAngeloGioacchino Del Regno 		.of_compatible = "mediatek,mt6331-keys"
170d9cd0bc6SAngeloGioacchino Del Regno 	},
171d9cd0bc6SAngeloGioacchino Del Regno };
172d9cd0bc6SAngeloGioacchino Del Regno 
1732b91c28fSHsin-Hsiung Wang static const struct mfd_cell mt6358_devs[] = {
1742b91c28fSHsin-Hsiung Wang 	{
1752b91c28fSHsin-Hsiung Wang 		.name = "mt6358-regulator",
1762b91c28fSHsin-Hsiung Wang 		.of_compatible = "mediatek,mt6358-regulator"
1772b91c28fSHsin-Hsiung Wang 	}, {
1782b91c28fSHsin-Hsiung Wang 		.name = "mt6358-rtc",
1792b91c28fSHsin-Hsiung Wang 		.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
1802b91c28fSHsin-Hsiung Wang 		.resources = mt6358_rtc_resources,
1812b91c28fSHsin-Hsiung Wang 		.of_compatible = "mediatek,mt6358-rtc",
1822b91c28fSHsin-Hsiung Wang 	}, {
1832b91c28fSHsin-Hsiung Wang 		.name = "mt6358-sound",
1842b91c28fSHsin-Hsiung Wang 		.of_compatible = "mediatek,mt6358-sound"
18534b6677eSMattijs Korpershoek 	}, {
18634b6677eSMattijs Korpershoek 		.name = "mt6358-keys",
18734b6677eSMattijs Korpershoek 		.num_resources = ARRAY_SIZE(mt6358_keys_resources),
18834b6677eSMattijs Korpershoek 		.resources = mt6358_keys_resources,
18934b6677eSMattijs Korpershoek 		.of_compatible = "mediatek,mt6358-keys"
1902b91c28fSHsin-Hsiung Wang 	},
1912b91c28fSHsin-Hsiung Wang };
1922b91c28fSHsin-Hsiung Wang 
193e545b8f3SHsin-Hsiung Wang static const struct mfd_cell mt6359_devs[] = {
194e545b8f3SHsin-Hsiung Wang 	{ .name = "mt6359-regulator", },
195e545b8f3SHsin-Hsiung Wang 	{
196e545b8f3SHsin-Hsiung Wang 		.name = "mt6359-rtc",
197e545b8f3SHsin-Hsiung Wang 		.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
198e545b8f3SHsin-Hsiung Wang 		.resources = mt6358_rtc_resources,
199e545b8f3SHsin-Hsiung Wang 		.of_compatible = "mediatek,mt6358-rtc",
200e545b8f3SHsin-Hsiung Wang 	},
201e545b8f3SHsin-Hsiung Wang 	{ .name = "mt6359-sound", },
2024a901e30SFabien Parent 	{
2034a901e30SFabien Parent 		.name = "mtk-pmic-keys",
2044a901e30SFabien Parent 		.num_resources = ARRAY_SIZE(mt6359_keys_resources),
2054a901e30SFabien Parent 		.resources = mt6359_keys_resources,
2064a901e30SFabien Parent 		.of_compatible = "mediatek,mt6359-keys"
2074a901e30SFabien Parent 	},
208e545b8f3SHsin-Hsiung Wang };
209e545b8f3SHsin-Hsiung Wang 
2106df8dd5cSFlora Fu static const struct mfd_cell mt6397_devs[] = {
2116df8dd5cSFlora Fu 	{
2126df8dd5cSFlora Fu 		.name = "mt6397-rtc",
213a5d7ea09SEddie Huang 		.num_resources = ARRAY_SIZE(mt6397_rtc_resources),
214a5d7ea09SEddie Huang 		.resources = mt6397_rtc_resources,
2156df8dd5cSFlora Fu 		.of_compatible = "mediatek,mt6397-rtc",
2166df8dd5cSFlora Fu 	}, {
2176df8dd5cSFlora Fu 		.name = "mt6397-regulator",
2186df8dd5cSFlora Fu 		.of_compatible = "mediatek,mt6397-regulator",
2196df8dd5cSFlora Fu 	}, {
2206df8dd5cSFlora Fu 		.name = "mt6397-codec",
2216df8dd5cSFlora Fu 		.of_compatible = "mediatek,mt6397-codec",
2226df8dd5cSFlora Fu 	}, {
2236df8dd5cSFlora Fu 		.name = "mt6397-clk",
2246df8dd5cSFlora Fu 		.of_compatible = "mediatek,mt6397-clk",
225cf55078bSHongzhou Yang 	}, {
226cf55078bSHongzhou Yang 		.name = "mt6397-pinctrl",
227cf55078bSHongzhou Yang 		.of_compatible = "mediatek,mt6397-pinctrl",
22855d1d154SChen Zhong 	}, {
22955d1d154SChen Zhong 		.name = "mtk-pmic-keys",
23055d1d154SChen Zhong 		.num_resources = ARRAY_SIZE(mt6397_keys_resources),
23155d1d154SChen Zhong 		.resources = mt6397_keys_resources,
23255d1d154SChen Zhong 		.of_compatible = "mediatek,mt6397-keys"
23355d1d154SChen Zhong 	}
2346df8dd5cSFlora Fu };
2356df8dd5cSFlora Fu 
23611c4f2beSFrank Wunderlich struct chip_data {
23711c4f2beSFrank Wunderlich 	u32 cid_addr;
23811c4f2beSFrank Wunderlich 	u32 cid_shift;
239d0c7347dSHsin-Hsiung Wang 	const struct mfd_cell *cells;
240d0c7347dSHsin-Hsiung Wang 	int cell_size;
241d0c7347dSHsin-Hsiung Wang 	int (*irq_init)(struct mt6397_chip *chip);
24211c4f2beSFrank Wunderlich };
24311c4f2beSFrank Wunderlich 
24411c4f2beSFrank Wunderlich static const struct chip_data mt6323_core = {
24511c4f2beSFrank Wunderlich 	.cid_addr = MT6323_CID,
24611c4f2beSFrank Wunderlich 	.cid_shift = 0,
247d0c7347dSHsin-Hsiung Wang 	.cells = mt6323_devs,
248d0c7347dSHsin-Hsiung Wang 	.cell_size = ARRAY_SIZE(mt6323_devs),
249d0c7347dSHsin-Hsiung Wang 	.irq_init = mt6397_irq_init,
25011c4f2beSFrank Wunderlich };
25111c4f2beSFrank Wunderlich 
252de58cee8SFabien Parent static const struct chip_data mt6357_core = {
253de58cee8SFabien Parent 	.cid_addr = MT6357_SWCID,
254de58cee8SFabien Parent 	.cid_shift = 8,
255de58cee8SFabien Parent 	.cells = mt6357_devs,
256de58cee8SFabien Parent 	.cell_size = ARRAY_SIZE(mt6357_devs),
257de58cee8SFabien Parent 	.irq_init = mt6358_irq_init,
258de58cee8SFabien Parent };
259de58cee8SFabien Parent 
260d9cd0bc6SAngeloGioacchino Del Regno static const struct chip_data mt6331_mt6332_core = {
261d9cd0bc6SAngeloGioacchino Del Regno 	.cid_addr = MT6331_HWCID,
262d9cd0bc6SAngeloGioacchino Del Regno 	.cid_shift = 0,
263d9cd0bc6SAngeloGioacchino Del Regno 	.cells = mt6331_mt6332_devs,
264d9cd0bc6SAngeloGioacchino Del Regno 	.cell_size = ARRAY_SIZE(mt6331_mt6332_devs),
265d9cd0bc6SAngeloGioacchino Del Regno 	.irq_init = mt6397_irq_init,
266d9cd0bc6SAngeloGioacchino Del Regno };
267d9cd0bc6SAngeloGioacchino Del Regno 
2682b91c28fSHsin-Hsiung Wang static const struct chip_data mt6358_core = {
2692b91c28fSHsin-Hsiung Wang 	.cid_addr = MT6358_SWCID,
2702b91c28fSHsin-Hsiung Wang 	.cid_shift = 8,
2712b91c28fSHsin-Hsiung Wang 	.cells = mt6358_devs,
2722b91c28fSHsin-Hsiung Wang 	.cell_size = ARRAY_SIZE(mt6358_devs),
2732b91c28fSHsin-Hsiung Wang 	.irq_init = mt6358_irq_init,
2742b91c28fSHsin-Hsiung Wang };
2752b91c28fSHsin-Hsiung Wang 
276e545b8f3SHsin-Hsiung Wang static const struct chip_data mt6359_core = {
277e545b8f3SHsin-Hsiung Wang 	.cid_addr = MT6359_SWCID,
278e545b8f3SHsin-Hsiung Wang 	.cid_shift = 8,
279e545b8f3SHsin-Hsiung Wang 	.cells = mt6359_devs,
280e545b8f3SHsin-Hsiung Wang 	.cell_size = ARRAY_SIZE(mt6359_devs),
281e545b8f3SHsin-Hsiung Wang 	.irq_init = mt6358_irq_init,
282e545b8f3SHsin-Hsiung Wang };
283e545b8f3SHsin-Hsiung Wang 
28411c4f2beSFrank Wunderlich static const struct chip_data mt6397_core = {
28511c4f2beSFrank Wunderlich 	.cid_addr = MT6397_CID,
28611c4f2beSFrank Wunderlich 	.cid_shift = 0,
287d0c7347dSHsin-Hsiung Wang 	.cells = mt6397_devs,
288d0c7347dSHsin-Hsiung Wang 	.cell_size = ARRAY_SIZE(mt6397_devs),
289d0c7347dSHsin-Hsiung Wang 	.irq_init = mt6397_irq_init,
29011c4f2beSFrank Wunderlich };
29111c4f2beSFrank Wunderlich 
mt6397_probe(struct platform_device * pdev)2926df8dd5cSFlora Fu static int mt6397_probe(struct platform_device *pdev)
2936df8dd5cSFlora Fu {
2946df8dd5cSFlora Fu 	int ret;
295d0c7347dSHsin-Hsiung Wang 	unsigned int id = 0;
2961d2c25edSJohn Crispin 	struct mt6397_chip *pmic;
29711c4f2beSFrank Wunderlich 	const struct chip_data *pmic_core;
2986df8dd5cSFlora Fu 
2991d2c25edSJohn Crispin 	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
3001d2c25edSJohn Crispin 	if (!pmic)
3016df8dd5cSFlora Fu 		return -ENOMEM;
3026df8dd5cSFlora Fu 
3031d2c25edSJohn Crispin 	pmic->dev = &pdev->dev;
304feec4799SJohn Crispin 
3056df8dd5cSFlora Fu 	/*
3066df8dd5cSFlora Fu 	 * mt6397 MFD is child device of soc pmic wrapper.
3076df8dd5cSFlora Fu 	 * Regmap is set from its parent.
3086df8dd5cSFlora Fu 	 */
3091d2c25edSJohn Crispin 	pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
3101d2c25edSJohn Crispin 	if (!pmic->regmap)
3116df8dd5cSFlora Fu 		return -ENODEV;
3126df8dd5cSFlora Fu 
31311c4f2beSFrank Wunderlich 	pmic_core = of_device_get_match_data(&pdev->dev);
31411c4f2beSFrank Wunderlich 	if (!pmic_core)
31511c4f2beSFrank Wunderlich 		return -ENODEV;
3166df8dd5cSFlora Fu 
31711c4f2beSFrank Wunderlich 	ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
3181d2c25edSJohn Crispin 	if (ret) {
31911c4f2beSFrank Wunderlich 		dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
3201387ff53SHenry Chen 		return ret;
3211d2c25edSJohn Crispin 	}
3221d2c25edSJohn Crispin 
32311c4f2beSFrank Wunderlich 	pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;
32411c4f2beSFrank Wunderlich 
32511c4f2beSFrank Wunderlich 	platform_set_drvdata(pdev, pmic);
32611c4f2beSFrank Wunderlich 
3271387ff53SHenry Chen 	pmic->irq = platform_get_irq(pdev, 0);
3281387ff53SHenry Chen 	if (pmic->irq <= 0)
3291387ff53SHenry Chen 		return pmic->irq;
3301387ff53SHenry Chen 
331d0c7347dSHsin-Hsiung Wang 	ret = pmic_core->irq_init(pmic);
3321387ff53SHenry Chen 	if (ret)
3331387ff53SHenry Chen 		return ret;
3341387ff53SHenry Chen 
335eb00f70dSFabien Parent 	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
336d0c7347dSHsin-Hsiung Wang 				   pmic_core->cells, pmic_core->cell_size,
337eb00f70dSFabien Parent 				   NULL, 0, pmic->irq_domain);
3381d2c25edSJohn Crispin 	if (ret) {
3391d2c25edSJohn Crispin 		irq_domain_remove(pmic->irq_domain);
3406df8dd5cSFlora Fu 		dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
3411d2c25edSJohn Crispin 	}
3426df8dd5cSFlora Fu 
3436df8dd5cSFlora Fu 	return ret;
3446df8dd5cSFlora Fu }
3456df8dd5cSFlora Fu 
3466df8dd5cSFlora Fu static const struct of_device_id mt6397_of_match[] = {
34711c4f2beSFrank Wunderlich 	{
34811c4f2beSFrank Wunderlich 		.compatible = "mediatek,mt6323",
34911c4f2beSFrank Wunderlich 		.data = &mt6323_core,
35011c4f2beSFrank Wunderlich 	}, {
351d9cd0bc6SAngeloGioacchino Del Regno 		.compatible = "mediatek,mt6331",
352d9cd0bc6SAngeloGioacchino Del Regno 		.data = &mt6331_mt6332_core,
353d9cd0bc6SAngeloGioacchino Del Regno 	}, {
354de58cee8SFabien Parent 		.compatible = "mediatek,mt6357",
355de58cee8SFabien Parent 		.data = &mt6357_core,
356de58cee8SFabien Parent 	}, {
3572b91c28fSHsin-Hsiung Wang 		.compatible = "mediatek,mt6358",
3582b91c28fSHsin-Hsiung Wang 		.data = &mt6358_core,
3592b91c28fSHsin-Hsiung Wang 	}, {
360e545b8f3SHsin-Hsiung Wang 		.compatible = "mediatek,mt6359",
361e545b8f3SHsin-Hsiung Wang 		.data = &mt6359_core,
362e545b8f3SHsin-Hsiung Wang 	}, {
36311c4f2beSFrank Wunderlich 		.compatible = "mediatek,mt6397",
36411c4f2beSFrank Wunderlich 		.data = &mt6397_core,
36511c4f2beSFrank Wunderlich 	}, {
36611c4f2beSFrank Wunderlich 		/* sentinel */
36711c4f2beSFrank Wunderlich 	}
3686df8dd5cSFlora Fu };
3696df8dd5cSFlora Fu MODULE_DEVICE_TABLE(of, mt6397_of_match);
3706df8dd5cSFlora Fu 
371e1d9a109SJavier Martinez Canillas static const struct platform_device_id mt6397_id[] = {
372e1d9a109SJavier Martinez Canillas 	{ "mt6397", 0 },
373e1d9a109SJavier Martinez Canillas 	{ },
374e1d9a109SJavier Martinez Canillas };
375e1d9a109SJavier Martinez Canillas MODULE_DEVICE_TABLE(platform, mt6397_id);
376e1d9a109SJavier Martinez Canillas 
3776df8dd5cSFlora Fu static struct platform_driver mt6397_driver = {
3786df8dd5cSFlora Fu 	.probe = mt6397_probe,
3796df8dd5cSFlora Fu 	.driver = {
3806df8dd5cSFlora Fu 		.name = "mt6397",
3814fae3010SKrzysztof Kozlowski 		.of_match_table = mt6397_of_match,
3826df8dd5cSFlora Fu 	},
383e1d9a109SJavier Martinez Canillas 	.id_table = mt6397_id,
3846df8dd5cSFlora Fu };
3856df8dd5cSFlora Fu 
3866df8dd5cSFlora Fu module_platform_driver(mt6397_driver);
3876df8dd5cSFlora Fu 
3886df8dd5cSFlora Fu MODULE_AUTHOR("Flora Fu, MediaTek");
3896df8dd5cSFlora Fu MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
3906df8dd5cSFlora Fu MODULE_LICENSE("GPL");
391