162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2020 NXP.
462306a36Sopenharmony_ci * NXP PCA9450 pmic driver
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/err.h>
862306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
962306a36Sopenharmony_ci#include <linux/i2c.h>
1062306a36Sopenharmony_ci#include <linux/interrupt.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci#include <linux/of.h>
1462306a36Sopenharmony_ci#include <linux/platform_device.h>
1562306a36Sopenharmony_ci#include <linux/regulator/driver.h>
1662306a36Sopenharmony_ci#include <linux/regulator/machine.h>
1762306a36Sopenharmony_ci#include <linux/regulator/of_regulator.h>
1862306a36Sopenharmony_ci#include <linux/regulator/pca9450.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistruct pc9450_dvs_config {
2162306a36Sopenharmony_ci	unsigned int run_reg; /* dvs0 */
2262306a36Sopenharmony_ci	unsigned int run_mask;
2362306a36Sopenharmony_ci	unsigned int standby_reg; /* dvs1 */
2462306a36Sopenharmony_ci	unsigned int standby_mask;
2562306a36Sopenharmony_ci};
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistruct pca9450_regulator_desc {
2862306a36Sopenharmony_ci	struct regulator_desc desc;
2962306a36Sopenharmony_ci	const struct pc9450_dvs_config dvs;
3062306a36Sopenharmony_ci};
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistruct pca9450 {
3362306a36Sopenharmony_ci	struct device *dev;
3462306a36Sopenharmony_ci	struct regmap *regmap;
3562306a36Sopenharmony_ci	struct gpio_desc *sd_vsel_gpio;
3662306a36Sopenharmony_ci	enum pca9450_chip_type type;
3762306a36Sopenharmony_ci	unsigned int rcnt;
3862306a36Sopenharmony_ci	int irq;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic const struct regmap_range pca9450_status_range = {
4262306a36Sopenharmony_ci	.range_min = PCA9450_REG_INT1,
4362306a36Sopenharmony_ci	.range_max = PCA9450_REG_PWRON_STAT,
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic const struct regmap_access_table pca9450_volatile_regs = {
4762306a36Sopenharmony_ci	.yes_ranges = &pca9450_status_range,
4862306a36Sopenharmony_ci	.n_yes_ranges = 1,
4962306a36Sopenharmony_ci};
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic const struct regmap_config pca9450_regmap_config = {
5262306a36Sopenharmony_ci	.reg_bits = 8,
5362306a36Sopenharmony_ci	.val_bits = 8,
5462306a36Sopenharmony_ci	.volatile_table = &pca9450_volatile_regs,
5562306a36Sopenharmony_ci	.max_register = PCA9450_MAX_REGISTER - 1,
5662306a36Sopenharmony_ci	.cache_type = REGCACHE_RBTREE,
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/*
6062306a36Sopenharmony_ci * BUCK1/2/3
6162306a36Sopenharmony_ci * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
6262306a36Sopenharmony_ci * 00: 25mV/1usec
6362306a36Sopenharmony_ci * 01: 25mV/2usec
6462306a36Sopenharmony_ci * 10: 25mV/4usec
6562306a36Sopenharmony_ci * 11: 25mV/8usec
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_cistatic const unsigned int pca9450_dvs_buck_ramp_table[] = {
6862306a36Sopenharmony_ci	25000, 12500, 6250, 3125
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
7262306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
7362306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
7462306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
7562306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear_range,
7662306a36Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
7762306a36Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
7862306a36Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
7962306a36Sopenharmony_ci	.set_ramp_delay	= regulator_set_ramp_delay_regmap,
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic const struct regulator_ops pca9450_buck_regulator_ops = {
8362306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
8462306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
8562306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
8662306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear_range,
8762306a36Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
8862306a36Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
8962306a36Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic const struct regulator_ops pca9450_ldo_regulator_ops = {
9362306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
9462306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
9562306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
9662306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear_range,
9762306a36Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
9862306a36Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci/*
10262306a36Sopenharmony_ci * BUCK1/2/3
10362306a36Sopenharmony_ci * 0.60 to 2.1875V (12.5mV step)
10462306a36Sopenharmony_ci */
10562306a36Sopenharmony_cistatic const struct linear_range pca9450_dvs_buck_volts[] = {
10662306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(600000,  0x00, 0x7F, 12500),
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/*
11062306a36Sopenharmony_ci * BUCK4/5/6
11162306a36Sopenharmony_ci * 0.6V to 3.4V (25mV step)
11262306a36Sopenharmony_ci */
11362306a36Sopenharmony_cistatic const struct linear_range pca9450_buck_volts[] = {
11462306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
11562306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
11662306a36Sopenharmony_ci};
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci/*
11962306a36Sopenharmony_ci * LDO1
12062306a36Sopenharmony_ci * 1.6 to 3.3V ()
12162306a36Sopenharmony_ci */
12262306a36Sopenharmony_cistatic const struct linear_range pca9450_ldo1_volts[] = {
12362306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
12462306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/*
12862306a36Sopenharmony_ci * LDO2
12962306a36Sopenharmony_ci * 0.8 to 1.15V (50mV step)
13062306a36Sopenharmony_ci */
13162306a36Sopenharmony_cistatic const struct linear_range pca9450_ldo2_volts[] = {
13262306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/*
13662306a36Sopenharmony_ci * LDO3/4
13762306a36Sopenharmony_ci * 0.8 to 3.3V (100mV step)
13862306a36Sopenharmony_ci */
13962306a36Sopenharmony_cistatic const struct linear_range pca9450_ldo34_volts[] = {
14062306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
14162306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
14262306a36Sopenharmony_ci};
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci/*
14562306a36Sopenharmony_ci * LDO5
14662306a36Sopenharmony_ci * 1.8 to 3.3V (100mV step)
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_cistatic const struct linear_range pca9450_ldo5_volts[] = {
14962306a36Sopenharmony_ci	REGULATOR_LINEAR_RANGE(1800000,  0x00, 0x0F, 100000),
15062306a36Sopenharmony_ci};
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistatic int buck_set_dvs(const struct regulator_desc *desc,
15362306a36Sopenharmony_ci			struct device_node *np, struct regmap *regmap,
15462306a36Sopenharmony_ci			char *prop, unsigned int reg, unsigned int mask)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	int ret, i;
15762306a36Sopenharmony_ci	uint32_t uv;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	ret = of_property_read_u32(np, prop, &uv);
16062306a36Sopenharmony_ci	if (ret == -EINVAL)
16162306a36Sopenharmony_ci		return 0;
16262306a36Sopenharmony_ci	else if (ret)
16362306a36Sopenharmony_ci		return ret;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	for (i = 0; i < desc->n_voltages; i++) {
16662306a36Sopenharmony_ci		ret = regulator_desc_list_voltage_linear_range(desc, i);
16762306a36Sopenharmony_ci		if (ret < 0)
16862306a36Sopenharmony_ci			continue;
16962306a36Sopenharmony_ci		if (ret == uv) {
17062306a36Sopenharmony_ci			i <<= ffs(desc->vsel_mask) - 1;
17162306a36Sopenharmony_ci			ret = regmap_update_bits(regmap, reg, mask, i);
17262306a36Sopenharmony_ci			break;
17362306a36Sopenharmony_ci		}
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	if (ret == 0) {
17762306a36Sopenharmony_ci		struct pca9450_regulator_desc *regulator = container_of(desc,
17862306a36Sopenharmony_ci					struct pca9450_regulator_desc, desc);
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci		/* Enable DVS control through PMIC_STBY_REQ for this BUCK */
18162306a36Sopenharmony_ci		ret = regmap_update_bits(regmap, regulator->desc.enable_reg,
18262306a36Sopenharmony_ci					 BUCK1_DVS_CTRL, BUCK1_DVS_CTRL);
18362306a36Sopenharmony_ci	}
18462306a36Sopenharmony_ci	return ret;
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic int pca9450_set_dvs_levels(struct device_node *np,
18862306a36Sopenharmony_ci			    const struct regulator_desc *desc,
18962306a36Sopenharmony_ci			    struct regulator_config *cfg)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	struct pca9450_regulator_desc *data = container_of(desc,
19262306a36Sopenharmony_ci					struct pca9450_regulator_desc, desc);
19362306a36Sopenharmony_ci	const struct pc9450_dvs_config *dvs = &data->dvs;
19462306a36Sopenharmony_ci	unsigned int reg, mask;
19562306a36Sopenharmony_ci	char *prop;
19662306a36Sopenharmony_ci	int i, ret = 0;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
19962306a36Sopenharmony_ci		switch (i) {
20062306a36Sopenharmony_ci		case PCA9450_DVS_LEVEL_RUN:
20162306a36Sopenharmony_ci			prop = "nxp,dvs-run-voltage";
20262306a36Sopenharmony_ci			reg = dvs->run_reg;
20362306a36Sopenharmony_ci			mask = dvs->run_mask;
20462306a36Sopenharmony_ci			break;
20562306a36Sopenharmony_ci		case PCA9450_DVS_LEVEL_STANDBY:
20662306a36Sopenharmony_ci			prop = "nxp,dvs-standby-voltage";
20762306a36Sopenharmony_ci			reg = dvs->standby_reg;
20862306a36Sopenharmony_ci			mask = dvs->standby_mask;
20962306a36Sopenharmony_ci			break;
21062306a36Sopenharmony_ci		default:
21162306a36Sopenharmony_ci			return -EINVAL;
21262306a36Sopenharmony_ci		}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci		ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
21562306a36Sopenharmony_ci		if (ret)
21662306a36Sopenharmony_ci			break;
21762306a36Sopenharmony_ci	}
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	return ret;
22062306a36Sopenharmony_ci}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistatic const struct pca9450_regulator_desc pca9450a_regulators[] = {
22362306a36Sopenharmony_ci	{
22462306a36Sopenharmony_ci		.desc = {
22562306a36Sopenharmony_ci			.name = "buck1",
22662306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK1"),
22762306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
22862306a36Sopenharmony_ci			.id = PCA9450_BUCK1,
22962306a36Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
23062306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
23162306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
23262306a36Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
23362306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
23462306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
23562306a36Sopenharmony_ci			.vsel_mask = BUCK1OUT_DVS0_MASK,
23662306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK1CTRL,
23762306a36Sopenharmony_ci			.enable_mask = BUCK1_ENMODE_MASK,
23862306a36Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK1CTRL,
23962306a36Sopenharmony_ci			.ramp_mask = BUCK1_RAMP_MASK,
24062306a36Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
24162306a36Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
24262306a36Sopenharmony_ci			.owner = THIS_MODULE,
24362306a36Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
24462306a36Sopenharmony_ci		},
24562306a36Sopenharmony_ci		.dvs = {
24662306a36Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
24762306a36Sopenharmony_ci			.run_mask = BUCK1OUT_DVS0_MASK,
24862306a36Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
24962306a36Sopenharmony_ci			.standby_mask = BUCK1OUT_DVS1_MASK,
25062306a36Sopenharmony_ci		},
25162306a36Sopenharmony_ci	},
25262306a36Sopenharmony_ci	{
25362306a36Sopenharmony_ci		.desc = {
25462306a36Sopenharmony_ci			.name = "buck2",
25562306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK2"),
25662306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
25762306a36Sopenharmony_ci			.id = PCA9450_BUCK2,
25862306a36Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
25962306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
26062306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
26162306a36Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
26262306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
26362306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
26462306a36Sopenharmony_ci			.vsel_mask = BUCK2OUT_DVS0_MASK,
26562306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK2CTRL,
26662306a36Sopenharmony_ci			.enable_mask = BUCK2_ENMODE_MASK,
26762306a36Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK2CTRL,
26862306a36Sopenharmony_ci			.ramp_mask = BUCK2_RAMP_MASK,
26962306a36Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
27062306a36Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
27162306a36Sopenharmony_ci			.owner = THIS_MODULE,
27262306a36Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
27362306a36Sopenharmony_ci		},
27462306a36Sopenharmony_ci		.dvs = {
27562306a36Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
27662306a36Sopenharmony_ci			.run_mask = BUCK2OUT_DVS0_MASK,
27762306a36Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
27862306a36Sopenharmony_ci			.standby_mask = BUCK2OUT_DVS1_MASK,
27962306a36Sopenharmony_ci		},
28062306a36Sopenharmony_ci	},
28162306a36Sopenharmony_ci	{
28262306a36Sopenharmony_ci		.desc = {
28362306a36Sopenharmony_ci			.name = "buck3",
28462306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK3"),
28562306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
28662306a36Sopenharmony_ci			.id = PCA9450_BUCK3,
28762306a36Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
28862306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
28962306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
29062306a36Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
29162306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
29262306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
29362306a36Sopenharmony_ci			.vsel_mask = BUCK3OUT_DVS0_MASK,
29462306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK3CTRL,
29562306a36Sopenharmony_ci			.enable_mask = BUCK3_ENMODE_MASK,
29662306a36Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK3CTRL,
29762306a36Sopenharmony_ci			.ramp_mask = BUCK3_RAMP_MASK,
29862306a36Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
29962306a36Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
30062306a36Sopenharmony_ci			.owner = THIS_MODULE,
30162306a36Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
30262306a36Sopenharmony_ci		},
30362306a36Sopenharmony_ci		.dvs = {
30462306a36Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
30562306a36Sopenharmony_ci			.run_mask = BUCK3OUT_DVS0_MASK,
30662306a36Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
30762306a36Sopenharmony_ci			.standby_mask = BUCK3OUT_DVS1_MASK,
30862306a36Sopenharmony_ci		},
30962306a36Sopenharmony_ci	},
31062306a36Sopenharmony_ci	{
31162306a36Sopenharmony_ci		.desc = {
31262306a36Sopenharmony_ci			.name = "buck4",
31362306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK4"),
31462306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
31562306a36Sopenharmony_ci			.id = PCA9450_BUCK4,
31662306a36Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
31762306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
31862306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
31962306a36Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
32062306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
32162306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK4OUT,
32262306a36Sopenharmony_ci			.vsel_mask = BUCK4OUT_MASK,
32362306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK4CTRL,
32462306a36Sopenharmony_ci			.enable_mask = BUCK4_ENMODE_MASK,
32562306a36Sopenharmony_ci			.owner = THIS_MODULE,
32662306a36Sopenharmony_ci		},
32762306a36Sopenharmony_ci	},
32862306a36Sopenharmony_ci	{
32962306a36Sopenharmony_ci		.desc = {
33062306a36Sopenharmony_ci			.name = "buck5",
33162306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK5"),
33262306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
33362306a36Sopenharmony_ci			.id = PCA9450_BUCK5,
33462306a36Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
33562306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
33662306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
33762306a36Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
33862306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
33962306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK5OUT,
34062306a36Sopenharmony_ci			.vsel_mask = BUCK5OUT_MASK,
34162306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK5CTRL,
34262306a36Sopenharmony_ci			.enable_mask = BUCK5_ENMODE_MASK,
34362306a36Sopenharmony_ci			.owner = THIS_MODULE,
34462306a36Sopenharmony_ci		},
34562306a36Sopenharmony_ci	},
34662306a36Sopenharmony_ci	{
34762306a36Sopenharmony_ci		.desc = {
34862306a36Sopenharmony_ci			.name = "buck6",
34962306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK6"),
35062306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
35162306a36Sopenharmony_ci			.id = PCA9450_BUCK6,
35262306a36Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
35362306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
35462306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
35562306a36Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
35662306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
35762306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK6OUT,
35862306a36Sopenharmony_ci			.vsel_mask = BUCK6OUT_MASK,
35962306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK6CTRL,
36062306a36Sopenharmony_ci			.enable_mask = BUCK6_ENMODE_MASK,
36162306a36Sopenharmony_ci			.owner = THIS_MODULE,
36262306a36Sopenharmony_ci		},
36362306a36Sopenharmony_ci	},
36462306a36Sopenharmony_ci	{
36562306a36Sopenharmony_ci		.desc = {
36662306a36Sopenharmony_ci			.name = "ldo1",
36762306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO1"),
36862306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
36962306a36Sopenharmony_ci			.id = PCA9450_LDO1,
37062306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
37162306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
37262306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
37362306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo1_volts,
37462306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
37562306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO1CTRL,
37662306a36Sopenharmony_ci			.vsel_mask = LDO1OUT_MASK,
37762306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO1CTRL,
37862306a36Sopenharmony_ci			.enable_mask = LDO1_EN_MASK,
37962306a36Sopenharmony_ci			.owner = THIS_MODULE,
38062306a36Sopenharmony_ci		},
38162306a36Sopenharmony_ci	},
38262306a36Sopenharmony_ci	{
38362306a36Sopenharmony_ci		.desc = {
38462306a36Sopenharmony_ci			.name = "ldo2",
38562306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO2"),
38662306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
38762306a36Sopenharmony_ci			.id = PCA9450_LDO2,
38862306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
38962306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
39062306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
39162306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo2_volts,
39262306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
39362306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO2CTRL,
39462306a36Sopenharmony_ci			.vsel_mask = LDO2OUT_MASK,
39562306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO2CTRL,
39662306a36Sopenharmony_ci			.enable_mask = LDO2_EN_MASK,
39762306a36Sopenharmony_ci			.owner = THIS_MODULE,
39862306a36Sopenharmony_ci		},
39962306a36Sopenharmony_ci	},
40062306a36Sopenharmony_ci	{
40162306a36Sopenharmony_ci		.desc = {
40262306a36Sopenharmony_ci			.name = "ldo3",
40362306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO3"),
40462306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
40562306a36Sopenharmony_ci			.id = PCA9450_LDO3,
40662306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
40762306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
40862306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
40962306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
41062306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
41162306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO3CTRL,
41262306a36Sopenharmony_ci			.vsel_mask = LDO3OUT_MASK,
41362306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO3CTRL,
41462306a36Sopenharmony_ci			.enable_mask = LDO3_EN_MASK,
41562306a36Sopenharmony_ci			.owner = THIS_MODULE,
41662306a36Sopenharmony_ci		},
41762306a36Sopenharmony_ci	},
41862306a36Sopenharmony_ci	{
41962306a36Sopenharmony_ci		.desc = {
42062306a36Sopenharmony_ci			.name = "ldo4",
42162306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO4"),
42262306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
42362306a36Sopenharmony_ci			.id = PCA9450_LDO4,
42462306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
42562306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
42662306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
42762306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
42862306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
42962306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO4CTRL,
43062306a36Sopenharmony_ci			.vsel_mask = LDO4OUT_MASK,
43162306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO4CTRL,
43262306a36Sopenharmony_ci			.enable_mask = LDO4_EN_MASK,
43362306a36Sopenharmony_ci			.owner = THIS_MODULE,
43462306a36Sopenharmony_ci		},
43562306a36Sopenharmony_ci	},
43662306a36Sopenharmony_ci	{
43762306a36Sopenharmony_ci		.desc = {
43862306a36Sopenharmony_ci			.name = "ldo5",
43962306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO5"),
44062306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
44162306a36Sopenharmony_ci			.id = PCA9450_LDO5,
44262306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
44362306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
44462306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
44562306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo5_volts,
44662306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
44762306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
44862306a36Sopenharmony_ci			.vsel_mask = LDO5HOUT_MASK,
44962306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO5CTRL_H,
45062306a36Sopenharmony_ci			.enable_mask = LDO5H_EN_MASK,
45162306a36Sopenharmony_ci			.owner = THIS_MODULE,
45262306a36Sopenharmony_ci		},
45362306a36Sopenharmony_ci	},
45462306a36Sopenharmony_ci};
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci/*
45762306a36Sopenharmony_ci * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
45862306a36Sopenharmony_ci * on PCA9450C as no Buck3.
45962306a36Sopenharmony_ci */
46062306a36Sopenharmony_cistatic const struct pca9450_regulator_desc pca9450bc_regulators[] = {
46162306a36Sopenharmony_ci	{
46262306a36Sopenharmony_ci		.desc = {
46362306a36Sopenharmony_ci			.name = "buck1",
46462306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK1"),
46562306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
46662306a36Sopenharmony_ci			.id = PCA9450_BUCK1,
46762306a36Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
46862306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
46962306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
47062306a36Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
47162306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
47262306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
47362306a36Sopenharmony_ci			.vsel_mask = BUCK1OUT_DVS0_MASK,
47462306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK1CTRL,
47562306a36Sopenharmony_ci			.enable_mask = BUCK1_ENMODE_MASK,
47662306a36Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK1CTRL,
47762306a36Sopenharmony_ci			.ramp_mask = BUCK1_RAMP_MASK,
47862306a36Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
47962306a36Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
48062306a36Sopenharmony_ci			.owner = THIS_MODULE,
48162306a36Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
48262306a36Sopenharmony_ci		},
48362306a36Sopenharmony_ci		.dvs = {
48462306a36Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
48562306a36Sopenharmony_ci			.run_mask = BUCK1OUT_DVS0_MASK,
48662306a36Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
48762306a36Sopenharmony_ci			.standby_mask = BUCK1OUT_DVS1_MASK,
48862306a36Sopenharmony_ci		},
48962306a36Sopenharmony_ci	},
49062306a36Sopenharmony_ci	{
49162306a36Sopenharmony_ci		.desc = {
49262306a36Sopenharmony_ci			.name = "buck2",
49362306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK2"),
49462306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
49562306a36Sopenharmony_ci			.id = PCA9450_BUCK2,
49662306a36Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
49762306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
49862306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
49962306a36Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
50062306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
50162306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
50262306a36Sopenharmony_ci			.vsel_mask = BUCK2OUT_DVS0_MASK,
50362306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK2CTRL,
50462306a36Sopenharmony_ci			.enable_mask = BUCK2_ENMODE_MASK,
50562306a36Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK2CTRL,
50662306a36Sopenharmony_ci			.ramp_mask = BUCK2_RAMP_MASK,
50762306a36Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
50862306a36Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
50962306a36Sopenharmony_ci			.owner = THIS_MODULE,
51062306a36Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
51162306a36Sopenharmony_ci		},
51262306a36Sopenharmony_ci		.dvs = {
51362306a36Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
51462306a36Sopenharmony_ci			.run_mask = BUCK2OUT_DVS0_MASK,
51562306a36Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
51662306a36Sopenharmony_ci			.standby_mask = BUCK2OUT_DVS1_MASK,
51762306a36Sopenharmony_ci		},
51862306a36Sopenharmony_ci	},
51962306a36Sopenharmony_ci	{
52062306a36Sopenharmony_ci		.desc = {
52162306a36Sopenharmony_ci			.name = "buck4",
52262306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK4"),
52362306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
52462306a36Sopenharmony_ci			.id = PCA9450_BUCK4,
52562306a36Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
52662306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
52762306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
52862306a36Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
52962306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
53062306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK4OUT,
53162306a36Sopenharmony_ci			.vsel_mask = BUCK4OUT_MASK,
53262306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK4CTRL,
53362306a36Sopenharmony_ci			.enable_mask = BUCK4_ENMODE_MASK,
53462306a36Sopenharmony_ci			.owner = THIS_MODULE,
53562306a36Sopenharmony_ci		},
53662306a36Sopenharmony_ci	},
53762306a36Sopenharmony_ci	{
53862306a36Sopenharmony_ci		.desc = {
53962306a36Sopenharmony_ci			.name = "buck5",
54062306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK5"),
54162306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
54262306a36Sopenharmony_ci			.id = PCA9450_BUCK5,
54362306a36Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
54462306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
54562306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
54662306a36Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
54762306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
54862306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK5OUT,
54962306a36Sopenharmony_ci			.vsel_mask = BUCK5OUT_MASK,
55062306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK5CTRL,
55162306a36Sopenharmony_ci			.enable_mask = BUCK5_ENMODE_MASK,
55262306a36Sopenharmony_ci			.owner = THIS_MODULE,
55362306a36Sopenharmony_ci		},
55462306a36Sopenharmony_ci	},
55562306a36Sopenharmony_ci	{
55662306a36Sopenharmony_ci		.desc = {
55762306a36Sopenharmony_ci			.name = "buck6",
55862306a36Sopenharmony_ci			.of_match = of_match_ptr("BUCK6"),
55962306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
56062306a36Sopenharmony_ci			.id = PCA9450_BUCK6,
56162306a36Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
56262306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
56362306a36Sopenharmony_ci			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
56462306a36Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
56562306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
56662306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK6OUT,
56762306a36Sopenharmony_ci			.vsel_mask = BUCK6OUT_MASK,
56862306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK6CTRL,
56962306a36Sopenharmony_ci			.enable_mask = BUCK6_ENMODE_MASK,
57062306a36Sopenharmony_ci			.owner = THIS_MODULE,
57162306a36Sopenharmony_ci		},
57262306a36Sopenharmony_ci	},
57362306a36Sopenharmony_ci	{
57462306a36Sopenharmony_ci		.desc = {
57562306a36Sopenharmony_ci			.name = "ldo1",
57662306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO1"),
57762306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
57862306a36Sopenharmony_ci			.id = PCA9450_LDO1,
57962306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
58062306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
58162306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
58262306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo1_volts,
58362306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
58462306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO1CTRL,
58562306a36Sopenharmony_ci			.vsel_mask = LDO1OUT_MASK,
58662306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO1CTRL,
58762306a36Sopenharmony_ci			.enable_mask = LDO1_EN_MASK,
58862306a36Sopenharmony_ci			.owner = THIS_MODULE,
58962306a36Sopenharmony_ci		},
59062306a36Sopenharmony_ci	},
59162306a36Sopenharmony_ci	{
59262306a36Sopenharmony_ci		.desc = {
59362306a36Sopenharmony_ci			.name = "ldo2",
59462306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO2"),
59562306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
59662306a36Sopenharmony_ci			.id = PCA9450_LDO2,
59762306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
59862306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
59962306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
60062306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo2_volts,
60162306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
60262306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO2CTRL,
60362306a36Sopenharmony_ci			.vsel_mask = LDO2OUT_MASK,
60462306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO2CTRL,
60562306a36Sopenharmony_ci			.enable_mask = LDO2_EN_MASK,
60662306a36Sopenharmony_ci			.owner = THIS_MODULE,
60762306a36Sopenharmony_ci		},
60862306a36Sopenharmony_ci	},
60962306a36Sopenharmony_ci	{
61062306a36Sopenharmony_ci		.desc = {
61162306a36Sopenharmony_ci			.name = "ldo3",
61262306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO3"),
61362306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
61462306a36Sopenharmony_ci			.id = PCA9450_LDO3,
61562306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
61662306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
61762306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
61862306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
61962306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
62062306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO3CTRL,
62162306a36Sopenharmony_ci			.vsel_mask = LDO3OUT_MASK,
62262306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO3CTRL,
62362306a36Sopenharmony_ci			.enable_mask = LDO3_EN_MASK,
62462306a36Sopenharmony_ci			.owner = THIS_MODULE,
62562306a36Sopenharmony_ci		},
62662306a36Sopenharmony_ci	},
62762306a36Sopenharmony_ci	{
62862306a36Sopenharmony_ci		.desc = {
62962306a36Sopenharmony_ci			.name = "ldo4",
63062306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO4"),
63162306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
63262306a36Sopenharmony_ci			.id = PCA9450_LDO4,
63362306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
63462306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
63562306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
63662306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
63762306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
63862306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO4CTRL,
63962306a36Sopenharmony_ci			.vsel_mask = LDO4OUT_MASK,
64062306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO4CTRL,
64162306a36Sopenharmony_ci			.enable_mask = LDO4_EN_MASK,
64262306a36Sopenharmony_ci			.owner = THIS_MODULE,
64362306a36Sopenharmony_ci		},
64462306a36Sopenharmony_ci	},
64562306a36Sopenharmony_ci	{
64662306a36Sopenharmony_ci		.desc = {
64762306a36Sopenharmony_ci			.name = "ldo5",
64862306a36Sopenharmony_ci			.of_match = of_match_ptr("LDO5"),
64962306a36Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
65062306a36Sopenharmony_ci			.id = PCA9450_LDO5,
65162306a36Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
65262306a36Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
65362306a36Sopenharmony_ci			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
65462306a36Sopenharmony_ci			.linear_ranges = pca9450_ldo5_volts,
65562306a36Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
65662306a36Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
65762306a36Sopenharmony_ci			.vsel_mask = LDO5HOUT_MASK,
65862306a36Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO5CTRL_H,
65962306a36Sopenharmony_ci			.enable_mask = LDO5H_EN_MASK,
66062306a36Sopenharmony_ci			.owner = THIS_MODULE,
66162306a36Sopenharmony_ci		},
66262306a36Sopenharmony_ci	},
66362306a36Sopenharmony_ci};
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_cistatic irqreturn_t pca9450_irq_handler(int irq, void *data)
66662306a36Sopenharmony_ci{
66762306a36Sopenharmony_ci	struct pca9450 *pca9450 = data;
66862306a36Sopenharmony_ci	struct regmap *regmap = pca9450->regmap;
66962306a36Sopenharmony_ci	unsigned int status;
67062306a36Sopenharmony_ci	int ret;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
67362306a36Sopenharmony_ci	if (ret < 0) {
67462306a36Sopenharmony_ci		dev_err(pca9450->dev,
67562306a36Sopenharmony_ci			"Failed to read INT1(%d)\n", ret);
67662306a36Sopenharmony_ci		return IRQ_NONE;
67762306a36Sopenharmony_ci	}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	if (status & IRQ_PWRON)
68062306a36Sopenharmony_ci		dev_warn(pca9450->dev, "PWRON interrupt.\n");
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	if (status & IRQ_WDOGB)
68362306a36Sopenharmony_ci		dev_warn(pca9450->dev, "WDOGB interrupt.\n");
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci	if (status & IRQ_VR_FLT1)
68662306a36Sopenharmony_ci		dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	if (status & IRQ_VR_FLT2)
68962306a36Sopenharmony_ci		dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci	if (status & IRQ_LOWVSYS)
69262306a36Sopenharmony_ci		dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	if (status & IRQ_THERM_105)
69562306a36Sopenharmony_ci		dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	if (status & IRQ_THERM_125)
69862306a36Sopenharmony_ci		dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	return IRQ_HANDLED;
70162306a36Sopenharmony_ci}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_cistatic int pca9450_i2c_probe(struct i2c_client *i2c)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	enum pca9450_chip_type type = (unsigned int)(uintptr_t)
70662306a36Sopenharmony_ci				      of_device_get_match_data(&i2c->dev);
70762306a36Sopenharmony_ci	const struct pca9450_regulator_desc	*regulator_desc;
70862306a36Sopenharmony_ci	struct regulator_config config = { };
70962306a36Sopenharmony_ci	struct pca9450 *pca9450;
71062306a36Sopenharmony_ci	unsigned int device_id, i;
71162306a36Sopenharmony_ci	unsigned int reset_ctrl;
71262306a36Sopenharmony_ci	int ret;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	if (!i2c->irq) {
71562306a36Sopenharmony_ci		dev_err(&i2c->dev, "No IRQ configured?\n");
71662306a36Sopenharmony_ci		return -EINVAL;
71762306a36Sopenharmony_ci	}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
72062306a36Sopenharmony_ci	if (!pca9450)
72162306a36Sopenharmony_ci		return -ENOMEM;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	switch (type) {
72462306a36Sopenharmony_ci	case PCA9450_TYPE_PCA9450A:
72562306a36Sopenharmony_ci		regulator_desc = pca9450a_regulators;
72662306a36Sopenharmony_ci		pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
72762306a36Sopenharmony_ci		break;
72862306a36Sopenharmony_ci	case PCA9450_TYPE_PCA9450BC:
72962306a36Sopenharmony_ci		regulator_desc = pca9450bc_regulators;
73062306a36Sopenharmony_ci		pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
73162306a36Sopenharmony_ci		break;
73262306a36Sopenharmony_ci	default:
73362306a36Sopenharmony_ci		dev_err(&i2c->dev, "Unknown device type");
73462306a36Sopenharmony_ci		return -EINVAL;
73562306a36Sopenharmony_ci	}
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	pca9450->irq = i2c->irq;
73862306a36Sopenharmony_ci	pca9450->type = type;
73962306a36Sopenharmony_ci	pca9450->dev = &i2c->dev;
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci	dev_set_drvdata(&i2c->dev, pca9450);
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci	pca9450->regmap = devm_regmap_init_i2c(i2c,
74462306a36Sopenharmony_ci					       &pca9450_regmap_config);
74562306a36Sopenharmony_ci	if (IS_ERR(pca9450->regmap)) {
74662306a36Sopenharmony_ci		dev_err(&i2c->dev, "regmap initialization failed\n");
74762306a36Sopenharmony_ci		return PTR_ERR(pca9450->regmap);
74862306a36Sopenharmony_ci	}
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
75162306a36Sopenharmony_ci	if (ret) {
75262306a36Sopenharmony_ci		dev_err(&i2c->dev, "Read device id error\n");
75362306a36Sopenharmony_ci		return ret;
75462306a36Sopenharmony_ci	}
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	/* Check your board and dts for match the right pmic */
75762306a36Sopenharmony_ci	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
75862306a36Sopenharmony_ci	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
75962306a36Sopenharmony_ci		dev_err(&i2c->dev, "Device id(%x) mismatched\n",
76062306a36Sopenharmony_ci			device_id >> 4);
76162306a36Sopenharmony_ci		return -EINVAL;
76262306a36Sopenharmony_ci	}
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	for (i = 0; i < pca9450->rcnt; i++) {
76562306a36Sopenharmony_ci		const struct regulator_desc *desc;
76662306a36Sopenharmony_ci		struct regulator_dev *rdev;
76762306a36Sopenharmony_ci		const struct pca9450_regulator_desc *r;
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci		r = &regulator_desc[i];
77062306a36Sopenharmony_ci		desc = &r->desc;
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci		config.regmap = pca9450->regmap;
77362306a36Sopenharmony_ci		config.dev = pca9450->dev;
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci		rdev = devm_regulator_register(pca9450->dev, desc, &config);
77662306a36Sopenharmony_ci		if (IS_ERR(rdev)) {
77762306a36Sopenharmony_ci			ret = PTR_ERR(rdev);
77862306a36Sopenharmony_ci			dev_err(pca9450->dev,
77962306a36Sopenharmony_ci				"Failed to register regulator(%s): %d\n",
78062306a36Sopenharmony_ci				desc->name, ret);
78162306a36Sopenharmony_ci			return ret;
78262306a36Sopenharmony_ci		}
78362306a36Sopenharmony_ci	}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
78662306a36Sopenharmony_ci					pca9450_irq_handler,
78762306a36Sopenharmony_ci					(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
78862306a36Sopenharmony_ci					"pca9450-irq", pca9450);
78962306a36Sopenharmony_ci	if (ret != 0) {
79062306a36Sopenharmony_ci		dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
79162306a36Sopenharmony_ci			pca9450->irq);
79262306a36Sopenharmony_ci		return ret;
79362306a36Sopenharmony_ci	}
79462306a36Sopenharmony_ci	/* Unmask all interrupt except PWRON/WDOG/RSVD */
79562306a36Sopenharmony_ci	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
79662306a36Sopenharmony_ci				IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
79762306a36Sopenharmony_ci				IRQ_THERM_105 | IRQ_THERM_125,
79862306a36Sopenharmony_ci				IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
79962306a36Sopenharmony_ci	if (ret) {
80062306a36Sopenharmony_ci		dev_err(&i2c->dev, "Unmask irq error\n");
80162306a36Sopenharmony_ci		return ret;
80262306a36Sopenharmony_ci	}
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	/* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
80562306a36Sopenharmony_ci	ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
80662306a36Sopenharmony_ci				BUCK123_PRESET_EN);
80762306a36Sopenharmony_ci	if (ret) {
80862306a36Sopenharmony_ci		dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
80962306a36Sopenharmony_ci		return ret;
81062306a36Sopenharmony_ci	}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))
81362306a36Sopenharmony_ci		reset_ctrl = WDOG_B_CFG_WARM;
81462306a36Sopenharmony_ci	else
81562306a36Sopenharmony_ci		reset_ctrl = WDOG_B_CFG_COLD_LDO12;
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci	/* Set reset behavior on assertion of WDOG_B signal */
81862306a36Sopenharmony_ci	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
81962306a36Sopenharmony_ci				 WDOG_B_CFG_MASK, reset_ctrl);
82062306a36Sopenharmony_ci	if (ret) {
82162306a36Sopenharmony_ci		dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
82262306a36Sopenharmony_ci		return ret;
82362306a36Sopenharmony_ci	}
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {
82662306a36Sopenharmony_ci		/* Enable I2C Level Translator */
82762306a36Sopenharmony_ci		ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,
82862306a36Sopenharmony_ci					 I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);
82962306a36Sopenharmony_ci		if (ret) {
83062306a36Sopenharmony_ci			dev_err(&i2c->dev,
83162306a36Sopenharmony_ci				"Failed to enable I2C level translator\n");
83262306a36Sopenharmony_ci			return ret;
83362306a36Sopenharmony_ci		}
83462306a36Sopenharmony_ci	}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci	/*
83762306a36Sopenharmony_ci	 * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
83862306a36Sopenharmony_ci	 * This is only valid if the SD_VSEL input of the PMIC is high. Let's
83962306a36Sopenharmony_ci	 * check if the pin is available as GPIO and set it to high.
84062306a36Sopenharmony_ci	 */
84162306a36Sopenharmony_ci	pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci	if (IS_ERR(pca9450->sd_vsel_gpio)) {
84462306a36Sopenharmony_ci		dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
84562306a36Sopenharmony_ci		return PTR_ERR(pca9450->sd_vsel_gpio);
84662306a36Sopenharmony_ci	}
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	dev_info(&i2c->dev, "%s probed.\n",
84962306a36Sopenharmony_ci		type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ci	return 0;
85262306a36Sopenharmony_ci}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic const struct of_device_id pca9450_of_match[] = {
85562306a36Sopenharmony_ci	{
85662306a36Sopenharmony_ci		.compatible = "nxp,pca9450a",
85762306a36Sopenharmony_ci		.data = (void *)PCA9450_TYPE_PCA9450A,
85862306a36Sopenharmony_ci	},
85962306a36Sopenharmony_ci	{
86062306a36Sopenharmony_ci		.compatible = "nxp,pca9450b",
86162306a36Sopenharmony_ci		.data = (void *)PCA9450_TYPE_PCA9450BC,
86262306a36Sopenharmony_ci	},
86362306a36Sopenharmony_ci	{
86462306a36Sopenharmony_ci		.compatible = "nxp,pca9450c",
86562306a36Sopenharmony_ci		.data = (void *)PCA9450_TYPE_PCA9450BC,
86662306a36Sopenharmony_ci	},
86762306a36Sopenharmony_ci	{ }
86862306a36Sopenharmony_ci};
86962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, pca9450_of_match);
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_cistatic struct i2c_driver pca9450_i2c_driver = {
87262306a36Sopenharmony_ci	.driver = {
87362306a36Sopenharmony_ci		.name = "nxp-pca9450",
87462306a36Sopenharmony_ci		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
87562306a36Sopenharmony_ci		.of_match_table = pca9450_of_match,
87662306a36Sopenharmony_ci	},
87762306a36Sopenharmony_ci	.probe = pca9450_i2c_probe,
87862306a36Sopenharmony_ci};
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_cimodule_i2c_driver(pca9450_i2c_driver);
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ciMODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
88362306a36Sopenharmony_ciMODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
88462306a36Sopenharmony_ciMODULE_LICENSE("GPL");
885