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 = ®ulator_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