1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014 MediaTek Inc.
4 * Author: Flora Fu, MediaTek
7 #include <linux/interrupt.h>
8 #include <linux/ioport.h>
9 #include <linux/irqdomain.h>
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14 #include <linux/mfd/core.h>
15 #include <linux/mfd/mt6323/core.h>
16 #include <linux/mfd/mt6328/core.h>
17 #include <linux/mfd/mt6331/core.h>
18 #include <linux/mfd/mt6357/core.h>
19 #include <linux/mfd/mt6358/core.h>
20 #include <linux/mfd/mt6359/core.h>
21 #include <linux/mfd/mt6397/core.h>
22 #include <linux/mfd/mt6323/registers.h>
23 #include <linux/mfd/mt6328/registers.h>
24 #include <linux/mfd/mt6331/registers.h>
25 #include <linux/mfd/mt6357/registers.h>
26 #include <linux/mfd/mt6358/registers.h>
27 #include <linux/mfd/mt6359/registers.h>
28 #include <linux/mfd/mt6397/registers.h>
30 #define MT6323_RTC_BASE 0x8000
31 #define MT6323_RTC_SIZE 0x40
33 #define MT6357_RTC_BASE 0x0588
34 #define MT6357_RTC_SIZE 0x3c
36 #define MT6331_RTC_BASE 0x4000
37 #define MT6331_RTC_SIZE 0x40
39 #define MT6358_RTC_BASE 0x0588
40 #define MT6358_RTC_SIZE 0x3c
42 #define MT6397_RTC_BASE 0xe000
43 #define MT6397_RTC_SIZE 0x3e
45 #define MT6323_PWRC_BASE 0x8000
46 #define MT6323_PWRC_SIZE 0x40
48 static const struct resource mt6323_rtc_resources
[] = {
49 DEFINE_RES_MEM(MT6323_RTC_BASE
, MT6323_RTC_SIZE
),
50 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC
),
53 static const struct resource mt6357_rtc_resources
[] = {
54 DEFINE_RES_MEM(MT6357_RTC_BASE
, MT6357_RTC_SIZE
),
55 DEFINE_RES_IRQ(MT6357_IRQ_RTC
),
58 static const struct resource mt6331_rtc_resources
[] = {
59 DEFINE_RES_MEM(MT6331_RTC_BASE
, MT6331_RTC_SIZE
),
60 DEFINE_RES_IRQ(MT6331_IRQ_STATUS_RTC
),
63 static const struct resource mt6358_rtc_resources
[] = {
64 DEFINE_RES_MEM(MT6358_RTC_BASE
, MT6358_RTC_SIZE
),
65 DEFINE_RES_IRQ(MT6358_IRQ_RTC
),
68 static const struct resource mt6397_rtc_resources
[] = {
69 DEFINE_RES_MEM(MT6397_RTC_BASE
, MT6397_RTC_SIZE
),
70 DEFINE_RES_IRQ(MT6397_IRQ_RTC
),
73 static const struct resource mt6358_keys_resources
[] = {
74 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY
, "powerkey"),
75 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY
, "homekey"),
76 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY_R
, "powerkey_r"),
77 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY_R
, "homekey_r"),
80 static const struct resource mt6359_keys_resources
[] = {
81 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY
, "powerkey"),
82 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY
, "homekey"),
83 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY_R
, "powerkey_r"),
84 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY_R
, "homekey_r"),
87 static const struct resource mt6323_keys_resources
[] = {
88 DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY
, "powerkey"),
89 DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY
, "homekey"),
92 static const struct resource mt6328_keys_resources
[] = {
93 DEFINE_RES_IRQ_NAMED(MT6328_IRQ_STATUS_PWRKEY
, "powerkey"),
94 DEFINE_RES_IRQ_NAMED(MT6328_IRQ_STATUS_HOMEKEY
, "homekey"),
95 DEFINE_RES_IRQ_NAMED(MT6328_IRQ_STATUS_PWRKEY_R
, "powerkey_r"),
96 DEFINE_RES_IRQ_NAMED(MT6328_IRQ_STATUS_HOMEKEY_R
, "homekey_r"),
99 static const struct resource mt6357_keys_resources
[] = {
100 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY
, "powerkey"),
101 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY
, "homekey"),
102 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY_R
, "powerkey_r"),
103 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY_R
, "homekey_r"),
106 static const struct resource mt6331_keys_resources
[] = {
107 DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_PWRKEY
, "powerkey"),
108 DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_HOMEKEY
, "homekey"),
111 static const struct resource mt6397_keys_resources
[] = {
112 DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY
, "powerkey"),
113 DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY
, "homekey"),
116 static const struct resource mt6323_pwrc_resources
[] = {
117 DEFINE_RES_MEM(MT6323_PWRC_BASE
, MT6323_PWRC_SIZE
),
120 static const struct mfd_cell mt6323_devs
[] = {
122 .name
= "mt6323-rtc",
123 .num_resources
= ARRAY_SIZE(mt6323_rtc_resources
),
124 .resources
= mt6323_rtc_resources
,
125 .of_compatible
= "mediatek,mt6323-rtc",
127 .name
= "mt6323-regulator",
128 .of_compatible
= "mediatek,mt6323-regulator"
130 .name
= "mt6323-led",
131 .of_compatible
= "mediatek,mt6323-led"
133 .name
= "mtk-pmic-keys",
134 .num_resources
= ARRAY_SIZE(mt6323_keys_resources
),
135 .resources
= mt6323_keys_resources
,
136 .of_compatible
= "mediatek,mt6323-keys"
138 .name
= "mt6323-pwrc",
139 .num_resources
= ARRAY_SIZE(mt6323_pwrc_resources
),
140 .resources
= mt6323_pwrc_resources
,
141 .of_compatible
= "mediatek,mt6323-pwrc"
145 static const struct mfd_cell mt6328_devs
[] = {
147 .name
= "mt6328-regulator",
148 .of_compatible
= "mediatek,mt6328-regulator"
150 .name
= "mtk-pmic-keys",
151 .num_resources
= ARRAY_SIZE(mt6328_keys_resources
),
152 .resources
= mt6328_keys_resources
,
153 .of_compatible
= "mediatek,mt6328-keys"
157 static const struct mfd_cell mt6357_devs
[] = {
159 .name
= "mt6359-auxadc",
160 .of_compatible
= "mediatek,mt6357-auxadc"
162 .name
= "mt6357-regulator",
164 .name
= "mt6357-rtc",
165 .num_resources
= ARRAY_SIZE(mt6357_rtc_resources
),
166 .resources
= mt6357_rtc_resources
,
167 .of_compatible
= "mediatek,mt6357-rtc",
169 .name
= "mt6357-sound",
170 .of_compatible
= "mediatek,mt6357-sound"
172 .name
= "mtk-pmic-keys",
173 .num_resources
= ARRAY_SIZE(mt6357_keys_resources
),
174 .resources
= mt6357_keys_resources
,
175 .of_compatible
= "mediatek,mt6357-keys"
179 /* MT6331 is always used in combination with MT6332 */
180 static const struct mfd_cell mt6331_mt6332_devs
[] = {
182 .name
= "mt6331-rtc",
183 .num_resources
= ARRAY_SIZE(mt6331_rtc_resources
),
184 .resources
= mt6331_rtc_resources
,
185 .of_compatible
= "mediatek,mt6331-rtc",
187 .name
= "mt6331-regulator",
188 .of_compatible
= "mediatek,mt6331-regulator"
190 .name
= "mt6332-regulator",
191 .of_compatible
= "mediatek,mt6332-regulator"
193 .name
= "mtk-pmic-keys",
194 .num_resources
= ARRAY_SIZE(mt6331_keys_resources
),
195 .resources
= mt6331_keys_resources
,
196 .of_compatible
= "mediatek,mt6331-keys"
200 static const struct mfd_cell mt6358_devs
[] = {
202 .name
= "mt6359-auxadc",
203 .of_compatible
= "mediatek,mt6358-auxadc"
205 .name
= "mt6358-regulator",
206 .of_compatible
= "mediatek,mt6358-regulator"
208 .name
= "mt6358-rtc",
209 .num_resources
= ARRAY_SIZE(mt6358_rtc_resources
),
210 .resources
= mt6358_rtc_resources
,
211 .of_compatible
= "mediatek,mt6358-rtc",
213 .name
= "mt6358-sound",
214 .of_compatible
= "mediatek,mt6358-sound"
216 .name
= "mt6358-keys",
217 .num_resources
= ARRAY_SIZE(mt6358_keys_resources
),
218 .resources
= mt6358_keys_resources
,
219 .of_compatible
= "mediatek,mt6358-keys"
223 static const struct mfd_cell mt6359_devs
[] = {
225 .name
= "mt6359-auxadc",
226 .of_compatible
= "mediatek,mt6359-auxadc"
228 { .name
= "mt6359-regulator", },
230 .name
= "mt6359-rtc",
231 .num_resources
= ARRAY_SIZE(mt6358_rtc_resources
),
232 .resources
= mt6358_rtc_resources
,
233 .of_compatible
= "mediatek,mt6358-rtc",
235 { .name
= "mt6359-sound", },
237 .name
= "mtk-pmic-keys",
238 .num_resources
= ARRAY_SIZE(mt6359_keys_resources
),
239 .resources
= mt6359_keys_resources
,
240 .of_compatible
= "mediatek,mt6359-keys"
244 static const struct mfd_cell mt6397_devs
[] = {
246 .name
= "mt6397-rtc",
247 .num_resources
= ARRAY_SIZE(mt6397_rtc_resources
),
248 .resources
= mt6397_rtc_resources
,
249 .of_compatible
= "mediatek,mt6397-rtc",
251 .name
= "mt6397-regulator",
252 .of_compatible
= "mediatek,mt6397-regulator",
254 .name
= "mt6397-codec",
255 .of_compatible
= "mediatek,mt6397-codec",
257 .name
= "mt6397-clk",
258 .of_compatible
= "mediatek,mt6397-clk",
260 .name
= "mt6397-pinctrl",
261 .of_compatible
= "mediatek,mt6397-pinctrl",
263 .name
= "mtk-pmic-keys",
264 .num_resources
= ARRAY_SIZE(mt6397_keys_resources
),
265 .resources
= mt6397_keys_resources
,
266 .of_compatible
= "mediatek,mt6397-keys"
273 const struct mfd_cell
*cells
;
275 int (*irq_init
)(struct mt6397_chip
*chip
);
278 static const struct chip_data mt6323_core
= {
279 .cid_addr
= MT6323_CID
,
281 .cells
= mt6323_devs
,
282 .cell_size
= ARRAY_SIZE(mt6323_devs
),
283 .irq_init
= mt6397_irq_init
,
286 static const struct chip_data mt6328_core
= {
287 .cid_addr
= MT6328_HWCID
,
289 .cells
= mt6328_devs
,
290 .cell_size
= ARRAY_SIZE(mt6328_devs
),
291 .irq_init
= mt6397_irq_init
,
294 static const struct chip_data mt6357_core
= {
295 .cid_addr
= MT6357_SWCID
,
297 .cells
= mt6357_devs
,
298 .cell_size
= ARRAY_SIZE(mt6357_devs
),
299 .irq_init
= mt6358_irq_init
,
302 static const struct chip_data mt6331_mt6332_core
= {
303 .cid_addr
= MT6331_HWCID
,
305 .cells
= mt6331_mt6332_devs
,
306 .cell_size
= ARRAY_SIZE(mt6331_mt6332_devs
),
307 .irq_init
= mt6397_irq_init
,
310 static const struct chip_data mt6358_core
= {
311 .cid_addr
= MT6358_SWCID
,
313 .cells
= mt6358_devs
,
314 .cell_size
= ARRAY_SIZE(mt6358_devs
),
315 .irq_init
= mt6358_irq_init
,
318 static const struct chip_data mt6359_core
= {
319 .cid_addr
= MT6359_SWCID
,
321 .cells
= mt6359_devs
,
322 .cell_size
= ARRAY_SIZE(mt6359_devs
),
323 .irq_init
= mt6358_irq_init
,
326 static const struct chip_data mt6397_core
= {
327 .cid_addr
= MT6397_CID
,
329 .cells
= mt6397_devs
,
330 .cell_size
= ARRAY_SIZE(mt6397_devs
),
331 .irq_init
= mt6397_irq_init
,
334 static int mt6397_probe(struct platform_device
*pdev
)
338 struct mt6397_chip
*pmic
;
339 const struct chip_data
*pmic_core
;
341 pmic
= devm_kzalloc(&pdev
->dev
, sizeof(*pmic
), GFP_KERNEL
);
345 pmic
->dev
= &pdev
->dev
;
348 * mt6397 MFD is child device of soc pmic wrapper.
349 * Regmap is set from its parent.
351 pmic
->regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
355 pmic_core
= of_device_get_match_data(&pdev
->dev
);
359 ret
= regmap_read(pmic
->regmap
, pmic_core
->cid_addr
, &id
);
361 dev_err(&pdev
->dev
, "Failed to read chip id: %d\n", ret
);
365 pmic
->chip_id
= (id
>> pmic_core
->cid_shift
) & 0xff;
367 platform_set_drvdata(pdev
, pmic
);
369 pmic
->irq
= platform_get_irq(pdev
, 0);
373 ret
= pmic_core
->irq_init(pmic
);
377 ret
= devm_mfd_add_devices(&pdev
->dev
, PLATFORM_DEVID_NONE
,
378 pmic_core
->cells
, pmic_core
->cell_size
,
379 NULL
, 0, pmic
->irq_domain
);
381 irq_domain_remove(pmic
->irq_domain
);
382 dev_err(&pdev
->dev
, "failed to add child devices: %d\n", ret
);
388 static const struct of_device_id mt6397_of_match
[] = {
390 .compatible
= "mediatek,mt6323",
391 .data
= &mt6323_core
,
393 .compatible
= "mediatek,mt6328",
394 .data
= &mt6328_core
,
396 .compatible
= "mediatek,mt6331",
397 .data
= &mt6331_mt6332_core
,
399 .compatible
= "mediatek,mt6357",
400 .data
= &mt6357_core
,
402 .compatible
= "mediatek,mt6358",
403 .data
= &mt6358_core
,
405 .compatible
= "mediatek,mt6359",
406 .data
= &mt6359_core
,
408 .compatible
= "mediatek,mt6397",
409 .data
= &mt6397_core
,
414 MODULE_DEVICE_TABLE(of
, mt6397_of_match
);
416 static const struct platform_device_id mt6397_id
[] = {
420 MODULE_DEVICE_TABLE(platform
, mt6397_id
);
422 static struct platform_driver mt6397_driver
= {
423 .probe
= mt6397_probe
,
426 .of_match_table
= mt6397_of_match
,
428 .id_table
= mt6397_id
,
431 module_platform_driver(mt6397_driver
);
433 MODULE_AUTHOR("Flora Fu, MediaTek");
434 MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
435 MODULE_LICENSE("GPL");