cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mt6397-core.c (7640B)


      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/mt6358/core.h>
     16#include <linux/mfd/mt6359/core.h>
     17#include <linux/mfd/mt6397/core.h>
     18#include <linux/mfd/mt6323/registers.h>
     19#include <linux/mfd/mt6358/registers.h>
     20#include <linux/mfd/mt6359/registers.h>
     21#include <linux/mfd/mt6397/registers.h>
     22
     23#define MT6323_RTC_BASE		0x8000
     24#define MT6323_RTC_SIZE		0x40
     25
     26#define MT6358_RTC_BASE		0x0588
     27#define MT6358_RTC_SIZE		0x3c
     28
     29#define MT6397_RTC_BASE		0xe000
     30#define MT6397_RTC_SIZE		0x3e
     31
     32#define MT6323_PWRC_BASE	0x8000
     33#define MT6323_PWRC_SIZE	0x40
     34
     35static const struct resource mt6323_rtc_resources[] = {
     36	DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
     37	DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
     38};
     39
     40static const struct resource mt6358_rtc_resources[] = {
     41	DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),
     42	DEFINE_RES_IRQ(MT6358_IRQ_RTC),
     43};
     44
     45static const struct resource mt6397_rtc_resources[] = {
     46	DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
     47	DEFINE_RES_IRQ(MT6397_IRQ_RTC),
     48};
     49
     50static const struct resource mt6358_keys_resources[] = {
     51	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY, "powerkey"),
     52	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY, "homekey"),
     53	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY_R, "powerkey_r"),
     54	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY_R, "homekey_r"),
     55};
     56
     57static const struct resource mt6359_keys_resources[] = {
     58	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY, "powerkey"),
     59	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY, "homekey"),
     60	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY_R, "powerkey_r"),
     61	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY_R, "homekey_r"),
     62};
     63
     64static const struct resource mt6323_keys_resources[] = {
     65	DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY, "powerkey"),
     66	DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"),
     67};
     68
     69static const struct resource mt6397_keys_resources[] = {
     70	DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"),
     71	DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"),
     72};
     73
     74static const struct resource mt6323_pwrc_resources[] = {
     75	DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
     76};
     77
     78static const struct mfd_cell mt6323_devs[] = {
     79	{
     80		.name = "mt6323-rtc",
     81		.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
     82		.resources = mt6323_rtc_resources,
     83		.of_compatible = "mediatek,mt6323-rtc",
     84	}, {
     85		.name = "mt6323-regulator",
     86		.of_compatible = "mediatek,mt6323-regulator"
     87	}, {
     88		.name = "mt6323-led",
     89		.of_compatible = "mediatek,mt6323-led"
     90	}, {
     91		.name = "mtk-pmic-keys",
     92		.num_resources = ARRAY_SIZE(mt6323_keys_resources),
     93		.resources = mt6323_keys_resources,
     94		.of_compatible = "mediatek,mt6323-keys"
     95	}, {
     96		.name = "mt6323-pwrc",
     97		.num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
     98		.resources = mt6323_pwrc_resources,
     99		.of_compatible = "mediatek,mt6323-pwrc"
    100	},
    101};
    102
    103static const struct mfd_cell mt6358_devs[] = {
    104	{
    105		.name = "mt6358-regulator",
    106		.of_compatible = "mediatek,mt6358-regulator"
    107	}, {
    108		.name = "mt6358-rtc",
    109		.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
    110		.resources = mt6358_rtc_resources,
    111		.of_compatible = "mediatek,mt6358-rtc",
    112	}, {
    113		.name = "mt6358-sound",
    114		.of_compatible = "mediatek,mt6358-sound"
    115	}, {
    116		.name = "mt6358-keys",
    117		.num_resources = ARRAY_SIZE(mt6358_keys_resources),
    118		.resources = mt6358_keys_resources,
    119		.of_compatible = "mediatek,mt6358-keys"
    120	},
    121};
    122
    123static const struct mfd_cell mt6359_devs[] = {
    124	{ .name = "mt6359-regulator", },
    125	{
    126		.name = "mt6359-rtc",
    127		.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
    128		.resources = mt6358_rtc_resources,
    129		.of_compatible = "mediatek,mt6358-rtc",
    130	},
    131	{ .name = "mt6359-sound", },
    132	{
    133		.name = "mtk-pmic-keys",
    134		.num_resources = ARRAY_SIZE(mt6359_keys_resources),
    135		.resources = mt6359_keys_resources,
    136		.of_compatible = "mediatek,mt6359-keys"
    137	},
    138};
    139
    140static const struct mfd_cell mt6397_devs[] = {
    141	{
    142		.name = "mt6397-rtc",
    143		.num_resources = ARRAY_SIZE(mt6397_rtc_resources),
    144		.resources = mt6397_rtc_resources,
    145		.of_compatible = "mediatek,mt6397-rtc",
    146	}, {
    147		.name = "mt6397-regulator",
    148		.of_compatible = "mediatek,mt6397-regulator",
    149	}, {
    150		.name = "mt6397-codec",
    151		.of_compatible = "mediatek,mt6397-codec",
    152	}, {
    153		.name = "mt6397-clk",
    154		.of_compatible = "mediatek,mt6397-clk",
    155	}, {
    156		.name = "mt6397-pinctrl",
    157		.of_compatible = "mediatek,mt6397-pinctrl",
    158	}, {
    159		.name = "mtk-pmic-keys",
    160		.num_resources = ARRAY_SIZE(mt6397_keys_resources),
    161		.resources = mt6397_keys_resources,
    162		.of_compatible = "mediatek,mt6397-keys"
    163	}
    164};
    165
    166struct chip_data {
    167	u32 cid_addr;
    168	u32 cid_shift;
    169	const struct mfd_cell *cells;
    170	int cell_size;
    171	int (*irq_init)(struct mt6397_chip *chip);
    172};
    173
    174static const struct chip_data mt6323_core = {
    175	.cid_addr = MT6323_CID,
    176	.cid_shift = 0,
    177	.cells = mt6323_devs,
    178	.cell_size = ARRAY_SIZE(mt6323_devs),
    179	.irq_init = mt6397_irq_init,
    180};
    181
    182static const struct chip_data mt6358_core = {
    183	.cid_addr = MT6358_SWCID,
    184	.cid_shift = 8,
    185	.cells = mt6358_devs,
    186	.cell_size = ARRAY_SIZE(mt6358_devs),
    187	.irq_init = mt6358_irq_init,
    188};
    189
    190static const struct chip_data mt6359_core = {
    191	.cid_addr = MT6359_SWCID,
    192	.cid_shift = 8,
    193	.cells = mt6359_devs,
    194	.cell_size = ARRAY_SIZE(mt6359_devs),
    195	.irq_init = mt6358_irq_init,
    196};
    197
    198static const struct chip_data mt6397_core = {
    199	.cid_addr = MT6397_CID,
    200	.cid_shift = 0,
    201	.cells = mt6397_devs,
    202	.cell_size = ARRAY_SIZE(mt6397_devs),
    203	.irq_init = mt6397_irq_init,
    204};
    205
    206static int mt6397_probe(struct platform_device *pdev)
    207{
    208	int ret;
    209	unsigned int id = 0;
    210	struct mt6397_chip *pmic;
    211	const struct chip_data *pmic_core;
    212
    213	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
    214	if (!pmic)
    215		return -ENOMEM;
    216
    217	pmic->dev = &pdev->dev;
    218
    219	/*
    220	 * mt6397 MFD is child device of soc pmic wrapper.
    221	 * Regmap is set from its parent.
    222	 */
    223	pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
    224	if (!pmic->regmap)
    225		return -ENODEV;
    226
    227	pmic_core = of_device_get_match_data(&pdev->dev);
    228	if (!pmic_core)
    229		return -ENODEV;
    230
    231	ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
    232	if (ret) {
    233		dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
    234		return ret;
    235	}
    236
    237	pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;
    238
    239	platform_set_drvdata(pdev, pmic);
    240
    241	pmic->irq = platform_get_irq(pdev, 0);
    242	if (pmic->irq <= 0)
    243		return pmic->irq;
    244
    245	ret = pmic_core->irq_init(pmic);
    246	if (ret)
    247		return ret;
    248
    249	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
    250				   pmic_core->cells, pmic_core->cell_size,
    251				   NULL, 0, pmic->irq_domain);
    252	if (ret) {
    253		irq_domain_remove(pmic->irq_domain);
    254		dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
    255	}
    256
    257	return ret;
    258}
    259
    260static const struct of_device_id mt6397_of_match[] = {
    261	{
    262		.compatible = "mediatek,mt6323",
    263		.data = &mt6323_core,
    264	}, {
    265		.compatible = "mediatek,mt6358",
    266		.data = &mt6358_core,
    267	}, {
    268		.compatible = "mediatek,mt6359",
    269		.data = &mt6359_core,
    270	}, {
    271		.compatible = "mediatek,mt6397",
    272		.data = &mt6397_core,
    273	}, {
    274		/* sentinel */
    275	}
    276};
    277MODULE_DEVICE_TABLE(of, mt6397_of_match);
    278
    279static const struct platform_device_id mt6397_id[] = {
    280	{ "mt6397", 0 },
    281	{ },
    282};
    283MODULE_DEVICE_TABLE(platform, mt6397_id);
    284
    285static struct platform_driver mt6397_driver = {
    286	.probe = mt6397_probe,
    287	.driver = {
    288		.name = "mt6397",
    289		.of_match_table = mt6397_of_match,
    290	},
    291	.id_table = mt6397_id,
    292};
    293
    294module_platform_driver(mt6397_driver);
    295
    296MODULE_AUTHOR("Flora Fu, MediaTek");
    297MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
    298MODULE_LICENSE("GPL");