brintos

brintos / linux-shallow public Read only

0
0
Text · 10.3 KiB · c2939e7 Raw
404 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2014 MediaTek Inc.4 * Author: Flora Fu, MediaTek5 */6 7#include <linux/interrupt.h>8#include <linux/ioport.h>9#include <linux/irqdomain.h>10#include <linux/module.h>11#include <linux/of.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/mt6331/core.h>17#include <linux/mfd/mt6357/core.h>18#include <linux/mfd/mt6358/core.h>19#include <linux/mfd/mt6359/core.h>20#include <linux/mfd/mt6397/core.h>21#include <linux/mfd/mt6323/registers.h>22#include <linux/mfd/mt6331/registers.h>23#include <linux/mfd/mt6357/registers.h>24#include <linux/mfd/mt6358/registers.h>25#include <linux/mfd/mt6359/registers.h>26#include <linux/mfd/mt6397/registers.h>27 28#define MT6323_RTC_BASE		0x800029#define MT6323_RTC_SIZE		0x4030 31#define MT6357_RTC_BASE		0x058832#define MT6357_RTC_SIZE		0x3c33 34#define MT6331_RTC_BASE		0x400035#define MT6331_RTC_SIZE		0x4036 37#define MT6358_RTC_BASE		0x058838#define MT6358_RTC_SIZE		0x3c39 40#define MT6397_RTC_BASE		0xe00041#define MT6397_RTC_SIZE		0x3e42 43#define MT6323_PWRC_BASE	0x800044#define MT6323_PWRC_SIZE	0x4045 46static const struct resource mt6323_rtc_resources[] = {47	DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),48	DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),49};50 51static const struct resource mt6357_rtc_resources[] = {52	DEFINE_RES_MEM(MT6357_RTC_BASE, MT6357_RTC_SIZE),53	DEFINE_RES_IRQ(MT6357_IRQ_RTC),54};55 56static const struct resource mt6331_rtc_resources[] = {57	DEFINE_RES_MEM(MT6331_RTC_BASE, MT6331_RTC_SIZE),58	DEFINE_RES_IRQ(MT6331_IRQ_STATUS_RTC),59};60 61static const struct resource mt6358_rtc_resources[] = {62	DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),63	DEFINE_RES_IRQ(MT6358_IRQ_RTC),64};65 66static const struct resource mt6397_rtc_resources[] = {67	DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),68	DEFINE_RES_IRQ(MT6397_IRQ_RTC),69};70 71static const struct resource mt6358_keys_resources[] = {72	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY, "powerkey"),73	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY, "homekey"),74	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY_R, "powerkey_r"),75	DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY_R, "homekey_r"),76};77 78static const struct resource mt6359_keys_resources[] = {79	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY, "powerkey"),80	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY, "homekey"),81	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_PWRKEY_R, "powerkey_r"),82	DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY_R, "homekey_r"),83};84 85static const struct resource mt6323_keys_resources[] = {86	DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY, "powerkey"),87	DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"),88};89 90static const struct resource mt6357_keys_resources[] = {91	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY, "powerkey"),92	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY, "homekey"),93	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_PWRKEY_R, "powerkey_r"),94	DEFINE_RES_IRQ_NAMED(MT6357_IRQ_HOMEKEY_R, "homekey_r"),95};96 97static const struct resource mt6331_keys_resources[] = {98	DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_PWRKEY, "powerkey"),99	DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_HOMEKEY, "homekey"),100};101 102static const struct resource mt6397_keys_resources[] = {103	DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"),104	DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"),105};106 107static const struct resource mt6323_pwrc_resources[] = {108	DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),109};110 111static const struct mfd_cell mt6323_devs[] = {112	{113		.name = "mt6323-rtc",114		.num_resources = ARRAY_SIZE(mt6323_rtc_resources),115		.resources = mt6323_rtc_resources,116		.of_compatible = "mediatek,mt6323-rtc",117	}, {118		.name = "mt6323-regulator",119		.of_compatible = "mediatek,mt6323-regulator"120	}, {121		.name = "mt6323-led",122		.of_compatible = "mediatek,mt6323-led"123	}, {124		.name = "mtk-pmic-keys",125		.num_resources = ARRAY_SIZE(mt6323_keys_resources),126		.resources = mt6323_keys_resources,127		.of_compatible = "mediatek,mt6323-keys"128	}, {129		.name = "mt6323-pwrc",130		.num_resources = ARRAY_SIZE(mt6323_pwrc_resources),131		.resources = mt6323_pwrc_resources,132		.of_compatible = "mediatek,mt6323-pwrc"133	},134};135 136static const struct mfd_cell mt6357_devs[] = {137	{138		.name = "mt6359-auxadc",139		.of_compatible = "mediatek,mt6357-auxadc"140	}, {141		.name = "mt6357-regulator",142	}, {143		.name = "mt6357-rtc",144		.num_resources = ARRAY_SIZE(mt6357_rtc_resources),145		.resources = mt6357_rtc_resources,146		.of_compatible = "mediatek,mt6357-rtc",147	}, {148		.name = "mt6357-sound",149		.of_compatible = "mediatek,mt6357-sound"150	}, {151		.name = "mtk-pmic-keys",152		.num_resources = ARRAY_SIZE(mt6357_keys_resources),153		.resources = mt6357_keys_resources,154		.of_compatible = "mediatek,mt6357-keys"155	},156};157 158/* MT6331 is always used in combination with MT6332 */159static const struct mfd_cell mt6331_mt6332_devs[] = {160	{161		.name = "mt6331-rtc",162		.num_resources = ARRAY_SIZE(mt6331_rtc_resources),163		.resources = mt6331_rtc_resources,164		.of_compatible = "mediatek,mt6331-rtc",165	}, {166		.name = "mt6331-regulator",167		.of_compatible = "mediatek,mt6331-regulator"168	}, {169		.name = "mt6332-regulator",170		.of_compatible = "mediatek,mt6332-regulator"171	}, {172		.name = "mtk-pmic-keys",173		.num_resources = ARRAY_SIZE(mt6331_keys_resources),174		.resources = mt6331_keys_resources,175		.of_compatible = "mediatek,mt6331-keys"176	},177};178 179static const struct mfd_cell mt6358_devs[] = {180	{181		.name = "mt6359-auxadc",182		.of_compatible = "mediatek,mt6358-auxadc"183	}, {184		.name = "mt6358-regulator",185		.of_compatible = "mediatek,mt6358-regulator"186	}, {187		.name = "mt6358-rtc",188		.num_resources = ARRAY_SIZE(mt6358_rtc_resources),189		.resources = mt6358_rtc_resources,190		.of_compatible = "mediatek,mt6358-rtc",191	}, {192		.name = "mt6358-sound",193		.of_compatible = "mediatek,mt6358-sound"194	}, {195		.name = "mt6358-keys",196		.num_resources = ARRAY_SIZE(mt6358_keys_resources),197		.resources = mt6358_keys_resources,198		.of_compatible = "mediatek,mt6358-keys"199	},200};201 202static const struct mfd_cell mt6359_devs[] = {203	{204		.name = "mt6359-auxadc",205		.of_compatible = "mediatek,mt6359-auxadc"206	},207	{ .name = "mt6359-regulator", },208	{209		.name = "mt6359-rtc",210		.num_resources = ARRAY_SIZE(mt6358_rtc_resources),211		.resources = mt6358_rtc_resources,212		.of_compatible = "mediatek,mt6358-rtc",213	},214	{ .name = "mt6359-sound", },215	{216		.name = "mtk-pmic-keys",217		.num_resources = ARRAY_SIZE(mt6359_keys_resources),218		.resources = mt6359_keys_resources,219		.of_compatible = "mediatek,mt6359-keys"220	},221};222 223static const struct mfd_cell mt6397_devs[] = {224	{225		.name = "mt6397-rtc",226		.num_resources = ARRAY_SIZE(mt6397_rtc_resources),227		.resources = mt6397_rtc_resources,228		.of_compatible = "mediatek,mt6397-rtc",229	}, {230		.name = "mt6397-regulator",231		.of_compatible = "mediatek,mt6397-regulator",232	}, {233		.name = "mt6397-codec",234		.of_compatible = "mediatek,mt6397-codec",235	}, {236		.name = "mt6397-clk",237		.of_compatible = "mediatek,mt6397-clk",238	}, {239		.name = "mt6397-pinctrl",240		.of_compatible = "mediatek,mt6397-pinctrl",241	}, {242		.name = "mtk-pmic-keys",243		.num_resources = ARRAY_SIZE(mt6397_keys_resources),244		.resources = mt6397_keys_resources,245		.of_compatible = "mediatek,mt6397-keys"246	}247};248 249struct chip_data {250	u32 cid_addr;251	u32 cid_shift;252	const struct mfd_cell *cells;253	int cell_size;254	int (*irq_init)(struct mt6397_chip *chip);255};256 257static const struct chip_data mt6323_core = {258	.cid_addr = MT6323_CID,259	.cid_shift = 0,260	.cells = mt6323_devs,261	.cell_size = ARRAY_SIZE(mt6323_devs),262	.irq_init = mt6397_irq_init,263};264 265static const struct chip_data mt6357_core = {266	.cid_addr = MT6357_SWCID,267	.cid_shift = 8,268	.cells = mt6357_devs,269	.cell_size = ARRAY_SIZE(mt6357_devs),270	.irq_init = mt6358_irq_init,271};272 273static const struct chip_data mt6331_mt6332_core = {274	.cid_addr = MT6331_HWCID,275	.cid_shift = 0,276	.cells = mt6331_mt6332_devs,277	.cell_size = ARRAY_SIZE(mt6331_mt6332_devs),278	.irq_init = mt6397_irq_init,279};280 281static const struct chip_data mt6358_core = {282	.cid_addr = MT6358_SWCID,283	.cid_shift = 8,284	.cells = mt6358_devs,285	.cell_size = ARRAY_SIZE(mt6358_devs),286	.irq_init = mt6358_irq_init,287};288 289static const struct chip_data mt6359_core = {290	.cid_addr = MT6359_SWCID,291	.cid_shift = 8,292	.cells = mt6359_devs,293	.cell_size = ARRAY_SIZE(mt6359_devs),294	.irq_init = mt6358_irq_init,295};296 297static const struct chip_data mt6397_core = {298	.cid_addr = MT6397_CID,299	.cid_shift = 0,300	.cells = mt6397_devs,301	.cell_size = ARRAY_SIZE(mt6397_devs),302	.irq_init = mt6397_irq_init,303};304 305static int mt6397_probe(struct platform_device *pdev)306{307	int ret;308	unsigned int id = 0;309	struct mt6397_chip *pmic;310	const struct chip_data *pmic_core;311 312	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);313	if (!pmic)314		return -ENOMEM;315 316	pmic->dev = &pdev->dev;317 318	/*319	 * mt6397 MFD is child device of soc pmic wrapper.320	 * Regmap is set from its parent.321	 */322	pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);323	if (!pmic->regmap)324		return -ENODEV;325 326	pmic_core = of_device_get_match_data(&pdev->dev);327	if (!pmic_core)328		return -ENODEV;329 330	ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);331	if (ret) {332		dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);333		return ret;334	}335 336	pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;337 338	platform_set_drvdata(pdev, pmic);339 340	pmic->irq = platform_get_irq(pdev, 0);341	if (pmic->irq <= 0)342		return pmic->irq;343 344	ret = pmic_core->irq_init(pmic);345	if (ret)346		return ret;347 348	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,349				   pmic_core->cells, pmic_core->cell_size,350				   NULL, 0, pmic->irq_domain);351	if (ret) {352		irq_domain_remove(pmic->irq_domain);353		dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);354	}355 356	return ret;357}358 359static const struct of_device_id mt6397_of_match[] = {360	{361		.compatible = "mediatek,mt6323",362		.data = &mt6323_core,363	}, {364		.compatible = "mediatek,mt6331",365		.data = &mt6331_mt6332_core,366	}, {367		.compatible = "mediatek,mt6357",368		.data = &mt6357_core,369	}, {370		.compatible = "mediatek,mt6358",371		.data = &mt6358_core,372	}, {373		.compatible = "mediatek,mt6359",374		.data = &mt6359_core,375	}, {376		.compatible = "mediatek,mt6397",377		.data = &mt6397_core,378	}, {379		/* sentinel */380	}381};382MODULE_DEVICE_TABLE(of, mt6397_of_match);383 384static const struct platform_device_id mt6397_id[] = {385	{ "mt6397", 0 },386	{ },387};388MODULE_DEVICE_TABLE(platform, mt6397_id);389 390static struct platform_driver mt6397_driver = {391	.probe = mt6397_probe,392	.driver = {393		.name = "mt6397",394		.of_match_table = mt6397_of_match,395	},396	.id_table = mt6397_id,397};398 399module_platform_driver(mt6397_driver);400 401MODULE_AUTHOR("Flora Fu, MediaTek");402MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");403MODULE_LICENSE("GPL");404