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

mt6360-regulator.c (14652B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2//
      3// Copyright (C) 2020 MediaTek Inc.
      4//
      5// Author: Gene Chen <gene_chen@richtek.com>
      6
      7#include <linux/init.h>
      8#include <linux/kernel.h>
      9#include <linux/module.h>
     10#include <linux/of.h>
     11#include <linux/platform_device.h>
     12#include <linux/regmap.h>
     13#include <linux/regulator/driver.h>
     14#include <linux/regulator/machine.h>
     15
     16#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
     17
     18enum {
     19	MT6360_REGULATOR_BUCK1 = 0,
     20	MT6360_REGULATOR_BUCK2,
     21	MT6360_REGULATOR_LDO6,
     22	MT6360_REGULATOR_LDO7,
     23	MT6360_REGULATOR_LDO1,
     24	MT6360_REGULATOR_LDO2,
     25	MT6360_REGULATOR_LDO3,
     26	MT6360_REGULATOR_LDO5,
     27	MT6360_REGULATOR_MAX,
     28};
     29
     30struct mt6360_irq_mapping {
     31	const char *name;
     32	irq_handler_t handler;
     33};
     34
     35struct mt6360_regulator_desc {
     36	const struct regulator_desc desc;
     37	unsigned int mode_reg;
     38	unsigned int mode_mask;
     39	unsigned int state_reg;
     40	unsigned int state_mask;
     41	const struct mt6360_irq_mapping *irq_tables;
     42	int irq_table_size;
     43};
     44
     45struct mt6360_regulator_data {
     46	struct device *dev;
     47	struct regmap *regmap;
     48};
     49
     50static irqreturn_t mt6360_pgb_event_handler(int irq, void *data)
     51{
     52	struct regulator_dev *rdev = data;
     53
     54	regulator_notifier_call_chain(rdev, REGULATOR_EVENT_FAIL, NULL);
     55	return IRQ_HANDLED;
     56}
     57
     58static irqreturn_t mt6360_oc_event_handler(int irq, void *data)
     59{
     60	struct regulator_dev *rdev = data;
     61
     62	regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL);
     63	return IRQ_HANDLED;
     64}
     65
     66static irqreturn_t mt6360_ov_event_handler(int irq, void *data)
     67{
     68	struct regulator_dev *rdev = data;
     69
     70	regulator_notifier_call_chain(rdev, REGULATOR_EVENT_REGULATION_OUT, NULL);
     71	return IRQ_HANDLED;
     72}
     73
     74static irqreturn_t mt6360_uv_event_handler(int irq, void *data)
     75{
     76	struct regulator_dev *rdev = data;
     77
     78	regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, NULL);
     79	return IRQ_HANDLED;
     80}
     81
     82static const struct mt6360_irq_mapping buck1_irq_tbls[] = {
     83	{ "buck1_pgb_evt", mt6360_pgb_event_handler },
     84	{ "buck1_oc_evt", mt6360_oc_event_handler },
     85	{ "buck1_ov_evt", mt6360_ov_event_handler },
     86	{ "buck1_uv_evt", mt6360_uv_event_handler },
     87};
     88
     89static const struct mt6360_irq_mapping buck2_irq_tbls[] = {
     90	{ "buck2_pgb_evt", mt6360_pgb_event_handler },
     91	{ "buck2_oc_evt", mt6360_oc_event_handler },
     92	{ "buck2_ov_evt", mt6360_ov_event_handler },
     93	{ "buck2_uv_evt", mt6360_uv_event_handler },
     94};
     95
     96static const struct mt6360_irq_mapping ldo6_irq_tbls[] = {
     97	{ "ldo6_pgb_evt", mt6360_pgb_event_handler },
     98	{ "ldo6_oc_evt", mt6360_oc_event_handler },
     99};
    100
    101static const struct mt6360_irq_mapping ldo7_irq_tbls[] = {
    102	{ "ldo7_pgb_evt", mt6360_pgb_event_handler },
    103	{ "ldo7_oc_evt", mt6360_oc_event_handler },
    104};
    105
    106static const struct mt6360_irq_mapping ldo1_irq_tbls[] = {
    107	{ "ldo1_pgb_evt", mt6360_pgb_event_handler },
    108	{ "ldo1_oc_evt", mt6360_oc_event_handler },
    109};
    110
    111static const struct mt6360_irq_mapping ldo2_irq_tbls[] = {
    112	{ "ldo2_pgb_evt", mt6360_pgb_event_handler },
    113	{ "ldo2_oc_evt", mt6360_oc_event_handler },
    114};
    115
    116static const struct mt6360_irq_mapping ldo3_irq_tbls[] = {
    117	{ "ldo3_pgb_evt", mt6360_pgb_event_handler },
    118	{ "ldo3_oc_evt", mt6360_oc_event_handler },
    119};
    120
    121static const struct mt6360_irq_mapping ldo5_irq_tbls[] = {
    122	{ "ldo5_pgb_evt", mt6360_pgb_event_handler },
    123	{ "ldo5_oc_evt", mt6360_oc_event_handler },
    124};
    125
    126static const struct linear_range buck_vout_ranges[] = {
    127	REGULATOR_LINEAR_RANGE(300000, 0x00, 0xc7, 5000),
    128	REGULATOR_LINEAR_RANGE(1300000, 0xc8, 0xff, 0),
    129};
    130
    131static const struct linear_range ldo_vout_ranges1[] = {
    132	REGULATOR_LINEAR_RANGE(500000, 0x00, 0x09, 10000),
    133	REGULATOR_LINEAR_RANGE(600000, 0x0a, 0x10, 0),
    134	REGULATOR_LINEAR_RANGE(610000, 0x11, 0x19, 10000),
    135	REGULATOR_LINEAR_RANGE(700000, 0x1a, 0x20, 0),
    136	REGULATOR_LINEAR_RANGE(710000, 0x21, 0x29, 10000),
    137	REGULATOR_LINEAR_RANGE(800000, 0x2a, 0x30, 0),
    138	REGULATOR_LINEAR_RANGE(810000, 0x31, 0x39, 10000),
    139	REGULATOR_LINEAR_RANGE(900000, 0x3a, 0x40, 0),
    140	REGULATOR_LINEAR_RANGE(910000, 0x41, 0x49, 10000),
    141	REGULATOR_LINEAR_RANGE(1000000, 0x4a, 0x50, 0),
    142	REGULATOR_LINEAR_RANGE(1010000, 0x51, 0x59, 10000),
    143	REGULATOR_LINEAR_RANGE(1100000, 0x5a, 0x60, 0),
    144	REGULATOR_LINEAR_RANGE(1110000, 0x61, 0x69, 10000),
    145	REGULATOR_LINEAR_RANGE(1200000, 0x6a, 0x70, 0),
    146	REGULATOR_LINEAR_RANGE(1210000, 0x71, 0x79, 10000),
    147	REGULATOR_LINEAR_RANGE(1300000, 0x7a, 0x80, 0),
    148	REGULATOR_LINEAR_RANGE(1310000, 0x81, 0x89, 10000),
    149	REGULATOR_LINEAR_RANGE(1400000, 0x8a, 0x90, 0),
    150	REGULATOR_LINEAR_RANGE(1410000, 0x91, 0x99, 10000),
    151	REGULATOR_LINEAR_RANGE(1500000, 0x9a, 0xa0, 0),
    152	REGULATOR_LINEAR_RANGE(1510000, 0xa1, 0xa9, 10000),
    153	REGULATOR_LINEAR_RANGE(1600000, 0xaa, 0xb0, 0),
    154	REGULATOR_LINEAR_RANGE(1610000, 0xb1, 0xb9, 10000),
    155	REGULATOR_LINEAR_RANGE(1700000, 0xba, 0xc0, 0),
    156	REGULATOR_LINEAR_RANGE(1710000, 0xc1, 0xc9, 10000),
    157	REGULATOR_LINEAR_RANGE(1800000, 0xca, 0xd0, 0),
    158	REGULATOR_LINEAR_RANGE(1810000, 0xd1, 0xd9, 10000),
    159	REGULATOR_LINEAR_RANGE(1900000, 0xda, 0xe0, 0),
    160	REGULATOR_LINEAR_RANGE(1910000, 0xe1, 0xe9, 10000),
    161	REGULATOR_LINEAR_RANGE(2000000, 0xea, 0xf0, 0),
    162	REGULATOR_LINEAR_RANGE(2010000, 0xf1, 0xf9, 10000),
    163	REGULATOR_LINEAR_RANGE(2100000, 0xfa, 0xff, 0),
    164};
    165
    166static const struct linear_range ldo_vout_ranges2[] = {
    167	REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x09, 10000),
    168	REGULATOR_LINEAR_RANGE(1300000, 0x0a, 0x10, 0),
    169	REGULATOR_LINEAR_RANGE(1310000, 0x11, 0x19, 10000),
    170	REGULATOR_LINEAR_RANGE(1400000, 0x1a, 0x1f, 0),
    171	REGULATOR_LINEAR_RANGE(1500000, 0x20, 0x29, 10000),
    172	REGULATOR_LINEAR_RANGE(1600000, 0x2a, 0x2f, 0),
    173	REGULATOR_LINEAR_RANGE(1700000, 0x30, 0x39, 10000),
    174	REGULATOR_LINEAR_RANGE(1800000, 0x3a, 0x40, 0),
    175	REGULATOR_LINEAR_RANGE(1810000, 0x41, 0x49, 10000),
    176	REGULATOR_LINEAR_RANGE(1900000, 0x4a, 0x4f, 0),
    177	REGULATOR_LINEAR_RANGE(2000000, 0x50, 0x59, 10000),
    178	REGULATOR_LINEAR_RANGE(2100000, 0x5a, 0x60, 0),
    179	REGULATOR_LINEAR_RANGE(2110000, 0x61, 0x69, 10000),
    180	REGULATOR_LINEAR_RANGE(2200000, 0x6a, 0x6f, 0),
    181	REGULATOR_LINEAR_RANGE(2500000, 0x70, 0x79, 10000),
    182	REGULATOR_LINEAR_RANGE(2600000, 0x7a, 0x7f, 0),
    183	REGULATOR_LINEAR_RANGE(2700000, 0x80, 0x89, 10000),
    184	REGULATOR_LINEAR_RANGE(2800000, 0x8a, 0x90, 0),
    185	REGULATOR_LINEAR_RANGE(2810000, 0x91, 0x99, 10000),
    186	REGULATOR_LINEAR_RANGE(2900000, 0x9a, 0xa0, 0),
    187	REGULATOR_LINEAR_RANGE(2910000, 0xa1, 0xa9, 10000),
    188	REGULATOR_LINEAR_RANGE(3000000, 0xaa, 0xb0, 0),
    189	REGULATOR_LINEAR_RANGE(3010000, 0xb1, 0xb9, 10000),
    190	REGULATOR_LINEAR_RANGE(3100000, 0xba, 0xc0, 0),
    191	REGULATOR_LINEAR_RANGE(3110000, 0xc1, 0xc9, 10000),
    192	REGULATOR_LINEAR_RANGE(3200000, 0xca, 0xcf, 0),
    193	REGULATOR_LINEAR_RANGE(3300000, 0xd0, 0xd9, 10000),
    194	REGULATOR_LINEAR_RANGE(3400000, 0xda, 0xe0, 0),
    195	REGULATOR_LINEAR_RANGE(3410000, 0xe1, 0xe9, 10000),
    196	REGULATOR_LINEAR_RANGE(3500000, 0xea, 0xf0, 0),
    197	REGULATOR_LINEAR_RANGE(3510000, 0xf1, 0xf9, 10000),
    198	REGULATOR_LINEAR_RANGE(3600000, 0xfa, 0xff, 0),
    199};
    200
    201static const struct linear_range ldo_vout_ranges3[] = {
    202	REGULATOR_LINEAR_RANGE(2700000, 0x00, 0x09, 10000),
    203	REGULATOR_LINEAR_RANGE(2800000, 0x0a, 0x10, 0),
    204	REGULATOR_LINEAR_RANGE(2810000, 0x11, 0x19, 10000),
    205	REGULATOR_LINEAR_RANGE(2900000, 0x1a, 0x20, 0),
    206	REGULATOR_LINEAR_RANGE(2910000, 0x21, 0x29, 10000),
    207	REGULATOR_LINEAR_RANGE(3000000, 0x2a, 0x30, 0),
    208	REGULATOR_LINEAR_RANGE(3010000, 0x31, 0x39, 10000),
    209	REGULATOR_LINEAR_RANGE(3100000, 0x3a, 0x40, 0),
    210	REGULATOR_LINEAR_RANGE(3110000, 0x41, 0x49, 10000),
    211	REGULATOR_LINEAR_RANGE(3200000, 0x4a, 0x4f, 0),
    212	REGULATOR_LINEAR_RANGE(3300000, 0x50, 0x59, 10000),
    213	REGULATOR_LINEAR_RANGE(3400000, 0x5a, 0x60, 0),
    214	REGULATOR_LINEAR_RANGE(3410000, 0x61, 0x69, 10000),
    215	REGULATOR_LINEAR_RANGE(3500000, 0x6a, 0x70, 0),
    216	REGULATOR_LINEAR_RANGE(3510000, 0x71, 0x79, 10000),
    217	REGULATOR_LINEAR_RANGE(3600000, 0x7a, 0x7f, 0),
    218};
    219
    220static int mt6360_regulator_set_mode(struct regulator_dev *rdev,
    221				     unsigned int mode)
    222{
    223	const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc;
    224	struct regmap *regmap = rdev_get_regmap(rdev);
    225	int shift = ffs(rdesc->mode_mask) - 1;
    226	unsigned int val;
    227	int ret;
    228
    229	switch (mode) {
    230	case REGULATOR_MODE_NORMAL:
    231		val = MT6360_OPMODE_NORMAL;
    232		break;
    233	case REGULATOR_MODE_STANDBY:
    234		val = MT6360_OPMODE_ULP;
    235		break;
    236	case REGULATOR_MODE_IDLE:
    237		val = MT6360_OPMODE_LP;
    238		break;
    239	default:
    240		return -EINVAL;
    241	}
    242
    243	ret = regmap_update_bits(regmap, rdesc->mode_reg, rdesc->mode_mask, val << shift);
    244	if (ret) {
    245		dev_err(&rdev->dev, "%s: fail (%d)\n", __func__, ret);
    246		return ret;
    247	}
    248
    249	return 0;
    250}
    251
    252static unsigned int mt6360_regulator_get_mode(struct regulator_dev *rdev)
    253{
    254	const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc;
    255	struct regmap *regmap = rdev_get_regmap(rdev);
    256	int shift = ffs(rdesc->mode_mask) - 1;
    257	unsigned int val;
    258	int ret;
    259
    260	ret = regmap_read(regmap, rdesc->mode_reg, &val);
    261	if (ret)
    262		return ret;
    263
    264	val &= rdesc->mode_mask;
    265	val >>= shift;
    266
    267	switch (val) {
    268	case MT6360_OPMODE_LP:
    269		return REGULATOR_MODE_IDLE;
    270	case MT6360_OPMODE_ULP:
    271		return REGULATOR_MODE_STANDBY;
    272	case MT6360_OPMODE_NORMAL:
    273		return REGULATOR_MODE_NORMAL;
    274	default:
    275		return -EINVAL;
    276	}
    277}
    278
    279static int mt6360_regulator_get_status(struct regulator_dev *rdev)
    280{
    281	const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc;
    282	struct regmap *regmap = rdev_get_regmap(rdev);
    283	unsigned int val;
    284	int ret;
    285
    286	ret = regmap_read(regmap, rdesc->state_reg, &val);
    287	if (ret)
    288		return ret;
    289
    290	if (val & rdesc->state_mask)
    291		return REGULATOR_STATUS_ON;
    292
    293	return REGULATOR_STATUS_OFF;
    294}
    295
    296static const struct regulator_ops mt6360_regulator_ops = {
    297	.list_voltage = regulator_list_voltage_linear_range,
    298	.enable = regulator_enable_regmap,
    299	.disable = regulator_disable_regmap,
    300	.is_enabled = regulator_is_enabled_regmap,
    301	.set_voltage_sel = regulator_set_voltage_sel_regmap,
    302	.get_voltage_sel = regulator_get_voltage_sel_regmap,
    303	.set_mode = mt6360_regulator_set_mode,
    304	.get_mode = mt6360_regulator_get_mode,
    305	.get_status = mt6360_regulator_get_status,
    306};
    307
    308static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
    309{
    310	switch (hw_mode) {
    311	case MT6360_OPMODE_NORMAL:
    312		return REGULATOR_MODE_NORMAL;
    313	case MT6360_OPMODE_LP:
    314		return REGULATOR_MODE_IDLE;
    315	case MT6360_OPMODE_ULP:
    316		return REGULATOR_MODE_STANDBY;
    317	default:
    318		return REGULATOR_MODE_INVALID;
    319	}
    320}
    321
    322#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg,	vmask,	\
    323			      mreg, mmask, streg, stmask, vranges,	\
    324			      vcnts, offon_delay, irq_tbls)		\
    325{									\
    326	.desc = {							\
    327		.name = #_name,						\
    328		.supply_name = #_sname,					\
    329		.id =  MT6360_REGULATOR_##_name,			\
    330		.of_match = of_match_ptr(#_name),			\
    331		.regulators_node = of_match_ptr("regulator"),		\
    332		.of_map_mode = mt6360_regulator_of_map_mode,		\
    333		.owner = THIS_MODULE,					\
    334		.ops = &mt6360_regulator_ops,				\
    335		.type = REGULATOR_VOLTAGE,				\
    336		.vsel_reg = vreg,					\
    337		.vsel_mask = vmask,					\
    338		.enable_reg = ereg,					\
    339		.enable_mask = emask,					\
    340		.linear_ranges = vranges,				\
    341		.n_linear_ranges = ARRAY_SIZE(vranges),			\
    342		.n_voltages = vcnts,					\
    343		.off_on_delay = offon_delay,				\
    344	},								\
    345	.mode_reg = mreg,						\
    346	.mode_mask = mmask,						\
    347	.state_reg = streg,						\
    348	.state_mask = stmask,						\
    349	.irq_tables = irq_tbls,						\
    350	.irq_table_size = ARRAY_SIZE(irq_tbls),				\
    351}
    352
    353static const struct mt6360_regulator_desc mt6360_regulator_descs[] =  {
    354	MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
    355			      buck_vout_ranges, 256, 0, buck1_irq_tbls),
    356	MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
    357			      buck_vout_ranges, 256, 0, buck2_irq_tbls),
    358	MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
    359			      ldo_vout_ranges1, 256, 0, ldo6_irq_tbls),
    360	MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
    361			      ldo_vout_ranges1, 256, 0, ldo7_irq_tbls),
    362	MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
    363			      ldo_vout_ranges2, 256, 0, ldo1_irq_tbls),
    364	MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
    365			      ldo_vout_ranges2, 256, 0, ldo2_irq_tbls),
    366	MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
    367			      ldo_vout_ranges2, 256, 100, ldo3_irq_tbls),
    368	MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
    369			      ldo_vout_ranges3, 128, 100, ldo5_irq_tbls),
    370};
    371
    372static int mt6360_regulator_irq_register(struct platform_device *pdev,
    373					 struct regulator_dev *rdev,
    374					 const struct mt6360_irq_mapping *tbls,
    375					 int tbl_size)
    376{
    377	int i, irq, ret;
    378
    379	for (i = 0; i < tbl_size; i++) {
    380		const struct mt6360_irq_mapping *irq_desc = tbls + i;
    381
    382		irq = platform_get_irq_byname(pdev, irq_desc->name);
    383		if (irq < 0)
    384			return irq;
    385
    386		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, irq_desc->handler, 0,
    387						irq_desc->name, rdev);
    388		if (ret) {
    389			dev_err(&pdev->dev, "Fail to request %s irq\n", irq_desc->name);
    390			return ret;
    391		}
    392	}
    393
    394	return 0;
    395}
    396
    397static int mt6360_regulator_probe(struct platform_device *pdev)
    398{
    399	struct mt6360_regulator_data *mrd;
    400	struct regulator_config config = {};
    401	int i, ret;
    402
    403	mrd = devm_kzalloc(&pdev->dev, sizeof(*mrd), GFP_KERNEL);
    404	if (!mrd)
    405		return -ENOMEM;
    406
    407	mrd->dev = &pdev->dev;
    408
    409	mrd->regmap = dev_get_regmap(pdev->dev.parent, NULL);
    410	if (!mrd->regmap) {
    411		dev_err(&pdev->dev, "Failed to get parent regmap\n");
    412		return -ENODEV;
    413	}
    414
    415	config.dev = pdev->dev.parent;
    416	config.driver_data = mrd;
    417	config.regmap = mrd->regmap;
    418
    419	for (i = 0; i < ARRAY_SIZE(mt6360_regulator_descs); i++) {
    420		const struct mt6360_regulator_desc *rdesc = mt6360_regulator_descs + i;
    421		struct regulator_dev *rdev;
    422
    423		rdev = devm_regulator_register(&pdev->dev, &rdesc->desc, &config);
    424		if (IS_ERR(rdev)) {
    425			dev_err(&pdev->dev, "Failed to register  %d regulator\n", i);
    426			return PTR_ERR(rdev);
    427		}
    428
    429		ret = mt6360_regulator_irq_register(pdev, rdev, rdesc->irq_tables,
    430						    rdesc->irq_table_size);
    431		if (ret) {
    432			dev_err(&pdev->dev, "Failed to register  %d regulator irqs\n", i);
    433			return ret;
    434		}
    435	}
    436
    437	return 0;
    438}
    439
    440static const struct platform_device_id mt6360_regulator_id_table[] = {
    441	{ "mt6360-regulator", 0 },
    442	{},
    443};
    444MODULE_DEVICE_TABLE(platform, mt6360_regulator_id_table);
    445
    446static struct platform_driver mt6360_regulator_driver = {
    447	.driver = {
    448		.name = "mt6360-regulator",
    449	},
    450	.probe = mt6360_regulator_probe,
    451	.id_table = mt6360_regulator_id_table,
    452};
    453module_platform_driver(mt6360_regulator_driver);
    454
    455MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>");
    456MODULE_DESCRIPTION("MT6360 Regulator Driver");
    457MODULE_LICENSE("GPL v2");