brintos

brintos / linux-shallow public Read only

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