18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2020 NXP.
48c2ecf20Sopenharmony_ci * NXP PCA9450 pmic driver
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/err.h>
88c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h>
98c2ecf20Sopenharmony_ci#include <linux/i2c.h>
108c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/module.h>
138c2ecf20Sopenharmony_ci#include <linux/of.h>
148c2ecf20Sopenharmony_ci#include <linux/of_device.h>
158c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
168c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h>
178c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h>
188c2ecf20Sopenharmony_ci#include <linux/regulator/of_regulator.h>
198c2ecf20Sopenharmony_ci#include <linux/regulator/pca9450.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistruct pc9450_dvs_config {
228c2ecf20Sopenharmony_ci	unsigned int run_reg; /* dvs0 */
238c2ecf20Sopenharmony_ci	unsigned int run_mask;
248c2ecf20Sopenharmony_ci	unsigned int standby_reg; /* dvs1 */
258c2ecf20Sopenharmony_ci	unsigned int standby_mask;
268c2ecf20Sopenharmony_ci};
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistruct pca9450_regulator_desc {
298c2ecf20Sopenharmony_ci	struct regulator_desc desc;
308c2ecf20Sopenharmony_ci	const struct pc9450_dvs_config dvs;
318c2ecf20Sopenharmony_ci};
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistruct pca9450 {
348c2ecf20Sopenharmony_ci	struct device *dev;
358c2ecf20Sopenharmony_ci	struct regmap *regmap;
368c2ecf20Sopenharmony_ci	struct gpio_desc *sd_vsel_gpio;
378c2ecf20Sopenharmony_ci	enum pca9450_chip_type type;
388c2ecf20Sopenharmony_ci	unsigned int rcnt;
398c2ecf20Sopenharmony_ci	int irq;
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic const struct regmap_range pca9450_status_range = {
438c2ecf20Sopenharmony_ci	.range_min = PCA9450_REG_INT1,
448c2ecf20Sopenharmony_ci	.range_max = PCA9450_REG_PWRON_STAT,
458c2ecf20Sopenharmony_ci};
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistatic const struct regmap_access_table pca9450_volatile_regs = {
488c2ecf20Sopenharmony_ci	.yes_ranges = &pca9450_status_range,
498c2ecf20Sopenharmony_ci	.n_yes_ranges = 1,
508c2ecf20Sopenharmony_ci};
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic const struct regmap_config pca9450_regmap_config = {
538c2ecf20Sopenharmony_ci	.reg_bits = 8,
548c2ecf20Sopenharmony_ci	.val_bits = 8,
558c2ecf20Sopenharmony_ci	.volatile_table = &pca9450_volatile_regs,
568c2ecf20Sopenharmony_ci	.max_register = PCA9450_MAX_REGISTER - 1,
578c2ecf20Sopenharmony_ci	.cache_type = REGCACHE_RBTREE,
588c2ecf20Sopenharmony_ci};
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/*
618c2ecf20Sopenharmony_ci * BUCK1/2/3
628c2ecf20Sopenharmony_ci * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
638c2ecf20Sopenharmony_ci * 00: 25mV/1usec
648c2ecf20Sopenharmony_ci * 01: 25mV/2usec
658c2ecf20Sopenharmony_ci * 10: 25mV/4usec
668c2ecf20Sopenharmony_ci * 11: 25mV/8usec
678c2ecf20Sopenharmony_ci */
688c2ecf20Sopenharmony_cistatic const unsigned int pca9450_dvs_buck_ramp_table[] = {
698c2ecf20Sopenharmony_ci	25000, 12500, 6250, 3125
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
738c2ecf20Sopenharmony_ci	.enable = regulator_enable_regmap,
748c2ecf20Sopenharmony_ci	.disable = regulator_disable_regmap,
758c2ecf20Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
768c2ecf20Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear_range,
778c2ecf20Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
788c2ecf20Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
798c2ecf20Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
808c2ecf20Sopenharmony_ci	.set_ramp_delay	= regulator_set_ramp_delay_regmap,
818c2ecf20Sopenharmony_ci};
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic const struct regulator_ops pca9450_buck_regulator_ops = {
848c2ecf20Sopenharmony_ci	.enable = regulator_enable_regmap,
858c2ecf20Sopenharmony_ci	.disable = regulator_disable_regmap,
868c2ecf20Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
878c2ecf20Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear_range,
888c2ecf20Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
898c2ecf20Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
908c2ecf20Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
918c2ecf20Sopenharmony_ci};
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_cistatic const struct regulator_ops pca9450_ldo_regulator_ops = {
948c2ecf20Sopenharmony_ci	.enable = regulator_enable_regmap,
958c2ecf20Sopenharmony_ci	.disable = regulator_disable_regmap,
968c2ecf20Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
978c2ecf20Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear_range,
988c2ecf20Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
998c2ecf20Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
1008c2ecf20Sopenharmony_ci};
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/*
1038c2ecf20Sopenharmony_ci * BUCK1/2/3
1048c2ecf20Sopenharmony_ci * 0.60 to 2.1875V (12.5mV step)
1058c2ecf20Sopenharmony_ci */
1068c2ecf20Sopenharmony_cistatic const struct linear_range pca9450_dvs_buck_volts[] = {
1078c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(600000,  0x00, 0x7F, 12500),
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci/*
1118c2ecf20Sopenharmony_ci * BUCK4/5/6
1128c2ecf20Sopenharmony_ci * 0.6V to 3.4V (25mV step)
1138c2ecf20Sopenharmony_ci */
1148c2ecf20Sopenharmony_cistatic const struct linear_range pca9450_buck_volts[] = {
1158c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
1168c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
1178c2ecf20Sopenharmony_ci};
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/*
1208c2ecf20Sopenharmony_ci * LDO1
1218c2ecf20Sopenharmony_ci * 1.6 to 3.3V ()
1228c2ecf20Sopenharmony_ci */
1238c2ecf20Sopenharmony_cistatic const struct linear_range pca9450_ldo1_volts[] = {
1248c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
1258c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
1268c2ecf20Sopenharmony_ci};
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci/*
1298c2ecf20Sopenharmony_ci * LDO2
1308c2ecf20Sopenharmony_ci * 0.8 to 1.15V (50mV step)
1318c2ecf20Sopenharmony_ci */
1328c2ecf20Sopenharmony_cistatic const struct linear_range pca9450_ldo2_volts[] = {
1338c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/*
1378c2ecf20Sopenharmony_ci * LDO3/4
1388c2ecf20Sopenharmony_ci * 0.8 to 3.3V (100mV step)
1398c2ecf20Sopenharmony_ci */
1408c2ecf20Sopenharmony_cistatic const struct linear_range pca9450_ldo34_volts[] = {
1418c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
1428c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
1438c2ecf20Sopenharmony_ci};
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci/*
1468c2ecf20Sopenharmony_ci * LDO5
1478c2ecf20Sopenharmony_ci * 1.8 to 3.3V (100mV step)
1488c2ecf20Sopenharmony_ci */
1498c2ecf20Sopenharmony_cistatic const struct linear_range pca9450_ldo5_volts[] = {
1508c2ecf20Sopenharmony_ci	REGULATOR_LINEAR_RANGE(1800000,  0x00, 0x0F, 100000),
1518c2ecf20Sopenharmony_ci};
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic int buck_set_dvs(const struct regulator_desc *desc,
1548c2ecf20Sopenharmony_ci			struct device_node *np, struct regmap *regmap,
1558c2ecf20Sopenharmony_ci			char *prop, unsigned int reg, unsigned int mask)
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	int ret, i;
1588c2ecf20Sopenharmony_ci	uint32_t uv;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	ret = of_property_read_u32(np, prop, &uv);
1618c2ecf20Sopenharmony_ci	if (ret == -EINVAL)
1628c2ecf20Sopenharmony_ci		return 0;
1638c2ecf20Sopenharmony_ci	else if (ret)
1648c2ecf20Sopenharmony_ci		return ret;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	for (i = 0; i < desc->n_voltages; i++) {
1678c2ecf20Sopenharmony_ci		ret = regulator_desc_list_voltage_linear_range(desc, i);
1688c2ecf20Sopenharmony_ci		if (ret < 0)
1698c2ecf20Sopenharmony_ci			continue;
1708c2ecf20Sopenharmony_ci		if (ret == uv) {
1718c2ecf20Sopenharmony_ci			i <<= ffs(desc->vsel_mask) - 1;
1728c2ecf20Sopenharmony_ci			ret = regmap_update_bits(regmap, reg, mask, i);
1738c2ecf20Sopenharmony_ci			break;
1748c2ecf20Sopenharmony_ci		}
1758c2ecf20Sopenharmony_ci	}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	return ret;
1788c2ecf20Sopenharmony_ci}
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_cistatic int pca9450_set_dvs_levels(struct device_node *np,
1818c2ecf20Sopenharmony_ci			    const struct regulator_desc *desc,
1828c2ecf20Sopenharmony_ci			    struct regulator_config *cfg)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	struct pca9450_regulator_desc *data = container_of(desc,
1858c2ecf20Sopenharmony_ci					struct pca9450_regulator_desc, desc);
1868c2ecf20Sopenharmony_ci	const struct pc9450_dvs_config *dvs = &data->dvs;
1878c2ecf20Sopenharmony_ci	unsigned int reg, mask;
1888c2ecf20Sopenharmony_ci	char *prop;
1898c2ecf20Sopenharmony_ci	int i, ret = 0;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
1928c2ecf20Sopenharmony_ci		switch (i) {
1938c2ecf20Sopenharmony_ci		case PCA9450_DVS_LEVEL_RUN:
1948c2ecf20Sopenharmony_ci			prop = "nxp,dvs-run-voltage";
1958c2ecf20Sopenharmony_ci			reg = dvs->run_reg;
1968c2ecf20Sopenharmony_ci			mask = dvs->run_mask;
1978c2ecf20Sopenharmony_ci			break;
1988c2ecf20Sopenharmony_ci		case PCA9450_DVS_LEVEL_STANDBY:
1998c2ecf20Sopenharmony_ci			prop = "nxp,dvs-standby-voltage";
2008c2ecf20Sopenharmony_ci			reg = dvs->standby_reg;
2018c2ecf20Sopenharmony_ci			mask = dvs->standby_mask;
2028c2ecf20Sopenharmony_ci			break;
2038c2ecf20Sopenharmony_ci		default:
2048c2ecf20Sopenharmony_ci			return -EINVAL;
2058c2ecf20Sopenharmony_ci		}
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci		ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
2088c2ecf20Sopenharmony_ci		if (ret)
2098c2ecf20Sopenharmony_ci			break;
2108c2ecf20Sopenharmony_ci	}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	return ret;
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistatic const struct pca9450_regulator_desc pca9450a_regulators[] = {
2168c2ecf20Sopenharmony_ci	{
2178c2ecf20Sopenharmony_ci		.desc = {
2188c2ecf20Sopenharmony_ci			.name = "buck1",
2198c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK1"),
2208c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
2218c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK1,
2228c2ecf20Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
2238c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
2248c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
2258c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
2268c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
2278c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
2288c2ecf20Sopenharmony_ci			.vsel_mask = BUCK1OUT_DVS0_MASK,
2298c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK1CTRL,
2308c2ecf20Sopenharmony_ci			.enable_mask = BUCK1_ENMODE_MASK,
2318c2ecf20Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK1CTRL,
2328c2ecf20Sopenharmony_ci			.ramp_mask = BUCK1_RAMP_MASK,
2338c2ecf20Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
2348c2ecf20Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
2358c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
2368c2ecf20Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
2378c2ecf20Sopenharmony_ci		},
2388c2ecf20Sopenharmony_ci		.dvs = {
2398c2ecf20Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
2408c2ecf20Sopenharmony_ci			.run_mask = BUCK1OUT_DVS0_MASK,
2418c2ecf20Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
2428c2ecf20Sopenharmony_ci			.standby_mask = BUCK1OUT_DVS1_MASK,
2438c2ecf20Sopenharmony_ci		},
2448c2ecf20Sopenharmony_ci	},
2458c2ecf20Sopenharmony_ci	{
2468c2ecf20Sopenharmony_ci		.desc = {
2478c2ecf20Sopenharmony_ci			.name = "buck2",
2488c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK2"),
2498c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
2508c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK2,
2518c2ecf20Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
2528c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
2538c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
2548c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
2558c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
2568c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
2578c2ecf20Sopenharmony_ci			.vsel_mask = BUCK2OUT_DVS0_MASK,
2588c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK2CTRL,
2598c2ecf20Sopenharmony_ci			.enable_mask = BUCK2_ENMODE_MASK,
2608c2ecf20Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK2CTRL,
2618c2ecf20Sopenharmony_ci			.ramp_mask = BUCK2_RAMP_MASK,
2628c2ecf20Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
2638c2ecf20Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
2648c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
2658c2ecf20Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
2668c2ecf20Sopenharmony_ci		},
2678c2ecf20Sopenharmony_ci		.dvs = {
2688c2ecf20Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
2698c2ecf20Sopenharmony_ci			.run_mask = BUCK2OUT_DVS0_MASK,
2708c2ecf20Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
2718c2ecf20Sopenharmony_ci			.standby_mask = BUCK2OUT_DVS1_MASK,
2728c2ecf20Sopenharmony_ci		},
2738c2ecf20Sopenharmony_ci	},
2748c2ecf20Sopenharmony_ci	{
2758c2ecf20Sopenharmony_ci		.desc = {
2768c2ecf20Sopenharmony_ci			.name = "buck3",
2778c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK3"),
2788c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
2798c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK3,
2808c2ecf20Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
2818c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
2828c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
2838c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
2848c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
2858c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
2868c2ecf20Sopenharmony_ci			.vsel_mask = BUCK3OUT_DVS0_MASK,
2878c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK3CTRL,
2888c2ecf20Sopenharmony_ci			.enable_mask = BUCK3_ENMODE_MASK,
2898c2ecf20Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK3CTRL,
2908c2ecf20Sopenharmony_ci			.ramp_mask = BUCK3_RAMP_MASK,
2918c2ecf20Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
2928c2ecf20Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
2938c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
2948c2ecf20Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
2958c2ecf20Sopenharmony_ci		},
2968c2ecf20Sopenharmony_ci		.dvs = {
2978c2ecf20Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
2988c2ecf20Sopenharmony_ci			.run_mask = BUCK3OUT_DVS0_MASK,
2998c2ecf20Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
3008c2ecf20Sopenharmony_ci			.standby_mask = BUCK3OUT_DVS1_MASK,
3018c2ecf20Sopenharmony_ci		},
3028c2ecf20Sopenharmony_ci	},
3038c2ecf20Sopenharmony_ci	{
3048c2ecf20Sopenharmony_ci		.desc = {
3058c2ecf20Sopenharmony_ci			.name = "buck4",
3068c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK4"),
3078c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
3088c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK4,
3098c2ecf20Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
3108c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
3118c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
3128c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
3138c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
3148c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK4OUT,
3158c2ecf20Sopenharmony_ci			.vsel_mask = BUCK4OUT_MASK,
3168c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK4CTRL,
3178c2ecf20Sopenharmony_ci			.enable_mask = BUCK4_ENMODE_MASK,
3188c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
3198c2ecf20Sopenharmony_ci		},
3208c2ecf20Sopenharmony_ci	},
3218c2ecf20Sopenharmony_ci	{
3228c2ecf20Sopenharmony_ci		.desc = {
3238c2ecf20Sopenharmony_ci			.name = "buck5",
3248c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK5"),
3258c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
3268c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK5,
3278c2ecf20Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
3288c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
3298c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
3308c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
3318c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
3328c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK5OUT,
3338c2ecf20Sopenharmony_ci			.vsel_mask = BUCK5OUT_MASK,
3348c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK5CTRL,
3358c2ecf20Sopenharmony_ci			.enable_mask = BUCK5_ENMODE_MASK,
3368c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
3378c2ecf20Sopenharmony_ci		},
3388c2ecf20Sopenharmony_ci	},
3398c2ecf20Sopenharmony_ci	{
3408c2ecf20Sopenharmony_ci		.desc = {
3418c2ecf20Sopenharmony_ci			.name = "buck6",
3428c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK6"),
3438c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
3448c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK6,
3458c2ecf20Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
3468c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
3478c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
3488c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
3498c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
3508c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK6OUT,
3518c2ecf20Sopenharmony_ci			.vsel_mask = BUCK6OUT_MASK,
3528c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK6CTRL,
3538c2ecf20Sopenharmony_ci			.enable_mask = BUCK6_ENMODE_MASK,
3548c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
3558c2ecf20Sopenharmony_ci		},
3568c2ecf20Sopenharmony_ci	},
3578c2ecf20Sopenharmony_ci	{
3588c2ecf20Sopenharmony_ci		.desc = {
3598c2ecf20Sopenharmony_ci			.name = "ldo1",
3608c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO1"),
3618c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
3628c2ecf20Sopenharmony_ci			.id = PCA9450_LDO1,
3638c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
3648c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
3658c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
3668c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo1_volts,
3678c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
3688c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO1CTRL,
3698c2ecf20Sopenharmony_ci			.vsel_mask = LDO1OUT_MASK,
3708c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO1CTRL,
3718c2ecf20Sopenharmony_ci			.enable_mask = LDO1_EN_MASK,
3728c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
3738c2ecf20Sopenharmony_ci		},
3748c2ecf20Sopenharmony_ci	},
3758c2ecf20Sopenharmony_ci	{
3768c2ecf20Sopenharmony_ci		.desc = {
3778c2ecf20Sopenharmony_ci			.name = "ldo2",
3788c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO2"),
3798c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
3808c2ecf20Sopenharmony_ci			.id = PCA9450_LDO2,
3818c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
3828c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
3838c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
3848c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo2_volts,
3858c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
3868c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO2CTRL,
3878c2ecf20Sopenharmony_ci			.vsel_mask = LDO2OUT_MASK,
3888c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO2CTRL,
3898c2ecf20Sopenharmony_ci			.enable_mask = LDO2_EN_MASK,
3908c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
3918c2ecf20Sopenharmony_ci		},
3928c2ecf20Sopenharmony_ci	},
3938c2ecf20Sopenharmony_ci	{
3948c2ecf20Sopenharmony_ci		.desc = {
3958c2ecf20Sopenharmony_ci			.name = "ldo3",
3968c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO3"),
3978c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
3988c2ecf20Sopenharmony_ci			.id = PCA9450_LDO3,
3998c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
4008c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
4018c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
4028c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
4038c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
4048c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO3CTRL,
4058c2ecf20Sopenharmony_ci			.vsel_mask = LDO3OUT_MASK,
4068c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO3CTRL,
4078c2ecf20Sopenharmony_ci			.enable_mask = LDO3_EN_MASK,
4088c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
4098c2ecf20Sopenharmony_ci		},
4108c2ecf20Sopenharmony_ci	},
4118c2ecf20Sopenharmony_ci	{
4128c2ecf20Sopenharmony_ci		.desc = {
4138c2ecf20Sopenharmony_ci			.name = "ldo4",
4148c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO4"),
4158c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
4168c2ecf20Sopenharmony_ci			.id = PCA9450_LDO4,
4178c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
4188c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
4198c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
4208c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
4218c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
4228c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO4CTRL,
4238c2ecf20Sopenharmony_ci			.vsel_mask = LDO4OUT_MASK,
4248c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO4CTRL,
4258c2ecf20Sopenharmony_ci			.enable_mask = LDO4_EN_MASK,
4268c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
4278c2ecf20Sopenharmony_ci		},
4288c2ecf20Sopenharmony_ci	},
4298c2ecf20Sopenharmony_ci	{
4308c2ecf20Sopenharmony_ci		.desc = {
4318c2ecf20Sopenharmony_ci			.name = "ldo5",
4328c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO5"),
4338c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
4348c2ecf20Sopenharmony_ci			.id = PCA9450_LDO5,
4358c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
4368c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
4378c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
4388c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo5_volts,
4398c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
4408c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
4418c2ecf20Sopenharmony_ci			.vsel_mask = LDO5HOUT_MASK,
4428c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO5CTRL_H,
4438c2ecf20Sopenharmony_ci			.enable_mask = LDO5H_EN_MASK,
4448c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
4458c2ecf20Sopenharmony_ci		},
4468c2ecf20Sopenharmony_ci	},
4478c2ecf20Sopenharmony_ci};
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci/*
4508c2ecf20Sopenharmony_ci * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
4518c2ecf20Sopenharmony_ci * on PCA9450C as no Buck3.
4528c2ecf20Sopenharmony_ci */
4538c2ecf20Sopenharmony_cistatic const struct pca9450_regulator_desc pca9450bc_regulators[] = {
4548c2ecf20Sopenharmony_ci	{
4558c2ecf20Sopenharmony_ci		.desc = {
4568c2ecf20Sopenharmony_ci			.name = "buck1",
4578c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK1"),
4588c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
4598c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK1,
4608c2ecf20Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
4618c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
4628c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
4638c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
4648c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
4658c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
4668c2ecf20Sopenharmony_ci			.vsel_mask = BUCK1OUT_DVS0_MASK,
4678c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK1CTRL,
4688c2ecf20Sopenharmony_ci			.enable_mask = BUCK1_ENMODE_MASK,
4698c2ecf20Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK1CTRL,
4708c2ecf20Sopenharmony_ci			.ramp_mask = BUCK1_RAMP_MASK,
4718c2ecf20Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
4728c2ecf20Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
4738c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
4748c2ecf20Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
4758c2ecf20Sopenharmony_ci		},
4768c2ecf20Sopenharmony_ci		.dvs = {
4778c2ecf20Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
4788c2ecf20Sopenharmony_ci			.run_mask = BUCK1OUT_DVS0_MASK,
4798c2ecf20Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
4808c2ecf20Sopenharmony_ci			.standby_mask = BUCK1OUT_DVS1_MASK,
4818c2ecf20Sopenharmony_ci		},
4828c2ecf20Sopenharmony_ci	},
4838c2ecf20Sopenharmony_ci	{
4848c2ecf20Sopenharmony_ci		.desc = {
4858c2ecf20Sopenharmony_ci			.name = "buck2",
4868c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK2"),
4878c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
4888c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK2,
4898c2ecf20Sopenharmony_ci			.ops = &pca9450_dvs_buck_regulator_ops,
4908c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
4918c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
4928c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_dvs_buck_volts,
4938c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
4948c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
4958c2ecf20Sopenharmony_ci			.vsel_mask = BUCK2OUT_DVS0_MASK,
4968c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK2CTRL,
4978c2ecf20Sopenharmony_ci			.enable_mask = BUCK2_ENMODE_MASK,
4988c2ecf20Sopenharmony_ci			.ramp_reg = PCA9450_REG_BUCK2CTRL,
4998c2ecf20Sopenharmony_ci			.ramp_mask = BUCK2_RAMP_MASK,
5008c2ecf20Sopenharmony_ci			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
5018c2ecf20Sopenharmony_ci			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
5028c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
5038c2ecf20Sopenharmony_ci			.of_parse_cb = pca9450_set_dvs_levels,
5048c2ecf20Sopenharmony_ci		},
5058c2ecf20Sopenharmony_ci		.dvs = {
5068c2ecf20Sopenharmony_ci			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
5078c2ecf20Sopenharmony_ci			.run_mask = BUCK2OUT_DVS0_MASK,
5088c2ecf20Sopenharmony_ci			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
5098c2ecf20Sopenharmony_ci			.standby_mask = BUCK2OUT_DVS1_MASK,
5108c2ecf20Sopenharmony_ci		},
5118c2ecf20Sopenharmony_ci	},
5128c2ecf20Sopenharmony_ci	{
5138c2ecf20Sopenharmony_ci		.desc = {
5148c2ecf20Sopenharmony_ci			.name = "buck4",
5158c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK4"),
5168c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
5178c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK4,
5188c2ecf20Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
5198c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
5208c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
5218c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
5228c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
5238c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK4OUT,
5248c2ecf20Sopenharmony_ci			.vsel_mask = BUCK4OUT_MASK,
5258c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK4CTRL,
5268c2ecf20Sopenharmony_ci			.enable_mask = BUCK4_ENMODE_MASK,
5278c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
5288c2ecf20Sopenharmony_ci		},
5298c2ecf20Sopenharmony_ci	},
5308c2ecf20Sopenharmony_ci	{
5318c2ecf20Sopenharmony_ci		.desc = {
5328c2ecf20Sopenharmony_ci			.name = "buck5",
5338c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK5"),
5348c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
5358c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK5,
5368c2ecf20Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
5378c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
5388c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
5398c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
5408c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
5418c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK5OUT,
5428c2ecf20Sopenharmony_ci			.vsel_mask = BUCK5OUT_MASK,
5438c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK5CTRL,
5448c2ecf20Sopenharmony_ci			.enable_mask = BUCK5_ENMODE_MASK,
5458c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
5468c2ecf20Sopenharmony_ci		},
5478c2ecf20Sopenharmony_ci	},
5488c2ecf20Sopenharmony_ci	{
5498c2ecf20Sopenharmony_ci		.desc = {
5508c2ecf20Sopenharmony_ci			.name = "buck6",
5518c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("BUCK6"),
5528c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
5538c2ecf20Sopenharmony_ci			.id = PCA9450_BUCK6,
5548c2ecf20Sopenharmony_ci			.ops = &pca9450_buck_regulator_ops,
5558c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
5568c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
5578c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_buck_volts,
5588c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
5598c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_BUCK6OUT,
5608c2ecf20Sopenharmony_ci			.vsel_mask = BUCK6OUT_MASK,
5618c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_BUCK6CTRL,
5628c2ecf20Sopenharmony_ci			.enable_mask = BUCK6_ENMODE_MASK,
5638c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
5648c2ecf20Sopenharmony_ci		},
5658c2ecf20Sopenharmony_ci	},
5668c2ecf20Sopenharmony_ci	{
5678c2ecf20Sopenharmony_ci		.desc = {
5688c2ecf20Sopenharmony_ci			.name = "ldo1",
5698c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO1"),
5708c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
5718c2ecf20Sopenharmony_ci			.id = PCA9450_LDO1,
5728c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
5738c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
5748c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
5758c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo1_volts,
5768c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
5778c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO1CTRL,
5788c2ecf20Sopenharmony_ci			.vsel_mask = LDO1OUT_MASK,
5798c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO1CTRL,
5808c2ecf20Sopenharmony_ci			.enable_mask = LDO1_EN_MASK,
5818c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
5828c2ecf20Sopenharmony_ci		},
5838c2ecf20Sopenharmony_ci	},
5848c2ecf20Sopenharmony_ci	{
5858c2ecf20Sopenharmony_ci		.desc = {
5868c2ecf20Sopenharmony_ci			.name = "ldo2",
5878c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO2"),
5888c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
5898c2ecf20Sopenharmony_ci			.id = PCA9450_LDO2,
5908c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
5918c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
5928c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
5938c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo2_volts,
5948c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
5958c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO2CTRL,
5968c2ecf20Sopenharmony_ci			.vsel_mask = LDO2OUT_MASK,
5978c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO2CTRL,
5988c2ecf20Sopenharmony_ci			.enable_mask = LDO2_EN_MASK,
5998c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
6008c2ecf20Sopenharmony_ci		},
6018c2ecf20Sopenharmony_ci	},
6028c2ecf20Sopenharmony_ci	{
6038c2ecf20Sopenharmony_ci		.desc = {
6048c2ecf20Sopenharmony_ci			.name = "ldo3",
6058c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO3"),
6068c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
6078c2ecf20Sopenharmony_ci			.id = PCA9450_LDO3,
6088c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
6098c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
6108c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
6118c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
6128c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
6138c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO3CTRL,
6148c2ecf20Sopenharmony_ci			.vsel_mask = LDO3OUT_MASK,
6158c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO3CTRL,
6168c2ecf20Sopenharmony_ci			.enable_mask = LDO3_EN_MASK,
6178c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
6188c2ecf20Sopenharmony_ci		},
6198c2ecf20Sopenharmony_ci	},
6208c2ecf20Sopenharmony_ci	{
6218c2ecf20Sopenharmony_ci		.desc = {
6228c2ecf20Sopenharmony_ci			.name = "ldo4",
6238c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO4"),
6248c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
6258c2ecf20Sopenharmony_ci			.id = PCA9450_LDO4,
6268c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
6278c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
6288c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
6298c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo34_volts,
6308c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
6318c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO4CTRL,
6328c2ecf20Sopenharmony_ci			.vsel_mask = LDO4OUT_MASK,
6338c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO4CTRL,
6348c2ecf20Sopenharmony_ci			.enable_mask = LDO4_EN_MASK,
6358c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
6368c2ecf20Sopenharmony_ci		},
6378c2ecf20Sopenharmony_ci	},
6388c2ecf20Sopenharmony_ci	{
6398c2ecf20Sopenharmony_ci		.desc = {
6408c2ecf20Sopenharmony_ci			.name = "ldo5",
6418c2ecf20Sopenharmony_ci			.of_match = of_match_ptr("LDO5"),
6428c2ecf20Sopenharmony_ci			.regulators_node = of_match_ptr("regulators"),
6438c2ecf20Sopenharmony_ci			.id = PCA9450_LDO5,
6448c2ecf20Sopenharmony_ci			.ops = &pca9450_ldo_regulator_ops,
6458c2ecf20Sopenharmony_ci			.type = REGULATOR_VOLTAGE,
6468c2ecf20Sopenharmony_ci			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
6478c2ecf20Sopenharmony_ci			.linear_ranges = pca9450_ldo5_volts,
6488c2ecf20Sopenharmony_ci			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
6498c2ecf20Sopenharmony_ci			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
6508c2ecf20Sopenharmony_ci			.vsel_mask = LDO5HOUT_MASK,
6518c2ecf20Sopenharmony_ci			.enable_reg = PCA9450_REG_LDO5CTRL_H,
6528c2ecf20Sopenharmony_ci			.enable_mask = LDO5H_EN_MASK,
6538c2ecf20Sopenharmony_ci			.owner = THIS_MODULE,
6548c2ecf20Sopenharmony_ci		},
6558c2ecf20Sopenharmony_ci	},
6568c2ecf20Sopenharmony_ci};
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_cistatic irqreturn_t pca9450_irq_handler(int irq, void *data)
6598c2ecf20Sopenharmony_ci{
6608c2ecf20Sopenharmony_ci	struct pca9450 *pca9450 = data;
6618c2ecf20Sopenharmony_ci	struct regmap *regmap = pca9450->regmap;
6628c2ecf20Sopenharmony_ci	unsigned int status;
6638c2ecf20Sopenharmony_ci	int ret;
6648c2ecf20Sopenharmony_ci
6658c2ecf20Sopenharmony_ci	ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
6668c2ecf20Sopenharmony_ci	if (ret < 0) {
6678c2ecf20Sopenharmony_ci		dev_err(pca9450->dev,
6688c2ecf20Sopenharmony_ci			"Failed to read INT1(%d)\n", ret);
6698c2ecf20Sopenharmony_ci		return IRQ_NONE;
6708c2ecf20Sopenharmony_ci	}
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci	if (status & IRQ_PWRON)
6738c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "PWRON interrupt.\n");
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci	if (status & IRQ_WDOGB)
6768c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "WDOGB interrupt.\n");
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci	if (status & IRQ_VR_FLT1)
6798c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	if (status & IRQ_VR_FLT2)
6828c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci	if (status & IRQ_LOWVSYS)
6858c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci	if (status & IRQ_THERM_105)
6888c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
6898c2ecf20Sopenharmony_ci
6908c2ecf20Sopenharmony_ci	if (status & IRQ_THERM_125)
6918c2ecf20Sopenharmony_ci		dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
6948c2ecf20Sopenharmony_ci}
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_cistatic int pca9450_i2c_probe(struct i2c_client *i2c,
6978c2ecf20Sopenharmony_ci			     const struct i2c_device_id *id)
6988c2ecf20Sopenharmony_ci{
6998c2ecf20Sopenharmony_ci	enum pca9450_chip_type type = (unsigned int)(uintptr_t)
7008c2ecf20Sopenharmony_ci				      of_device_get_match_data(&i2c->dev);
7018c2ecf20Sopenharmony_ci	const struct pca9450_regulator_desc	*regulator_desc;
7028c2ecf20Sopenharmony_ci	struct regulator_config config = { };
7038c2ecf20Sopenharmony_ci	struct pca9450 *pca9450;
7048c2ecf20Sopenharmony_ci	unsigned int device_id, i;
7058c2ecf20Sopenharmony_ci	int ret;
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci	if (!i2c->irq) {
7088c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "No IRQ configured?\n");
7098c2ecf20Sopenharmony_ci		return -EINVAL;
7108c2ecf20Sopenharmony_ci	}
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci	pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
7138c2ecf20Sopenharmony_ci	if (!pca9450)
7148c2ecf20Sopenharmony_ci		return -ENOMEM;
7158c2ecf20Sopenharmony_ci
7168c2ecf20Sopenharmony_ci	switch (type) {
7178c2ecf20Sopenharmony_ci	case PCA9450_TYPE_PCA9450A:
7188c2ecf20Sopenharmony_ci		regulator_desc = pca9450a_regulators;
7198c2ecf20Sopenharmony_ci		pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
7208c2ecf20Sopenharmony_ci		break;
7218c2ecf20Sopenharmony_ci	case PCA9450_TYPE_PCA9450BC:
7228c2ecf20Sopenharmony_ci		regulator_desc = pca9450bc_regulators;
7238c2ecf20Sopenharmony_ci		pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
7248c2ecf20Sopenharmony_ci		break;
7258c2ecf20Sopenharmony_ci	default:
7268c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Unknown device type");
7278c2ecf20Sopenharmony_ci		return -EINVAL;
7288c2ecf20Sopenharmony_ci	}
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_ci	pca9450->irq = i2c->irq;
7318c2ecf20Sopenharmony_ci	pca9450->type = type;
7328c2ecf20Sopenharmony_ci	pca9450->dev = &i2c->dev;
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci	dev_set_drvdata(&i2c->dev, pca9450);
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_ci	pca9450->regmap = devm_regmap_init_i2c(i2c,
7378c2ecf20Sopenharmony_ci					       &pca9450_regmap_config);
7388c2ecf20Sopenharmony_ci	if (IS_ERR(pca9450->regmap)) {
7398c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "regmap initialization failed\n");
7408c2ecf20Sopenharmony_ci		return PTR_ERR(pca9450->regmap);
7418c2ecf20Sopenharmony_ci	}
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ci	ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
7448c2ecf20Sopenharmony_ci	if (ret) {
7458c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Read device id error\n");
7468c2ecf20Sopenharmony_ci		return ret;
7478c2ecf20Sopenharmony_ci	}
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_ci	/* Check your board and dts for match the right pmic */
7508c2ecf20Sopenharmony_ci	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
7518c2ecf20Sopenharmony_ci	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
7528c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Device id(%x) mismatched\n",
7538c2ecf20Sopenharmony_ci			device_id >> 4);
7548c2ecf20Sopenharmony_ci		return -EINVAL;
7558c2ecf20Sopenharmony_ci	}
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_ci	for (i = 0; i < pca9450->rcnt; i++) {
7588c2ecf20Sopenharmony_ci		const struct regulator_desc *desc;
7598c2ecf20Sopenharmony_ci		struct regulator_dev *rdev;
7608c2ecf20Sopenharmony_ci		const struct pca9450_regulator_desc *r;
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci		r = &regulator_desc[i];
7638c2ecf20Sopenharmony_ci		desc = &r->desc;
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci		config.regmap = pca9450->regmap;
7668c2ecf20Sopenharmony_ci		config.dev = pca9450->dev;
7678c2ecf20Sopenharmony_ci
7688c2ecf20Sopenharmony_ci		rdev = devm_regulator_register(pca9450->dev, desc, &config);
7698c2ecf20Sopenharmony_ci		if (IS_ERR(rdev)) {
7708c2ecf20Sopenharmony_ci			ret = PTR_ERR(rdev);
7718c2ecf20Sopenharmony_ci			dev_err(pca9450->dev,
7728c2ecf20Sopenharmony_ci				"Failed to register regulator(%s): %d\n",
7738c2ecf20Sopenharmony_ci				desc->name, ret);
7748c2ecf20Sopenharmony_ci			return ret;
7758c2ecf20Sopenharmony_ci		}
7768c2ecf20Sopenharmony_ci	}
7778c2ecf20Sopenharmony_ci
7788c2ecf20Sopenharmony_ci	ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
7798c2ecf20Sopenharmony_ci					pca9450_irq_handler,
7808c2ecf20Sopenharmony_ci					(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
7818c2ecf20Sopenharmony_ci					"pca9450-irq", pca9450);
7828c2ecf20Sopenharmony_ci	if (ret != 0) {
7838c2ecf20Sopenharmony_ci		dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
7848c2ecf20Sopenharmony_ci			pca9450->irq);
7858c2ecf20Sopenharmony_ci		return ret;
7868c2ecf20Sopenharmony_ci	}
7878c2ecf20Sopenharmony_ci	/* Unmask all interrupt except PWRON/WDOG/RSVD */
7888c2ecf20Sopenharmony_ci	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
7898c2ecf20Sopenharmony_ci				IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
7908c2ecf20Sopenharmony_ci				IRQ_THERM_105 | IRQ_THERM_125,
7918c2ecf20Sopenharmony_ci				IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
7928c2ecf20Sopenharmony_ci	if (ret) {
7938c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Unmask irq error\n");
7948c2ecf20Sopenharmony_ci		return ret;
7958c2ecf20Sopenharmony_ci	}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci	/* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
7988c2ecf20Sopenharmony_ci	ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
7998c2ecf20Sopenharmony_ci				BUCK123_PRESET_EN);
8008c2ecf20Sopenharmony_ci	if (ret) {
8018c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
8028c2ecf20Sopenharmony_ci		return ret;
8038c2ecf20Sopenharmony_ci	}
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_ci	/* Set reset behavior on assertion of WDOG_B signal */
8068c2ecf20Sopenharmony_ci	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
8078c2ecf20Sopenharmony_ci				WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12);
8088c2ecf20Sopenharmony_ci	if (ret) {
8098c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
8108c2ecf20Sopenharmony_ci		return ret;
8118c2ecf20Sopenharmony_ci	}
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_ci	/*
8148c2ecf20Sopenharmony_ci	 * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
8158c2ecf20Sopenharmony_ci	 * This is only valid if the SD_VSEL input of the PMIC is high. Let's
8168c2ecf20Sopenharmony_ci	 * check if the pin is available as GPIO and set it to high.
8178c2ecf20Sopenharmony_ci	 */
8188c2ecf20Sopenharmony_ci	pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_ci	if (IS_ERR(pca9450->sd_vsel_gpio)) {
8218c2ecf20Sopenharmony_ci		dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
8228c2ecf20Sopenharmony_ci		return ret;
8238c2ecf20Sopenharmony_ci	}
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci	dev_info(&i2c->dev, "%s probed.\n",
8268c2ecf20Sopenharmony_ci		type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	return 0;
8298c2ecf20Sopenharmony_ci}
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_cistatic const struct of_device_id pca9450_of_match[] = {
8328c2ecf20Sopenharmony_ci	{
8338c2ecf20Sopenharmony_ci		.compatible = "nxp,pca9450a",
8348c2ecf20Sopenharmony_ci		.data = (void *)PCA9450_TYPE_PCA9450A,
8358c2ecf20Sopenharmony_ci	},
8368c2ecf20Sopenharmony_ci	{
8378c2ecf20Sopenharmony_ci		.compatible = "nxp,pca9450b",
8388c2ecf20Sopenharmony_ci		.data = (void *)PCA9450_TYPE_PCA9450BC,
8398c2ecf20Sopenharmony_ci	},
8408c2ecf20Sopenharmony_ci	{
8418c2ecf20Sopenharmony_ci		.compatible = "nxp,pca9450c",
8428c2ecf20Sopenharmony_ci		.data = (void *)PCA9450_TYPE_PCA9450BC,
8438c2ecf20Sopenharmony_ci	},
8448c2ecf20Sopenharmony_ci	{ }
8458c2ecf20Sopenharmony_ci};
8468c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, pca9450_of_match);
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_cistatic struct i2c_driver pca9450_i2c_driver = {
8498c2ecf20Sopenharmony_ci	.driver = {
8508c2ecf20Sopenharmony_ci		.name = "nxp-pca9450",
8518c2ecf20Sopenharmony_ci		.of_match_table = pca9450_of_match,
8528c2ecf20Sopenharmony_ci	},
8538c2ecf20Sopenharmony_ci	.probe = pca9450_i2c_probe,
8548c2ecf20Sopenharmony_ci};
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_cimodule_i2c_driver(pca9450_i2c_driver);
8578c2ecf20Sopenharmony_ci
8588c2ecf20Sopenharmony_ciMODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
8598c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
8608c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
861