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

pca9450-regulator.c (24942B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2020 NXP.
      4 * NXP PCA9450 pmic driver
      5 */
      6
      7#include <linux/err.h>
      8#include <linux/gpio/consumer.h>
      9#include <linux/i2c.h>
     10#include <linux/interrupt.h>
     11#include <linux/kernel.h>
     12#include <linux/module.h>
     13#include <linux/of.h>
     14#include <linux/of_device.h>
     15#include <linux/platform_device.h>
     16#include <linux/regulator/driver.h>
     17#include <linux/regulator/machine.h>
     18#include <linux/regulator/of_regulator.h>
     19#include <linux/regulator/pca9450.h>
     20
     21struct pc9450_dvs_config {
     22	unsigned int run_reg; /* dvs0 */
     23	unsigned int run_mask;
     24	unsigned int standby_reg; /* dvs1 */
     25	unsigned int standby_mask;
     26};
     27
     28struct pca9450_regulator_desc {
     29	struct regulator_desc desc;
     30	const struct pc9450_dvs_config dvs;
     31};
     32
     33struct pca9450 {
     34	struct device *dev;
     35	struct regmap *regmap;
     36	struct gpio_desc *sd_vsel_gpio;
     37	enum pca9450_chip_type type;
     38	unsigned int rcnt;
     39	int irq;
     40};
     41
     42static const struct regmap_range pca9450_status_range = {
     43	.range_min = PCA9450_REG_INT1,
     44	.range_max = PCA9450_REG_PWRON_STAT,
     45};
     46
     47static const struct regmap_access_table pca9450_volatile_regs = {
     48	.yes_ranges = &pca9450_status_range,
     49	.n_yes_ranges = 1,
     50};
     51
     52static const struct regmap_config pca9450_regmap_config = {
     53	.reg_bits = 8,
     54	.val_bits = 8,
     55	.volatile_table = &pca9450_volatile_regs,
     56	.max_register = PCA9450_MAX_REGISTER - 1,
     57	.cache_type = REGCACHE_RBTREE,
     58};
     59
     60/*
     61 * BUCK1/2/3
     62 * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
     63 * 00: 25mV/1usec
     64 * 01: 25mV/2usec
     65 * 10: 25mV/4usec
     66 * 11: 25mV/8usec
     67 */
     68static const unsigned int pca9450_dvs_buck_ramp_table[] = {
     69	25000, 12500, 6250, 3125
     70};
     71
     72static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
     73	.enable = regulator_enable_regmap,
     74	.disable = regulator_disable_regmap,
     75	.is_enabled = regulator_is_enabled_regmap,
     76	.list_voltage = regulator_list_voltage_linear_range,
     77	.set_voltage_sel = regulator_set_voltage_sel_regmap,
     78	.get_voltage_sel = regulator_get_voltage_sel_regmap,
     79	.set_voltage_time_sel = regulator_set_voltage_time_sel,
     80	.set_ramp_delay	= regulator_set_ramp_delay_regmap,
     81};
     82
     83static const struct regulator_ops pca9450_buck_regulator_ops = {
     84	.enable = regulator_enable_regmap,
     85	.disable = regulator_disable_regmap,
     86	.is_enabled = regulator_is_enabled_regmap,
     87	.list_voltage = regulator_list_voltage_linear_range,
     88	.set_voltage_sel = regulator_set_voltage_sel_regmap,
     89	.get_voltage_sel = regulator_get_voltage_sel_regmap,
     90	.set_voltage_time_sel = regulator_set_voltage_time_sel,
     91};
     92
     93static const struct regulator_ops pca9450_ldo_regulator_ops = {
     94	.enable = regulator_enable_regmap,
     95	.disable = regulator_disable_regmap,
     96	.is_enabled = regulator_is_enabled_regmap,
     97	.list_voltage = regulator_list_voltage_linear_range,
     98	.set_voltage_sel = regulator_set_voltage_sel_regmap,
     99	.get_voltage_sel = regulator_get_voltage_sel_regmap,
    100};
    101
    102/*
    103 * BUCK1/2/3
    104 * 0.60 to 2.1875V (12.5mV step)
    105 */
    106static const struct linear_range pca9450_dvs_buck_volts[] = {
    107	REGULATOR_LINEAR_RANGE(600000,  0x00, 0x7F, 12500),
    108};
    109
    110/*
    111 * BUCK4/5/6
    112 * 0.6V to 3.4V (25mV step)
    113 */
    114static const struct linear_range pca9450_buck_volts[] = {
    115	REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
    116	REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
    117};
    118
    119/*
    120 * LDO1
    121 * 1.6 to 3.3V ()
    122 */
    123static const struct linear_range pca9450_ldo1_volts[] = {
    124	REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
    125	REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
    126};
    127
    128/*
    129 * LDO2
    130 * 0.8 to 1.15V (50mV step)
    131 */
    132static const struct linear_range pca9450_ldo2_volts[] = {
    133	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
    134};
    135
    136/*
    137 * LDO3/4
    138 * 0.8 to 3.3V (100mV step)
    139 */
    140static const struct linear_range pca9450_ldo34_volts[] = {
    141	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
    142	REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
    143};
    144
    145/*
    146 * LDO5
    147 * 1.8 to 3.3V (100mV step)
    148 */
    149static const struct linear_range pca9450_ldo5_volts[] = {
    150	REGULATOR_LINEAR_RANGE(1800000,  0x00, 0x0F, 100000),
    151};
    152
    153static int buck_set_dvs(const struct regulator_desc *desc,
    154			struct device_node *np, struct regmap *regmap,
    155			char *prop, unsigned int reg, unsigned int mask)
    156{
    157	int ret, i;
    158	uint32_t uv;
    159
    160	ret = of_property_read_u32(np, prop, &uv);
    161	if (ret == -EINVAL)
    162		return 0;
    163	else if (ret)
    164		return ret;
    165
    166	for (i = 0; i < desc->n_voltages; i++) {
    167		ret = regulator_desc_list_voltage_linear_range(desc, i);
    168		if (ret < 0)
    169			continue;
    170		if (ret == uv) {
    171			i <<= ffs(desc->vsel_mask) - 1;
    172			ret = regmap_update_bits(regmap, reg, mask, i);
    173			break;
    174		}
    175	}
    176
    177	if (ret == 0) {
    178		struct pca9450_regulator_desc *regulator = container_of(desc,
    179					struct pca9450_regulator_desc, desc);
    180
    181		/* Enable DVS control through PMIC_STBY_REQ for this BUCK */
    182		ret = regmap_update_bits(regmap, regulator->desc.enable_reg,
    183					 BUCK1_DVS_CTRL, BUCK1_DVS_CTRL);
    184	}
    185	return ret;
    186}
    187
    188static int pca9450_set_dvs_levels(struct device_node *np,
    189			    const struct regulator_desc *desc,
    190			    struct regulator_config *cfg)
    191{
    192	struct pca9450_regulator_desc *data = container_of(desc,
    193					struct pca9450_regulator_desc, desc);
    194	const struct pc9450_dvs_config *dvs = &data->dvs;
    195	unsigned int reg, mask;
    196	char *prop;
    197	int i, ret = 0;
    198
    199	for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
    200		switch (i) {
    201		case PCA9450_DVS_LEVEL_RUN:
    202			prop = "nxp,dvs-run-voltage";
    203			reg = dvs->run_reg;
    204			mask = dvs->run_mask;
    205			break;
    206		case PCA9450_DVS_LEVEL_STANDBY:
    207			prop = "nxp,dvs-standby-voltage";
    208			reg = dvs->standby_reg;
    209			mask = dvs->standby_mask;
    210			break;
    211		default:
    212			return -EINVAL;
    213		}
    214
    215		ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
    216		if (ret)
    217			break;
    218	}
    219
    220	return ret;
    221}
    222
    223static const struct pca9450_regulator_desc pca9450a_regulators[] = {
    224	{
    225		.desc = {
    226			.name = "buck1",
    227			.of_match = of_match_ptr("BUCK1"),
    228			.regulators_node = of_match_ptr("regulators"),
    229			.id = PCA9450_BUCK1,
    230			.ops = &pca9450_dvs_buck_regulator_ops,
    231			.type = REGULATOR_VOLTAGE,
    232			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
    233			.linear_ranges = pca9450_dvs_buck_volts,
    234			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
    235			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
    236			.vsel_mask = BUCK1OUT_DVS0_MASK,
    237			.enable_reg = PCA9450_REG_BUCK1CTRL,
    238			.enable_mask = BUCK1_ENMODE_MASK,
    239			.ramp_reg = PCA9450_REG_BUCK1CTRL,
    240			.ramp_mask = BUCK1_RAMP_MASK,
    241			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
    242			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
    243			.owner = THIS_MODULE,
    244			.of_parse_cb = pca9450_set_dvs_levels,
    245		},
    246		.dvs = {
    247			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
    248			.run_mask = BUCK1OUT_DVS0_MASK,
    249			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
    250			.standby_mask = BUCK1OUT_DVS1_MASK,
    251		},
    252	},
    253	{
    254		.desc = {
    255			.name = "buck2",
    256			.of_match = of_match_ptr("BUCK2"),
    257			.regulators_node = of_match_ptr("regulators"),
    258			.id = PCA9450_BUCK2,
    259			.ops = &pca9450_dvs_buck_regulator_ops,
    260			.type = REGULATOR_VOLTAGE,
    261			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
    262			.linear_ranges = pca9450_dvs_buck_volts,
    263			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
    264			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
    265			.vsel_mask = BUCK2OUT_DVS0_MASK,
    266			.enable_reg = PCA9450_REG_BUCK2CTRL,
    267			.enable_mask = BUCK1_ENMODE_MASK,
    268			.ramp_reg = PCA9450_REG_BUCK2CTRL,
    269			.ramp_mask = BUCK2_RAMP_MASK,
    270			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
    271			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
    272			.owner = THIS_MODULE,
    273			.of_parse_cb = pca9450_set_dvs_levels,
    274		},
    275		.dvs = {
    276			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
    277			.run_mask = BUCK2OUT_DVS0_MASK,
    278			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
    279			.standby_mask = BUCK2OUT_DVS1_MASK,
    280		},
    281	},
    282	{
    283		.desc = {
    284			.name = "buck3",
    285			.of_match = of_match_ptr("BUCK3"),
    286			.regulators_node = of_match_ptr("regulators"),
    287			.id = PCA9450_BUCK3,
    288			.ops = &pca9450_dvs_buck_regulator_ops,
    289			.type = REGULATOR_VOLTAGE,
    290			.n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
    291			.linear_ranges = pca9450_dvs_buck_volts,
    292			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
    293			.vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
    294			.vsel_mask = BUCK3OUT_DVS0_MASK,
    295			.enable_reg = PCA9450_REG_BUCK3CTRL,
    296			.enable_mask = BUCK3_ENMODE_MASK,
    297			.ramp_reg = PCA9450_REG_BUCK3CTRL,
    298			.ramp_mask = BUCK3_RAMP_MASK,
    299			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
    300			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
    301			.owner = THIS_MODULE,
    302			.of_parse_cb = pca9450_set_dvs_levels,
    303		},
    304		.dvs = {
    305			.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
    306			.run_mask = BUCK3OUT_DVS0_MASK,
    307			.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
    308			.standby_mask = BUCK3OUT_DVS1_MASK,
    309		},
    310	},
    311	{
    312		.desc = {
    313			.name = "buck4",
    314			.of_match = of_match_ptr("BUCK4"),
    315			.regulators_node = of_match_ptr("regulators"),
    316			.id = PCA9450_BUCK4,
    317			.ops = &pca9450_buck_regulator_ops,
    318			.type = REGULATOR_VOLTAGE,
    319			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
    320			.linear_ranges = pca9450_buck_volts,
    321			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
    322			.vsel_reg = PCA9450_REG_BUCK4OUT,
    323			.vsel_mask = BUCK4OUT_MASK,
    324			.enable_reg = PCA9450_REG_BUCK4CTRL,
    325			.enable_mask = BUCK4_ENMODE_MASK,
    326			.owner = THIS_MODULE,
    327		},
    328	},
    329	{
    330		.desc = {
    331			.name = "buck5",
    332			.of_match = of_match_ptr("BUCK5"),
    333			.regulators_node = of_match_ptr("regulators"),
    334			.id = PCA9450_BUCK5,
    335			.ops = &pca9450_buck_regulator_ops,
    336			.type = REGULATOR_VOLTAGE,
    337			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
    338			.linear_ranges = pca9450_buck_volts,
    339			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
    340			.vsel_reg = PCA9450_REG_BUCK5OUT,
    341			.vsel_mask = BUCK5OUT_MASK,
    342			.enable_reg = PCA9450_REG_BUCK5CTRL,
    343			.enable_mask = BUCK5_ENMODE_MASK,
    344			.owner = THIS_MODULE,
    345		},
    346	},
    347	{
    348		.desc = {
    349			.name = "buck6",
    350			.of_match = of_match_ptr("BUCK6"),
    351			.regulators_node = of_match_ptr("regulators"),
    352			.id = PCA9450_BUCK6,
    353			.ops = &pca9450_buck_regulator_ops,
    354			.type = REGULATOR_VOLTAGE,
    355			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
    356			.linear_ranges = pca9450_buck_volts,
    357			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
    358			.vsel_reg = PCA9450_REG_BUCK6OUT,
    359			.vsel_mask = BUCK6OUT_MASK,
    360			.enable_reg = PCA9450_REG_BUCK6CTRL,
    361			.enable_mask = BUCK6_ENMODE_MASK,
    362			.owner = THIS_MODULE,
    363		},
    364	},
    365	{
    366		.desc = {
    367			.name = "ldo1",
    368			.of_match = of_match_ptr("LDO1"),
    369			.regulators_node = of_match_ptr("regulators"),
    370			.id = PCA9450_LDO1,
    371			.ops = &pca9450_ldo_regulator_ops,
    372			.type = REGULATOR_VOLTAGE,
    373			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
    374			.linear_ranges = pca9450_ldo1_volts,
    375			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
    376			.vsel_reg = PCA9450_REG_LDO1CTRL,
    377			.vsel_mask = LDO1OUT_MASK,
    378			.enable_reg = PCA9450_REG_LDO1CTRL,
    379			.enable_mask = LDO1_EN_MASK,
    380			.owner = THIS_MODULE,
    381		},
    382	},
    383	{
    384		.desc = {
    385			.name = "ldo2",
    386			.of_match = of_match_ptr("LDO2"),
    387			.regulators_node = of_match_ptr("regulators"),
    388			.id = PCA9450_LDO2,
    389			.ops = &pca9450_ldo_regulator_ops,
    390			.type = REGULATOR_VOLTAGE,
    391			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
    392			.linear_ranges = pca9450_ldo2_volts,
    393			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
    394			.vsel_reg = PCA9450_REG_LDO2CTRL,
    395			.vsel_mask = LDO2OUT_MASK,
    396			.enable_reg = PCA9450_REG_LDO2CTRL,
    397			.enable_mask = LDO2_EN_MASK,
    398			.owner = THIS_MODULE,
    399		},
    400	},
    401	{
    402		.desc = {
    403			.name = "ldo3",
    404			.of_match = of_match_ptr("LDO3"),
    405			.regulators_node = of_match_ptr("regulators"),
    406			.id = PCA9450_LDO3,
    407			.ops = &pca9450_ldo_regulator_ops,
    408			.type = REGULATOR_VOLTAGE,
    409			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
    410			.linear_ranges = pca9450_ldo34_volts,
    411			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
    412			.vsel_reg = PCA9450_REG_LDO3CTRL,
    413			.vsel_mask = LDO3OUT_MASK,
    414			.enable_reg = PCA9450_REG_LDO3CTRL,
    415			.enable_mask = LDO3_EN_MASK,
    416			.owner = THIS_MODULE,
    417		},
    418	},
    419	{
    420		.desc = {
    421			.name = "ldo4",
    422			.of_match = of_match_ptr("LDO4"),
    423			.regulators_node = of_match_ptr("regulators"),
    424			.id = PCA9450_LDO4,
    425			.ops = &pca9450_ldo_regulator_ops,
    426			.type = REGULATOR_VOLTAGE,
    427			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
    428			.linear_ranges = pca9450_ldo34_volts,
    429			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
    430			.vsel_reg = PCA9450_REG_LDO4CTRL,
    431			.vsel_mask = LDO4OUT_MASK,
    432			.enable_reg = PCA9450_REG_LDO4CTRL,
    433			.enable_mask = LDO4_EN_MASK,
    434			.owner = THIS_MODULE,
    435		},
    436	},
    437	{
    438		.desc = {
    439			.name = "ldo5",
    440			.of_match = of_match_ptr("LDO5"),
    441			.regulators_node = of_match_ptr("regulators"),
    442			.id = PCA9450_LDO5,
    443			.ops = &pca9450_ldo_regulator_ops,
    444			.type = REGULATOR_VOLTAGE,
    445			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
    446			.linear_ranges = pca9450_ldo5_volts,
    447			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
    448			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
    449			.vsel_mask = LDO5HOUT_MASK,
    450			.enable_reg = PCA9450_REG_LDO5CTRL_H,
    451			.enable_mask = LDO5H_EN_MASK,
    452			.owner = THIS_MODULE,
    453		},
    454	},
    455};
    456
    457/*
    458 * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
    459 * on PCA9450C as no Buck3.
    460 */
    461static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
    462	{
    463		.desc = {
    464			.name = "buck1",
    465			.of_match = of_match_ptr("BUCK1"),
    466			.regulators_node = of_match_ptr("regulators"),
    467			.id = PCA9450_BUCK1,
    468			.ops = &pca9450_dvs_buck_regulator_ops,
    469			.type = REGULATOR_VOLTAGE,
    470			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
    471			.linear_ranges = pca9450_dvs_buck_volts,
    472			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
    473			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
    474			.vsel_mask = BUCK1OUT_DVS0_MASK,
    475			.enable_reg = PCA9450_REG_BUCK1CTRL,
    476			.enable_mask = BUCK1_ENMODE_MASK,
    477			.ramp_reg = PCA9450_REG_BUCK1CTRL,
    478			.ramp_mask = BUCK1_RAMP_MASK,
    479			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
    480			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
    481			.owner = THIS_MODULE,
    482			.of_parse_cb = pca9450_set_dvs_levels,
    483		},
    484		.dvs = {
    485			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
    486			.run_mask = BUCK1OUT_DVS0_MASK,
    487			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
    488			.standby_mask = BUCK1OUT_DVS1_MASK,
    489		},
    490	},
    491	{
    492		.desc = {
    493			.name = "buck2",
    494			.of_match = of_match_ptr("BUCK2"),
    495			.regulators_node = of_match_ptr("regulators"),
    496			.id = PCA9450_BUCK2,
    497			.ops = &pca9450_dvs_buck_regulator_ops,
    498			.type = REGULATOR_VOLTAGE,
    499			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
    500			.linear_ranges = pca9450_dvs_buck_volts,
    501			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
    502			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
    503			.vsel_mask = BUCK2OUT_DVS0_MASK,
    504			.enable_reg = PCA9450_REG_BUCK2CTRL,
    505			.enable_mask = BUCK1_ENMODE_MASK,
    506			.ramp_reg = PCA9450_REG_BUCK2CTRL,
    507			.ramp_mask = BUCK2_RAMP_MASK,
    508			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
    509			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
    510			.owner = THIS_MODULE,
    511			.of_parse_cb = pca9450_set_dvs_levels,
    512		},
    513		.dvs = {
    514			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
    515			.run_mask = BUCK2OUT_DVS0_MASK,
    516			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
    517			.standby_mask = BUCK2OUT_DVS1_MASK,
    518		},
    519	},
    520	{
    521		.desc = {
    522			.name = "buck4",
    523			.of_match = of_match_ptr("BUCK4"),
    524			.regulators_node = of_match_ptr("regulators"),
    525			.id = PCA9450_BUCK4,
    526			.ops = &pca9450_buck_regulator_ops,
    527			.type = REGULATOR_VOLTAGE,
    528			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
    529			.linear_ranges = pca9450_buck_volts,
    530			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
    531			.vsel_reg = PCA9450_REG_BUCK4OUT,
    532			.vsel_mask = BUCK4OUT_MASK,
    533			.enable_reg = PCA9450_REG_BUCK4CTRL,
    534			.enable_mask = BUCK4_ENMODE_MASK,
    535			.owner = THIS_MODULE,
    536		},
    537	},
    538	{
    539		.desc = {
    540			.name = "buck5",
    541			.of_match = of_match_ptr("BUCK5"),
    542			.regulators_node = of_match_ptr("regulators"),
    543			.id = PCA9450_BUCK5,
    544			.ops = &pca9450_buck_regulator_ops,
    545			.type = REGULATOR_VOLTAGE,
    546			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
    547			.linear_ranges = pca9450_buck_volts,
    548			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
    549			.vsel_reg = PCA9450_REG_BUCK5OUT,
    550			.vsel_mask = BUCK5OUT_MASK,
    551			.enable_reg = PCA9450_REG_BUCK5CTRL,
    552			.enable_mask = BUCK5_ENMODE_MASK,
    553			.owner = THIS_MODULE,
    554		},
    555	},
    556	{
    557		.desc = {
    558			.name = "buck6",
    559			.of_match = of_match_ptr("BUCK6"),
    560			.regulators_node = of_match_ptr("regulators"),
    561			.id = PCA9450_BUCK6,
    562			.ops = &pca9450_buck_regulator_ops,
    563			.type = REGULATOR_VOLTAGE,
    564			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
    565			.linear_ranges = pca9450_buck_volts,
    566			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
    567			.vsel_reg = PCA9450_REG_BUCK6OUT,
    568			.vsel_mask = BUCK6OUT_MASK,
    569			.enable_reg = PCA9450_REG_BUCK6CTRL,
    570			.enable_mask = BUCK6_ENMODE_MASK,
    571			.owner = THIS_MODULE,
    572		},
    573	},
    574	{
    575		.desc = {
    576			.name = "ldo1",
    577			.of_match = of_match_ptr("LDO1"),
    578			.regulators_node = of_match_ptr("regulators"),
    579			.id = PCA9450_LDO1,
    580			.ops = &pca9450_ldo_regulator_ops,
    581			.type = REGULATOR_VOLTAGE,
    582			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
    583			.linear_ranges = pca9450_ldo1_volts,
    584			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
    585			.vsel_reg = PCA9450_REG_LDO1CTRL,
    586			.vsel_mask = LDO1OUT_MASK,
    587			.enable_reg = PCA9450_REG_LDO1CTRL,
    588			.enable_mask = LDO1_EN_MASK,
    589			.owner = THIS_MODULE,
    590		},
    591	},
    592	{
    593		.desc = {
    594			.name = "ldo2",
    595			.of_match = of_match_ptr("LDO2"),
    596			.regulators_node = of_match_ptr("regulators"),
    597			.id = PCA9450_LDO2,
    598			.ops = &pca9450_ldo_regulator_ops,
    599			.type = REGULATOR_VOLTAGE,
    600			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
    601			.linear_ranges = pca9450_ldo2_volts,
    602			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
    603			.vsel_reg = PCA9450_REG_LDO2CTRL,
    604			.vsel_mask = LDO2OUT_MASK,
    605			.enable_reg = PCA9450_REG_LDO2CTRL,
    606			.enable_mask = LDO2_EN_MASK,
    607			.owner = THIS_MODULE,
    608		},
    609	},
    610	{
    611		.desc = {
    612			.name = "ldo3",
    613			.of_match = of_match_ptr("LDO3"),
    614			.regulators_node = of_match_ptr("regulators"),
    615			.id = PCA9450_LDO3,
    616			.ops = &pca9450_ldo_regulator_ops,
    617			.type = REGULATOR_VOLTAGE,
    618			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
    619			.linear_ranges = pca9450_ldo34_volts,
    620			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
    621			.vsel_reg = PCA9450_REG_LDO3CTRL,
    622			.vsel_mask = LDO3OUT_MASK,
    623			.enable_reg = PCA9450_REG_LDO3CTRL,
    624			.enable_mask = LDO3_EN_MASK,
    625			.owner = THIS_MODULE,
    626		},
    627	},
    628	{
    629		.desc = {
    630			.name = "ldo4",
    631			.of_match = of_match_ptr("LDO4"),
    632			.regulators_node = of_match_ptr("regulators"),
    633			.id = PCA9450_LDO4,
    634			.ops = &pca9450_ldo_regulator_ops,
    635			.type = REGULATOR_VOLTAGE,
    636			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
    637			.linear_ranges = pca9450_ldo34_volts,
    638			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
    639			.vsel_reg = PCA9450_REG_LDO4CTRL,
    640			.vsel_mask = LDO4OUT_MASK,
    641			.enable_reg = PCA9450_REG_LDO4CTRL,
    642			.enable_mask = LDO4_EN_MASK,
    643			.owner = THIS_MODULE,
    644		},
    645	},
    646	{
    647		.desc = {
    648			.name = "ldo5",
    649			.of_match = of_match_ptr("LDO5"),
    650			.regulators_node = of_match_ptr("regulators"),
    651			.id = PCA9450_LDO5,
    652			.ops = &pca9450_ldo_regulator_ops,
    653			.type = REGULATOR_VOLTAGE,
    654			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
    655			.linear_ranges = pca9450_ldo5_volts,
    656			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
    657			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
    658			.vsel_mask = LDO5HOUT_MASK,
    659			.enable_reg = PCA9450_REG_LDO5CTRL_H,
    660			.enable_mask = LDO5H_EN_MASK,
    661			.owner = THIS_MODULE,
    662		},
    663	},
    664};
    665
    666static irqreturn_t pca9450_irq_handler(int irq, void *data)
    667{
    668	struct pca9450 *pca9450 = data;
    669	struct regmap *regmap = pca9450->regmap;
    670	unsigned int status;
    671	int ret;
    672
    673	ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
    674	if (ret < 0) {
    675		dev_err(pca9450->dev,
    676			"Failed to read INT1(%d)\n", ret);
    677		return IRQ_NONE;
    678	}
    679
    680	if (status & IRQ_PWRON)
    681		dev_warn(pca9450->dev, "PWRON interrupt.\n");
    682
    683	if (status & IRQ_WDOGB)
    684		dev_warn(pca9450->dev, "WDOGB interrupt.\n");
    685
    686	if (status & IRQ_VR_FLT1)
    687		dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
    688
    689	if (status & IRQ_VR_FLT2)
    690		dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
    691
    692	if (status & IRQ_LOWVSYS)
    693		dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
    694
    695	if (status & IRQ_THERM_105)
    696		dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
    697
    698	if (status & IRQ_THERM_125)
    699		dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
    700
    701	return IRQ_HANDLED;
    702}
    703
    704static int pca9450_i2c_probe(struct i2c_client *i2c,
    705			     const struct i2c_device_id *id)
    706{
    707	enum pca9450_chip_type type = (unsigned int)(uintptr_t)
    708				      of_device_get_match_data(&i2c->dev);
    709	const struct pca9450_regulator_desc	*regulator_desc;
    710	struct regulator_config config = { };
    711	struct pca9450 *pca9450;
    712	unsigned int device_id, i;
    713	unsigned int reset_ctrl;
    714	int ret;
    715
    716	if (!i2c->irq) {
    717		dev_err(&i2c->dev, "No IRQ configured?\n");
    718		return -EINVAL;
    719	}
    720
    721	pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
    722	if (!pca9450)
    723		return -ENOMEM;
    724
    725	switch (type) {
    726	case PCA9450_TYPE_PCA9450A:
    727		regulator_desc = pca9450a_regulators;
    728		pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
    729		break;
    730	case PCA9450_TYPE_PCA9450BC:
    731		regulator_desc = pca9450bc_regulators;
    732		pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
    733		break;
    734	default:
    735		dev_err(&i2c->dev, "Unknown device type");
    736		return -EINVAL;
    737	}
    738
    739	pca9450->irq = i2c->irq;
    740	pca9450->type = type;
    741	pca9450->dev = &i2c->dev;
    742
    743	dev_set_drvdata(&i2c->dev, pca9450);
    744
    745	pca9450->regmap = devm_regmap_init_i2c(i2c,
    746					       &pca9450_regmap_config);
    747	if (IS_ERR(pca9450->regmap)) {
    748		dev_err(&i2c->dev, "regmap initialization failed\n");
    749		return PTR_ERR(pca9450->regmap);
    750	}
    751
    752	ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
    753	if (ret) {
    754		dev_err(&i2c->dev, "Read device id error\n");
    755		return ret;
    756	}
    757
    758	/* Check your board and dts for match the right pmic */
    759	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
    760	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
    761		dev_err(&i2c->dev, "Device id(%x) mismatched\n",
    762			device_id >> 4);
    763		return -EINVAL;
    764	}
    765
    766	for (i = 0; i < pca9450->rcnt; i++) {
    767		const struct regulator_desc *desc;
    768		struct regulator_dev *rdev;
    769		const struct pca9450_regulator_desc *r;
    770
    771		r = &regulator_desc[i];
    772		desc = &r->desc;
    773
    774		config.regmap = pca9450->regmap;
    775		config.dev = pca9450->dev;
    776
    777		rdev = devm_regulator_register(pca9450->dev, desc, &config);
    778		if (IS_ERR(rdev)) {
    779			ret = PTR_ERR(rdev);
    780			dev_err(pca9450->dev,
    781				"Failed to register regulator(%s): %d\n",
    782				desc->name, ret);
    783			return ret;
    784		}
    785	}
    786
    787	ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
    788					pca9450_irq_handler,
    789					(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
    790					"pca9450-irq", pca9450);
    791	if (ret != 0) {
    792		dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
    793			pca9450->irq);
    794		return ret;
    795	}
    796	/* Unmask all interrupt except PWRON/WDOG/RSVD */
    797	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
    798				IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
    799				IRQ_THERM_105 | IRQ_THERM_125,
    800				IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
    801	if (ret) {
    802		dev_err(&i2c->dev, "Unmask irq error\n");
    803		return ret;
    804	}
    805
    806	/* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
    807	ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
    808				BUCK123_PRESET_EN);
    809	if (ret) {
    810		dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
    811		return ret;
    812	}
    813
    814	if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))
    815		reset_ctrl = WDOG_B_CFG_WARM;
    816	else
    817		reset_ctrl = WDOG_B_CFG_COLD_LDO12;
    818
    819	/* Set reset behavior on assertion of WDOG_B signal */
    820	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
    821				 WDOG_B_CFG_MASK, reset_ctrl);
    822	if (ret) {
    823		dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
    824		return ret;
    825	}
    826
    827	if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {
    828		/* Enable I2C Level Translator */
    829		ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,
    830					 I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);
    831		if (ret) {
    832			dev_err(&i2c->dev,
    833				"Failed to enable I2C level translator\n");
    834			return ret;
    835		}
    836	}
    837
    838	/*
    839	 * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
    840	 * This is only valid if the SD_VSEL input of the PMIC is high. Let's
    841	 * check if the pin is available as GPIO and set it to high.
    842	 */
    843	pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
    844
    845	if (IS_ERR(pca9450->sd_vsel_gpio)) {
    846		dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
    847		return PTR_ERR(pca9450->sd_vsel_gpio);
    848	}
    849
    850	dev_info(&i2c->dev, "%s probed.\n",
    851		type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
    852
    853	return 0;
    854}
    855
    856static const struct of_device_id pca9450_of_match[] = {
    857	{
    858		.compatible = "nxp,pca9450a",
    859		.data = (void *)PCA9450_TYPE_PCA9450A,
    860	},
    861	{
    862		.compatible = "nxp,pca9450b",
    863		.data = (void *)PCA9450_TYPE_PCA9450BC,
    864	},
    865	{
    866		.compatible = "nxp,pca9450c",
    867		.data = (void *)PCA9450_TYPE_PCA9450BC,
    868	},
    869	{ }
    870};
    871MODULE_DEVICE_TABLE(of, pca9450_of_match);
    872
    873static struct i2c_driver pca9450_i2c_driver = {
    874	.driver = {
    875		.name = "nxp-pca9450",
    876		.of_match_table = pca9450_of_match,
    877	},
    878	.probe = pca9450_i2c_probe,
    879};
    880
    881module_i2c_driver(pca9450_i2c_driver);
    882
    883MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
    884MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
    885MODULE_LICENSE("GPL");