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/module.h>
9 #include <linux/of_device.h>
10 #include <linux/of_irq.h>
11 #include <linux/regmap.h>
12 #include <linux/mfd/core.h>
13 #include <linux/mfd/mt6397/core.h>
14 #include <linux/mfd/mt6323/core.h>
15 #include <linux/mfd/mt6397/registers.h>
16 #include <linux/mfd/mt6323/registers.h>
18 #define MT6397_RTC_BASE 0xe000
19 #define MT6397_RTC_SIZE 0x3e
21 #define MT6323_CID_CODE 0x23
22 #define MT6391_CID_CODE 0x91
23 #define MT6397_CID_CODE 0x97
25 static const struct resource mt6397_rtc_resources[] = {
27 .start = MT6397_RTC_BASE,
28 .end = MT6397_RTC_BASE + MT6397_RTC_SIZE,
29 .flags = IORESOURCE_MEM,
32 .start = MT6397_IRQ_RTC,
33 .end = MT6397_IRQ_RTC,
34 .flags = IORESOURCE_IRQ,
38 static const struct resource mt6323_keys_resources[] = {
39 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY),
40 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY),
43 static const struct resource mt6397_keys_resources[] = {
44 DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY),
45 DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
48 static const struct mfd_cell mt6323_devs[] = {
50 .name = "mt6323-regulator",
51 .of_compatible = "mediatek,mt6323-regulator"
54 .of_compatible = "mediatek,mt6323-led"
56 .name = "mtk-pmic-keys",
57 .num_resources = ARRAY_SIZE(mt6323_keys_resources),
58 .resources = mt6323_keys_resources,
59 .of_compatible = "mediatek,mt6323-keys"
63 static const struct mfd_cell mt6397_devs[] = {
66 .num_resources = ARRAY_SIZE(mt6397_rtc_resources),
67 .resources = mt6397_rtc_resources,
68 .of_compatible = "mediatek,mt6397-rtc",
70 .name = "mt6397-regulator",
71 .of_compatible = "mediatek,mt6397-regulator",
73 .name = "mt6397-codec",
74 .of_compatible = "mediatek,mt6397-codec",
77 .of_compatible = "mediatek,mt6397-clk",
79 .name = "mt6397-pinctrl",
80 .of_compatible = "mediatek,mt6397-pinctrl",
82 .name = "mtk-pmic-keys",
83 .num_resources = ARRAY_SIZE(mt6397_keys_resources),
84 .resources = mt6397_keys_resources,
85 .of_compatible = "mediatek,mt6397-keys"
89 static void mt6397_irq_lock(struct irq_data *data)
91 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
93 mutex_lock(&mt6397->irqlock);
96 static void mt6397_irq_sync_unlock(struct irq_data *data)
98 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
100 regmap_write(mt6397->regmap, mt6397->int_con[0],
101 mt6397->irq_masks_cur[0]);
102 regmap_write(mt6397->regmap, mt6397->int_con[1],
103 mt6397->irq_masks_cur[1]);
105 mutex_unlock(&mt6397->irqlock);
108 static void mt6397_irq_disable(struct irq_data *data)
110 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
111 int shift = data->hwirq & 0xf;
112 int reg = data->hwirq >> 4;
114 mt6397->irq_masks_cur[reg] &= ~BIT(shift);
117 static void mt6397_irq_enable(struct irq_data *data)
119 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
120 int shift = data->hwirq & 0xf;
121 int reg = data->hwirq >> 4;
123 mt6397->irq_masks_cur[reg] |= BIT(shift);
126 #ifdef CONFIG_PM_SLEEP
127 static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
129 struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
130 int shift = irq_data->hwirq & 0xf;
131 int reg = irq_data->hwirq >> 4;
134 mt6397->wake_mask[reg] |= BIT(shift);
136 mt6397->wake_mask[reg] &= ~BIT(shift);
141 #define mt6397_irq_set_wake NULL
144 static struct irq_chip mt6397_irq_chip = {
145 .name = "mt6397-irq",
146 .irq_bus_lock = mt6397_irq_lock,
147 .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
148 .irq_enable = mt6397_irq_enable,
149 .irq_disable = mt6397_irq_disable,
150 .irq_set_wake = mt6397_irq_set_wake,
153 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
159 ret = regmap_read(mt6397->regmap, reg, &status);
161 dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
165 for (i = 0; i < 16; i++) {
166 if (status & BIT(i)) {
167 irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
169 handle_nested_irq(irq);
173 regmap_write(mt6397->regmap, reg, status);
176 static irqreturn_t mt6397_irq_thread(int irq, void *data)
178 struct mt6397_chip *mt6397 = data;
180 mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
181 mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
186 static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
189 struct mt6397_chip *mt6397 = d->host_data;
191 irq_set_chip_data(irq, mt6397);
192 irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
193 irq_set_nested_thread(irq, 1);
194 irq_set_noprobe(irq);
199 static const struct irq_domain_ops mt6397_irq_domain_ops = {
200 .map = mt6397_irq_domain_map,
203 static int mt6397_irq_init(struct mt6397_chip *mt6397)
207 mutex_init(&mt6397->irqlock);
209 /* Mask all interrupt sources */
210 regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
211 regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
213 mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
214 MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
215 if (!mt6397->irq_domain) {
216 dev_err(mt6397->dev, "could not create irq domain\n");
220 ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
221 mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
223 dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
231 #ifdef CONFIG_PM_SLEEP
232 static int mt6397_irq_suspend(struct device *dev)
234 struct mt6397_chip *chip = dev_get_drvdata(dev);
236 regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
237 regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
239 enable_irq_wake(chip->irq);
244 static int mt6397_irq_resume(struct device *dev)
246 struct mt6397_chip *chip = dev_get_drvdata(dev);
248 regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
249 regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
251 disable_irq_wake(chip->irq);
257 static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
260 static int mt6397_probe(struct platform_device *pdev)
264 struct mt6397_chip *pmic;
266 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
270 pmic->dev = &pdev->dev;
273 * mt6397 MFD is child device of soc pmic wrapper.
274 * Regmap is set from its parent.
276 pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
280 platform_set_drvdata(pdev, pmic);
282 ret = regmap_read(pmic->regmap, MT6397_CID, &id);
284 dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
288 pmic->irq = platform_get_irq(pdev, 0);
293 case MT6323_CID_CODE:
294 pmic->int_con[0] = MT6323_INT_CON0;
295 pmic->int_con[1] = MT6323_INT_CON1;
296 pmic->int_status[0] = MT6323_INT_STATUS0;
297 pmic->int_status[1] = MT6323_INT_STATUS1;
298 ret = mt6397_irq_init(pmic);
302 ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
303 ARRAY_SIZE(mt6323_devs), NULL,
304 0, pmic->irq_domain);
307 case MT6397_CID_CODE:
308 case MT6391_CID_CODE:
309 pmic->int_con[0] = MT6397_INT_CON0;
310 pmic->int_con[1] = MT6397_INT_CON1;
311 pmic->int_status[0] = MT6397_INT_STATUS0;
312 pmic->int_status[1] = MT6397_INT_STATUS1;
313 ret = mt6397_irq_init(pmic);
317 ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
318 ARRAY_SIZE(mt6397_devs), NULL,
319 0, pmic->irq_domain);
323 dev_err(&pdev->dev, "unsupported chip: %d\n", id);
328 irq_domain_remove(pmic->irq_domain);
329 dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
335 static const struct of_device_id mt6397_of_match[] = {
336 { .compatible = "mediatek,mt6397" },
337 { .compatible = "mediatek,mt6323" },
340 MODULE_DEVICE_TABLE(of, mt6397_of_match);
342 static const struct platform_device_id mt6397_id[] = {
346 MODULE_DEVICE_TABLE(platform, mt6397_id);
348 static struct platform_driver mt6397_driver = {
349 .probe = mt6397_probe,
352 .of_match_table = of_match_ptr(mt6397_of_match),
353 .pm = &mt6397_pm_ops,
355 .id_table = mt6397_id,
358 module_platform_driver(mt6397_driver);
360 MODULE_AUTHOR("Flora Fu, MediaTek");
361 MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
362 MODULE_LICENSE("GPL");