0001
0002
0003
0004
0005
0006
0007 #include <linux/interrupt.h>
0008 #include <linux/ioport.h>
0009 #include <linux/module.h>
0010 #include <linux/of_device.h>
0011 #include <linux/of_irq.h>
0012 #include <linux/regmap.h>
0013 #include <linux/mfd/core.h>
0014 #include <linux/mfd/mt6323/core.h>
0015 #include <linux/mfd/mt6331/core.h>
0016 #include <linux/mfd/mt6357/core.h>
0017 #include <linux/mfd/mt6358/core.h>
0018 #include <linux/mfd/mt6359/core.h>
0019 #include <linux/mfd/mt6397/core.h>
0020 #include <linux/mfd/mt6323/registers.h>
0021 #include <linux/mfd/mt6331/registers.h>
0022 #include <linux/mfd/mt6357/registers.h>
0023 #include <linux/mfd/mt6358/registers.h>
0024 #include <linux/mfd/mt6359/registers.h>
0025 #include <linux/mfd/mt6397/registers.h>
0026
0027 #define MT6323_RTC_BASE 0x8000
0028 #define MT6323_RTC_SIZE 0x40
0029
0030 #define MT6357_RTC_BASE 0x0588
0031 #define MT6357_RTC_SIZE 0x3c
0032
0033 #define MT6331_RTC_BASE 0x4000
0034 #define MT6331_RTC_SIZE 0x40
0035
0036 #define MT6358_RTC_BASE 0x0588
0037 #define MT6358_RTC_SIZE 0x3c
0038
0039 #define MT6397_RTC_BASE 0xe000
0040 #define MT6397_RTC_SIZE 0x3e
0041
0042 #define MT6323_PWRC_BASE 0x8000
0043 #define MT6323_PWRC_SIZE 0x40
0044
0045 static const struct resource mt6323_rtc_resources[] = {
0046 DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
0047 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
0048 };
0049
0050 static const struct resource mt6357_rtc_resources[] = {
0051 DEFINE_RES_MEM(MT6357_RTC_BASE, MT6357_RTC_SIZE),
0052 DEFINE_RES_IRQ(MT6357_IRQ_RTC),
0053 };
0054
0055 static const struct resource mt6331_rtc_resources[] = {
0056 DEFINE_RES_MEM(MT6331_RTC_BASE, MT6331_RTC_SIZE),
0057 DEFINE_RES_IRQ(MT6331_IRQ_STATUS_RTC),
0058 };
0059
0060 static const struct resource mt6358_rtc_resources[] = {
0061 DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),
0062 DEFINE_RES_IRQ(MT6358_IRQ_RTC),
0063 };
0064
0065 static const struct resource mt6397_rtc_resources[] = {
0066 DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
0067 DEFINE_RES_IRQ(MT6397_IRQ_RTC),
0068 };
0069
0070 static const struct resource mt6358_keys_resources[] = {
0071 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY, "powerkey"),
0072 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY, "homekey"),
0073 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY_R, "powerkey_r"),
0074 DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY_R, "homekey_r"),
0075 };
0076
0077 static const struct resource mt6359_keys_resources[] = {
0078 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY, "powerkey"),
0079 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY, "homekey"),
0080 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY_R, "powerkey_r"),
0081 DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY_R, "homekey_r"),
0082 };
0083
0084 static const struct resource mt6323_keys_resources[] = {
0085 DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY, "powerkey"),
0086 DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"),
0087 };
0088
0089 static const struct resource mt6357_keys_resources[] = {
0090 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY, "powerkey"),
0091 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY, "homekey"),
0092 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY_R, "powerkey_r"),
0093 DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY_R, "homekey_r"),
0094 };
0095
0096 static const struct resource mt6331_keys_resources[] = {
0097 DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_PWRKEY, "powerkey"),
0098 DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_HOMEKEY, "homekey"),
0099 };
0100
0101 static const struct resource mt6397_keys_resources[] = {
0102 DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"),
0103 DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"),
0104 };
0105
0106 static const struct resource mt6323_pwrc_resources[] = {
0107 DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
0108 };
0109
0110 static const struct mfd_cell mt6323_devs[] = {
0111 {
0112 .name = "mt6323-rtc",
0113 .num_resources = ARRAY_SIZE(mt6323_rtc_resources),
0114 .resources = mt6323_rtc_resources,
0115 .of_compatible = "mediatek,mt6323-rtc",
0116 }, {
0117 .name = "mt6323-regulator",
0118 .of_compatible = "mediatek,mt6323-regulator"
0119 }, {
0120 .name = "mt6323-led",
0121 .of_compatible = "mediatek,mt6323-led"
0122 }, {
0123 .name = "mtk-pmic-keys",
0124 .num_resources = ARRAY_SIZE(mt6323_keys_resources),
0125 .resources = mt6323_keys_resources,
0126 .of_compatible = "mediatek,mt6323-keys"
0127 }, {
0128 .name = "mt6323-pwrc",
0129 .num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
0130 .resources = mt6323_pwrc_resources,
0131 .of_compatible = "mediatek,mt6323-pwrc"
0132 },
0133 };
0134
0135 static const struct mfd_cell mt6357_devs[] = {
0136 {
0137 .name = "mt6357-regulator",
0138 }, {
0139 .name = "mt6357-rtc",
0140 .num_resources = ARRAY_SIZE(mt6357_rtc_resources),
0141 .resources = mt6357_rtc_resources,
0142 .of_compatible = "mediatek,mt6357-rtc",
0143 }, {
0144 .name = "mtk-pmic-keys",
0145 .num_resources = ARRAY_SIZE(mt6357_keys_resources),
0146 .resources = mt6357_keys_resources,
0147 .of_compatible = "mediatek,mt6357-keys"
0148 },
0149 };
0150
0151
0152 static const struct mfd_cell mt6331_mt6332_devs[] = {
0153 {
0154 .name = "mt6331-rtc",
0155 .num_resources = ARRAY_SIZE(mt6331_rtc_resources),
0156 .resources = mt6331_rtc_resources,
0157 .of_compatible = "mediatek,mt6331-rtc",
0158 }, {
0159 .name = "mt6331-regulator",
0160 .of_compatible = "mediatek,mt6331-regulator"
0161 }, {
0162 .name = "mt6332-regulator",
0163 .of_compatible = "mediatek,mt6332-regulator"
0164 }, {
0165 .name = "mtk-pmic-keys",
0166 .num_resources = ARRAY_SIZE(mt6331_keys_resources),
0167 .resources = mt6331_keys_resources,
0168 .of_compatible = "mediatek,mt6331-keys"
0169 },
0170 };
0171
0172 static const struct mfd_cell mt6358_devs[] = {
0173 {
0174 .name = "mt6358-regulator",
0175 .of_compatible = "mediatek,mt6358-regulator"
0176 }, {
0177 .name = "mt6358-rtc",
0178 .num_resources = ARRAY_SIZE(mt6358_rtc_resources),
0179 .resources = mt6358_rtc_resources,
0180 .of_compatible = "mediatek,mt6358-rtc",
0181 }, {
0182 .name = "mt6358-sound",
0183 .of_compatible = "mediatek,mt6358-sound"
0184 }, {
0185 .name = "mt6358-keys",
0186 .num_resources = ARRAY_SIZE(mt6358_keys_resources),
0187 .resources = mt6358_keys_resources,
0188 .of_compatible = "mediatek,mt6358-keys"
0189 },
0190 };
0191
0192 static const struct mfd_cell mt6359_devs[] = {
0193 { .name = "mt6359-regulator", },
0194 {
0195 .name = "mt6359-rtc",
0196 .num_resources = ARRAY_SIZE(mt6358_rtc_resources),
0197 .resources = mt6358_rtc_resources,
0198 .of_compatible = "mediatek,mt6358-rtc",
0199 },
0200 { .name = "mt6359-sound", },
0201 {
0202 .name = "mtk-pmic-keys",
0203 .num_resources = ARRAY_SIZE(mt6359_keys_resources),
0204 .resources = mt6359_keys_resources,
0205 .of_compatible = "mediatek,mt6359-keys"
0206 },
0207 };
0208
0209 static const struct mfd_cell mt6397_devs[] = {
0210 {
0211 .name = "mt6397-rtc",
0212 .num_resources = ARRAY_SIZE(mt6397_rtc_resources),
0213 .resources = mt6397_rtc_resources,
0214 .of_compatible = "mediatek,mt6397-rtc",
0215 }, {
0216 .name = "mt6397-regulator",
0217 .of_compatible = "mediatek,mt6397-regulator",
0218 }, {
0219 .name = "mt6397-codec",
0220 .of_compatible = "mediatek,mt6397-codec",
0221 }, {
0222 .name = "mt6397-clk",
0223 .of_compatible = "mediatek,mt6397-clk",
0224 }, {
0225 .name = "mt6397-pinctrl",
0226 .of_compatible = "mediatek,mt6397-pinctrl",
0227 }, {
0228 .name = "mtk-pmic-keys",
0229 .num_resources = ARRAY_SIZE(mt6397_keys_resources),
0230 .resources = mt6397_keys_resources,
0231 .of_compatible = "mediatek,mt6397-keys"
0232 }
0233 };
0234
0235 struct chip_data {
0236 u32 cid_addr;
0237 u32 cid_shift;
0238 const struct mfd_cell *cells;
0239 int cell_size;
0240 int (*irq_init)(struct mt6397_chip *chip);
0241 };
0242
0243 static const struct chip_data mt6323_core = {
0244 .cid_addr = MT6323_CID,
0245 .cid_shift = 0,
0246 .cells = mt6323_devs,
0247 .cell_size = ARRAY_SIZE(mt6323_devs),
0248 .irq_init = mt6397_irq_init,
0249 };
0250
0251 static const struct chip_data mt6357_core = {
0252 .cid_addr = MT6357_SWCID,
0253 .cid_shift = 8,
0254 .cells = mt6357_devs,
0255 .cell_size = ARRAY_SIZE(mt6357_devs),
0256 .irq_init = mt6358_irq_init,
0257 };
0258
0259 static const struct chip_data mt6331_mt6332_core = {
0260 .cid_addr = MT6331_HWCID,
0261 .cid_shift = 0,
0262 .cells = mt6331_mt6332_devs,
0263 .cell_size = ARRAY_SIZE(mt6331_mt6332_devs),
0264 .irq_init = mt6397_irq_init,
0265 };
0266
0267 static const struct chip_data mt6358_core = {
0268 .cid_addr = MT6358_SWCID,
0269 .cid_shift = 8,
0270 .cells = mt6358_devs,
0271 .cell_size = ARRAY_SIZE(mt6358_devs),
0272 .irq_init = mt6358_irq_init,
0273 };
0274
0275 static const struct chip_data mt6359_core = {
0276 .cid_addr = MT6359_SWCID,
0277 .cid_shift = 8,
0278 .cells = mt6359_devs,
0279 .cell_size = ARRAY_SIZE(mt6359_devs),
0280 .irq_init = mt6358_irq_init,
0281 };
0282
0283 static const struct chip_data mt6397_core = {
0284 .cid_addr = MT6397_CID,
0285 .cid_shift = 0,
0286 .cells = mt6397_devs,
0287 .cell_size = ARRAY_SIZE(mt6397_devs),
0288 .irq_init = mt6397_irq_init,
0289 };
0290
0291 static int mt6397_probe(struct platform_device *pdev)
0292 {
0293 int ret;
0294 unsigned int id = 0;
0295 struct mt6397_chip *pmic;
0296 const struct chip_data *pmic_core;
0297
0298 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
0299 if (!pmic)
0300 return -ENOMEM;
0301
0302 pmic->dev = &pdev->dev;
0303
0304
0305
0306
0307
0308 pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0309 if (!pmic->regmap)
0310 return -ENODEV;
0311
0312 pmic_core = of_device_get_match_data(&pdev->dev);
0313 if (!pmic_core)
0314 return -ENODEV;
0315
0316 ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
0317 if (ret) {
0318 dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
0319 return ret;
0320 }
0321
0322 pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;
0323
0324 platform_set_drvdata(pdev, pmic);
0325
0326 pmic->irq = platform_get_irq(pdev, 0);
0327 if (pmic->irq <= 0)
0328 return pmic->irq;
0329
0330 ret = pmic_core->irq_init(pmic);
0331 if (ret)
0332 return ret;
0333
0334 ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
0335 pmic_core->cells, pmic_core->cell_size,
0336 NULL, 0, pmic->irq_domain);
0337 if (ret) {
0338 irq_domain_remove(pmic->irq_domain);
0339 dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
0340 }
0341
0342 return ret;
0343 }
0344
0345 static const struct of_device_id mt6397_of_match[] = {
0346 {
0347 .compatible = "mediatek,mt6323",
0348 .data = &mt6323_core,
0349 }, {
0350 .compatible = "mediatek,mt6331",
0351 .data = &mt6331_mt6332_core,
0352 }, {
0353 .compatible = "mediatek,mt6357",
0354 .data = &mt6357_core,
0355 }, {
0356 .compatible = "mediatek,mt6358",
0357 .data = &mt6358_core,
0358 }, {
0359 .compatible = "mediatek,mt6359",
0360 .data = &mt6359_core,
0361 }, {
0362 .compatible = "mediatek,mt6397",
0363 .data = &mt6397_core,
0364 }, {
0365
0366 }
0367 };
0368 MODULE_DEVICE_TABLE(of, mt6397_of_match);
0369
0370 static const struct platform_device_id mt6397_id[] = {
0371 { "mt6397", 0 },
0372 { },
0373 };
0374 MODULE_DEVICE_TABLE(platform, mt6397_id);
0375
0376 static struct platform_driver mt6397_driver = {
0377 .probe = mt6397_probe,
0378 .driver = {
0379 .name = "mt6397",
0380 .of_match_table = mt6397_of_match,
0381 },
0382 .id_table = mt6397_id,
0383 };
0384
0385 module_platform_driver(mt6397_driver);
0386
0387 MODULE_AUTHOR("Flora Fu, MediaTek");
0388 MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
0389 MODULE_LICENSE("GPL");