root/drivers/mfd/mt6397-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mt6397_irq_suspend
  2. mt6397_irq_resume
  3. mt6397_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2014 MediaTek Inc.
   4  * Author: Flora Fu, MediaTek
   5  */
   6 
   7 #include <linux/interrupt.h>
   8 #include <linux/ioport.h>
   9 #include <linux/module.h>
  10 #include <linux/of_device.h>
  11 #include <linux/of_irq.h>
  12 #include <linux/regmap.h>
  13 #include <linux/mfd/core.h>
  14 #include <linux/mfd/mt6323/core.h>
  15 #include <linux/mfd/mt6397/core.h>
  16 #include <linux/mfd/mt6323/registers.h>
  17 #include <linux/mfd/mt6397/registers.h>
  18 
  19 #define MT6323_RTC_BASE         0x8000
  20 #define MT6323_RTC_SIZE         0x40
  21 
  22 #define MT6397_RTC_BASE         0xe000
  23 #define MT6397_RTC_SIZE         0x3e
  24 
  25 #define MT6323_PWRC_BASE        0x8000
  26 #define MT6323_PWRC_SIZE        0x40
  27 
  28 static const struct resource mt6323_rtc_resources[] = {
  29         DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
  30         DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
  31 };
  32 
  33 static const struct resource mt6397_rtc_resources[] = {
  34         DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
  35         DEFINE_RES_IRQ(MT6397_IRQ_RTC),
  36 };
  37 
  38 static const struct resource mt6323_keys_resources[] = {
  39         DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY),
  40         DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY),
  41 };
  42 
  43 static const struct resource mt6397_keys_resources[] = {
  44         DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY),
  45         DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
  46 };
  47 
  48 static const struct resource mt6323_pwrc_resources[] = {
  49         DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
  50 };
  51 
  52 static const struct mfd_cell mt6323_devs[] = {
  53         {
  54                 .name = "mt6323-rtc",
  55                 .num_resources = ARRAY_SIZE(mt6323_rtc_resources),
  56                 .resources = mt6323_rtc_resources,
  57                 .of_compatible = "mediatek,mt6323-rtc",
  58         }, {
  59                 .name = "mt6323-regulator",
  60                 .of_compatible = "mediatek,mt6323-regulator"
  61         }, {
  62                 .name = "mt6323-led",
  63                 .of_compatible = "mediatek,mt6323-led"
  64         }, {
  65                 .name = "mtk-pmic-keys",
  66                 .num_resources = ARRAY_SIZE(mt6323_keys_resources),
  67                 .resources = mt6323_keys_resources,
  68                 .of_compatible = "mediatek,mt6323-keys"
  69         }, {
  70                 .name = "mt6323-pwrc",
  71                 .num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
  72                 .resources = mt6323_pwrc_resources,
  73                 .of_compatible = "mediatek,mt6323-pwrc"
  74         },
  75 };
  76 
  77 static const struct mfd_cell mt6397_devs[] = {
  78         {
  79                 .name = "mt6397-rtc",
  80                 .num_resources = ARRAY_SIZE(mt6397_rtc_resources),
  81                 .resources = mt6397_rtc_resources,
  82                 .of_compatible = "mediatek,mt6397-rtc",
  83         }, {
  84                 .name = "mt6397-regulator",
  85                 .of_compatible = "mediatek,mt6397-regulator",
  86         }, {
  87                 .name = "mt6397-codec",
  88                 .of_compatible = "mediatek,mt6397-codec",
  89         }, {
  90                 .name = "mt6397-clk",
  91                 .of_compatible = "mediatek,mt6397-clk",
  92         }, {
  93                 .name = "mt6397-pinctrl",
  94                 .of_compatible = "mediatek,mt6397-pinctrl",
  95         }, {
  96                 .name = "mtk-pmic-keys",
  97                 .num_resources = ARRAY_SIZE(mt6397_keys_resources),
  98                 .resources = mt6397_keys_resources,
  99                 .of_compatible = "mediatek,mt6397-keys"
 100         }
 101 };
 102 
 103 #ifdef CONFIG_PM_SLEEP
 104 static int mt6397_irq_suspend(struct device *dev)
 105 {
 106         struct mt6397_chip *chip = dev_get_drvdata(dev);
 107 
 108         regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
 109         regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
 110 
 111         enable_irq_wake(chip->irq);
 112 
 113         return 0;
 114 }
 115 
 116 static int mt6397_irq_resume(struct device *dev)
 117 {
 118         struct mt6397_chip *chip = dev_get_drvdata(dev);
 119 
 120         regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
 121         regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
 122 
 123         disable_irq_wake(chip->irq);
 124 
 125         return 0;
 126 }
 127 #endif
 128 
 129 static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
 130                         mt6397_irq_resume);
 131 
 132 struct chip_data {
 133         u32 cid_addr;
 134         u32 cid_shift;
 135 };
 136 
 137 static const struct chip_data mt6323_core = {
 138         .cid_addr = MT6323_CID,
 139         .cid_shift = 0,
 140 };
 141 
 142 static const struct chip_data mt6397_core = {
 143         .cid_addr = MT6397_CID,
 144         .cid_shift = 0,
 145 };
 146 
 147 static int mt6397_probe(struct platform_device *pdev)
 148 {
 149         int ret;
 150         unsigned int id;
 151         struct mt6397_chip *pmic;
 152         const struct chip_data *pmic_core;
 153 
 154         pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
 155         if (!pmic)
 156                 return -ENOMEM;
 157 
 158         pmic->dev = &pdev->dev;
 159 
 160         /*
 161          * mt6397 MFD is child device of soc pmic wrapper.
 162          * Regmap is set from its parent.
 163          */
 164         pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
 165         if (!pmic->regmap)
 166                 return -ENODEV;
 167 
 168         pmic_core = of_device_get_match_data(&pdev->dev);
 169         if (!pmic_core)
 170                 return -ENODEV;
 171 
 172         ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
 173         if (ret) {
 174                 dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
 175                 return ret;
 176         }
 177 
 178         pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;
 179 
 180         platform_set_drvdata(pdev, pmic);
 181 
 182         pmic->irq = platform_get_irq(pdev, 0);
 183         if (pmic->irq <= 0)
 184                 return pmic->irq;
 185 
 186         ret = mt6397_irq_init(pmic);
 187         if (ret)
 188                 return ret;
 189 
 190         switch (pmic->chip_id) {
 191         case MT6323_CHIP_ID:
 192                 ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
 193                                            ARRAY_SIZE(mt6323_devs), NULL,
 194                                            0, pmic->irq_domain);
 195                 break;
 196 
 197         case MT6391_CHIP_ID:
 198         case MT6397_CHIP_ID:
 199                 ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
 200                                            ARRAY_SIZE(mt6397_devs), NULL,
 201                                            0, pmic->irq_domain);
 202                 break;
 203 
 204         default:
 205                 dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id);
 206                 return -ENODEV;
 207         }
 208 
 209         if (ret) {
 210                 irq_domain_remove(pmic->irq_domain);
 211                 dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
 212         }
 213 
 214         return ret;
 215 }
 216 
 217 static const struct of_device_id mt6397_of_match[] = {
 218         {
 219                 .compatible = "mediatek,mt6323",
 220                 .data = &mt6323_core,
 221         }, {
 222                 .compatible = "mediatek,mt6397",
 223                 .data = &mt6397_core,
 224         }, {
 225                 /* sentinel */
 226         }
 227 };
 228 MODULE_DEVICE_TABLE(of, mt6397_of_match);
 229 
 230 static const struct platform_device_id mt6397_id[] = {
 231         { "mt6397", 0 },
 232         { },
 233 };
 234 MODULE_DEVICE_TABLE(platform, mt6397_id);
 235 
 236 static struct platform_driver mt6397_driver = {
 237         .probe = mt6397_probe,
 238         .driver = {
 239                 .name = "mt6397",
 240                 .of_match_table = of_match_ptr(mt6397_of_match),
 241                 .pm = &mt6397_pm_ops,
 242         },
 243         .id_table = mt6397_id,
 244 };
 245 
 246 module_platform_driver(mt6397_driver);
 247 
 248 MODULE_AUTHOR("Flora Fu, MediaTek");
 249 MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
 250 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */