162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <linux/bits.h> 462306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 562306a36Sopenharmony_ci#include <linux/interrupt.h> 662306a36Sopenharmony_ci#include <linux/kernel.h> 762306a36Sopenharmony_ci#include <linux/mod_devicetable.h> 862306a36Sopenharmony_ci#include <linux/module.h> 962306a36Sopenharmony_ci#include <linux/of.h> 1062306a36Sopenharmony_ci#include <linux/platform_device.h> 1162306a36Sopenharmony_ci#include <linux/regmap.h> 1262306a36Sopenharmony_ci#include <linux/regulator/driver.h> 1362306a36Sopenharmony_ci#include <linux/regulator/machine.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cienum { 1662306a36Sopenharmony_ci MT6370_IDX_DSVBOOST = 0, 1762306a36Sopenharmony_ci MT6370_IDX_DSVPOS, 1862306a36Sopenharmony_ci MT6370_IDX_DSVNEG, 1962306a36Sopenharmony_ci MT6370_IDX_VIBLDO, 2062306a36Sopenharmony_ci MT6370_MAX_IDX 2162306a36Sopenharmony_ci}; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define MT6370_REG_LDO_CFG 0x180 2462306a36Sopenharmony_ci#define MT6370_REG_LDO_VOUT 0x181 2562306a36Sopenharmony_ci#define MT6370_REG_DB_CTRL1 0x1B0 2662306a36Sopenharmony_ci#define MT6370_REG_DB_CTRL2 0x1B1 2762306a36Sopenharmony_ci#define MT6370_REG_DB_VBST 0x1B2 2862306a36Sopenharmony_ci#define MT6370_REG_DB_VPOS 0x1B3 2962306a36Sopenharmony_ci#define MT6370_REG_DB_VNEG 0x1B4 3062306a36Sopenharmony_ci#define MT6370_REG_LDO_STAT 0x1DC 3162306a36Sopenharmony_ci#define MT6370_REG_DB_STAT 0x1DF 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define MT6370_LDOOMS_MASK BIT(7) 3462306a36Sopenharmony_ci#define MT6370_LDOEN_MASK BIT(7) 3562306a36Sopenharmony_ci#define MT6370_LDOVOUT_MASK GENMASK(3, 0) 3662306a36Sopenharmony_ci#define MT6370_DBPERD_MASK (BIT(7) | BIT(4)) 3762306a36Sopenharmony_ci#define MT6370_DBEXTEN_MASK BIT(0) 3862306a36Sopenharmony_ci#define MT6370_DBVPOSEN_MASK BIT(6) 3962306a36Sopenharmony_ci#define MT6370_DBVPOSDISG_MASK BIT(5) 4062306a36Sopenharmony_ci#define MT6370_DBVNEGEN_MASK BIT(3) 4162306a36Sopenharmony_ci#define MT6370_DBVNEGDISG_MASK BIT(2) 4262306a36Sopenharmony_ci#define MT6370_DBALLON_MASK (MT6370_DBVPOSEN_MASK | MT6370_DBVNEGEN_MASK) 4362306a36Sopenharmony_ci#define MT6370_DBSLEW_MASK GENMASK(7, 6) 4462306a36Sopenharmony_ci#define MT6370_DBVOUT_MASK GENMASK(5, 0) 4562306a36Sopenharmony_ci#define MT6370_LDOOC_EVT_MASK BIT(7) 4662306a36Sopenharmony_ci#define MT6370_POSSCP_EVT_MASK BIT(7) 4762306a36Sopenharmony_ci#define MT6370_NEGSCP_EVT_MASK BIT(6) 4862306a36Sopenharmony_ci#define MT6370_BSTOCP_EVT_MASK BIT(5) 4962306a36Sopenharmony_ci#define MT6370_POSOCP_EVT_MASK BIT(4) 5062306a36Sopenharmony_ci#define MT6370_NEGOCP_EVT_MASK BIT(3) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define MT6370_LDO_MINUV 1600000 5362306a36Sopenharmony_ci#define MT6370_LDO_STPUV 200000 5462306a36Sopenharmony_ci#define MT6370_LDO_N_VOLT 13 5562306a36Sopenharmony_ci#define MT6370_DBVBOOST_MINUV 4000000 5662306a36Sopenharmony_ci#define MT6370_DBVBOOST_STPUV 50000 5762306a36Sopenharmony_ci#define MT6370_DBVBOOST_N_VOLT 45 5862306a36Sopenharmony_ci#define MT6370_DBVOUT_MINUV 4000000 5962306a36Sopenharmony_ci#define MT6370_DBVOUT_STPUV 50000 6062306a36Sopenharmony_ci#define MT6370_DBVOUT_N_VOLT 41 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistruct mt6370_priv { 6362306a36Sopenharmony_ci struct device *dev; 6462306a36Sopenharmony_ci struct regmap *regmap; 6562306a36Sopenharmony_ci struct regulator_dev *rdev[MT6370_MAX_IDX]; 6662306a36Sopenharmony_ci bool use_external_ctrl; 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic const unsigned int mt6370_vpos_ramp_tbl[] = { 8540, 5840, 4830, 3000 }; 7062306a36Sopenharmony_cistatic const unsigned int mt6370_vneg_ramp_tbl[] = { 10090, 6310, 5050, 3150 }; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic int mt6370_get_error_flags(struct regulator_dev *rdev, 7362306a36Sopenharmony_ci unsigned int *flags) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci struct regmap *regmap = rdev_get_regmap(rdev); 7662306a36Sopenharmony_ci unsigned int stat_reg, stat, rpt_flags = 0; 7762306a36Sopenharmony_ci int rid = rdev_get_id(rdev), ret; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if (rid == MT6370_IDX_VIBLDO) 8062306a36Sopenharmony_ci stat_reg = MT6370_REG_LDO_STAT; 8162306a36Sopenharmony_ci else 8262306a36Sopenharmony_ci stat_reg = MT6370_REG_DB_STAT; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ret = regmap_read(regmap, stat_reg, &stat); 8562306a36Sopenharmony_ci if (ret) 8662306a36Sopenharmony_ci return ret; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci switch (rid) { 8962306a36Sopenharmony_ci case MT6370_IDX_DSVBOOST: 9062306a36Sopenharmony_ci if (stat & MT6370_BSTOCP_EVT_MASK) 9162306a36Sopenharmony_ci rpt_flags |= REGULATOR_ERROR_OVER_CURRENT; 9262306a36Sopenharmony_ci break; 9362306a36Sopenharmony_ci case MT6370_IDX_DSVPOS: 9462306a36Sopenharmony_ci if (stat & MT6370_POSSCP_EVT_MASK) 9562306a36Sopenharmony_ci rpt_flags |= REGULATOR_ERROR_UNDER_VOLTAGE; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if (stat & MT6370_POSOCP_EVT_MASK) 9862306a36Sopenharmony_ci rpt_flags |= REGULATOR_ERROR_OVER_CURRENT; 9962306a36Sopenharmony_ci break; 10062306a36Sopenharmony_ci case MT6370_IDX_DSVNEG: 10162306a36Sopenharmony_ci if (stat & MT6370_NEGSCP_EVT_MASK) 10262306a36Sopenharmony_ci rpt_flags |= REGULATOR_ERROR_UNDER_VOLTAGE; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci if (stat & MT6370_NEGOCP_EVT_MASK) 10562306a36Sopenharmony_ci rpt_flags |= REGULATOR_ERROR_OVER_CURRENT; 10662306a36Sopenharmony_ci break; 10762306a36Sopenharmony_ci default: 10862306a36Sopenharmony_ci if (stat & MT6370_LDOOC_EVT_MASK) 10962306a36Sopenharmony_ci rpt_flags |= REGULATOR_ERROR_OVER_CURRENT; 11062306a36Sopenharmony_ci break; 11162306a36Sopenharmony_ci } 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci *flags = rpt_flags; 11462306a36Sopenharmony_ci return 0; 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic const struct regulator_ops mt6370_dbvboost_ops = { 11862306a36Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 11962306a36Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 12062306a36Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 12162306a36Sopenharmony_ci .get_bypass = regulator_get_bypass_regmap, 12262306a36Sopenharmony_ci .set_bypass = regulator_set_bypass_regmap, 12362306a36Sopenharmony_ci .get_error_flags = mt6370_get_error_flags, 12462306a36Sopenharmony_ci}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic const struct regulator_ops mt6370_dbvout_ops = { 12762306a36Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 12862306a36Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 12962306a36Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 13062306a36Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 13162306a36Sopenharmony_ci .enable = regulator_enable_regmap, 13262306a36Sopenharmony_ci .disable = regulator_disable_regmap, 13362306a36Sopenharmony_ci .set_active_discharge = regulator_set_active_discharge_regmap, 13462306a36Sopenharmony_ci .set_ramp_delay = regulator_set_ramp_delay_regmap, 13562306a36Sopenharmony_ci .get_error_flags = mt6370_get_error_flags, 13662306a36Sopenharmony_ci}; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistatic const struct regulator_ops mt6370_ldo_ops = { 13962306a36Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 14062306a36Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 14162306a36Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 14262306a36Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 14362306a36Sopenharmony_ci .enable = regulator_enable_regmap, 14462306a36Sopenharmony_ci .disable = regulator_disable_regmap, 14562306a36Sopenharmony_ci .set_active_discharge = regulator_set_active_discharge_regmap, 14662306a36Sopenharmony_ci .get_error_flags = mt6370_get_error_flags, 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic int mt6370_of_parse_cb(struct device_node *np, 15062306a36Sopenharmony_ci const struct regulator_desc *desc, 15162306a36Sopenharmony_ci struct regulator_config *config) 15262306a36Sopenharmony_ci{ 15362306a36Sopenharmony_ci struct mt6370_priv *priv = config->driver_data; 15462306a36Sopenharmony_ci struct gpio_desc *enable_gpio; 15562306a36Sopenharmony_ci int ret; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci enable_gpio = fwnode_gpiod_get_index(of_fwnode_handle(np), "enable", 0, 15862306a36Sopenharmony_ci GPIOD_OUT_HIGH | 15962306a36Sopenharmony_ci GPIOD_FLAGS_BIT_NONEXCLUSIVE, 16062306a36Sopenharmony_ci desc->name); 16162306a36Sopenharmony_ci if (IS_ERR(enable_gpio)) { 16262306a36Sopenharmony_ci config->ena_gpiod = NULL; 16362306a36Sopenharmony_ci return 0; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci /* 16762306a36Sopenharmony_ci * RG control by default 16862306a36Sopenharmony_ci * Only if all are using external pin, change all by external control 16962306a36Sopenharmony_ci */ 17062306a36Sopenharmony_ci if (priv->use_external_ctrl) { 17162306a36Sopenharmony_ci ret = regmap_update_bits(priv->regmap, MT6370_REG_DB_CTRL1, 17262306a36Sopenharmony_ci MT6370_DBEXTEN_MASK, 17362306a36Sopenharmony_ci MT6370_DBEXTEN_MASK); 17462306a36Sopenharmony_ci if (ret) 17562306a36Sopenharmony_ci return ret; 17662306a36Sopenharmony_ci } 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci config->ena_gpiod = enable_gpio; 17962306a36Sopenharmony_ci priv->use_external_ctrl = true; 18062306a36Sopenharmony_ci return 0; 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistatic const struct regulator_desc mt6370_regulator_descs[] = { 18462306a36Sopenharmony_ci { 18562306a36Sopenharmony_ci .name = "mt6370-dsv-vbst", 18662306a36Sopenharmony_ci .of_match = of_match_ptr("dsvbst"), 18762306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 18862306a36Sopenharmony_ci .id = MT6370_IDX_DSVBOOST, 18962306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 19062306a36Sopenharmony_ci .owner = THIS_MODULE, 19162306a36Sopenharmony_ci .ops = &mt6370_dbvboost_ops, 19262306a36Sopenharmony_ci .min_uV = MT6370_DBVBOOST_MINUV, 19362306a36Sopenharmony_ci .uV_step = MT6370_DBVBOOST_STPUV, 19462306a36Sopenharmony_ci .n_voltages = MT6370_DBVBOOST_N_VOLT, 19562306a36Sopenharmony_ci .vsel_reg = MT6370_REG_DB_VBST, 19662306a36Sopenharmony_ci .vsel_mask = MT6370_DBVOUT_MASK, 19762306a36Sopenharmony_ci .bypass_reg = MT6370_REG_DB_CTRL1, 19862306a36Sopenharmony_ci .bypass_mask = MT6370_DBPERD_MASK, 19962306a36Sopenharmony_ci .bypass_val_on = MT6370_DBPERD_MASK, 20062306a36Sopenharmony_ci }, 20162306a36Sopenharmony_ci { 20262306a36Sopenharmony_ci .name = "mt6370-dsv-vpos", 20362306a36Sopenharmony_ci .of_match = of_match_ptr("dsvpos"), 20462306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 20562306a36Sopenharmony_ci .id = MT6370_IDX_DSVPOS, 20662306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 20762306a36Sopenharmony_ci .owner = THIS_MODULE, 20862306a36Sopenharmony_ci .of_parse_cb = mt6370_of_parse_cb, 20962306a36Sopenharmony_ci .ops = &mt6370_dbvout_ops, 21062306a36Sopenharmony_ci .min_uV = MT6370_DBVOUT_MINUV, 21162306a36Sopenharmony_ci .uV_step = MT6370_DBVOUT_STPUV, 21262306a36Sopenharmony_ci .n_voltages = MT6370_DBVOUT_N_VOLT, 21362306a36Sopenharmony_ci .vsel_reg = MT6370_REG_DB_VPOS, 21462306a36Sopenharmony_ci .vsel_mask = MT6370_DBVOUT_MASK, 21562306a36Sopenharmony_ci .enable_reg = MT6370_REG_DB_CTRL2, 21662306a36Sopenharmony_ci .enable_mask = MT6370_DBVPOSEN_MASK, 21762306a36Sopenharmony_ci .ramp_reg = MT6370_REG_DB_VPOS, 21862306a36Sopenharmony_ci .ramp_mask = MT6370_DBSLEW_MASK, 21962306a36Sopenharmony_ci .ramp_delay_table = mt6370_vpos_ramp_tbl, 22062306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(mt6370_vpos_ramp_tbl), 22162306a36Sopenharmony_ci .active_discharge_reg = MT6370_REG_DB_CTRL2, 22262306a36Sopenharmony_ci .active_discharge_mask = MT6370_DBVPOSDISG_MASK, 22362306a36Sopenharmony_ci .active_discharge_on = MT6370_DBVPOSDISG_MASK, 22462306a36Sopenharmony_ci }, 22562306a36Sopenharmony_ci { 22662306a36Sopenharmony_ci .name = "mt6370-dsv-vneg", 22762306a36Sopenharmony_ci .of_match = of_match_ptr("dsvneg"), 22862306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 22962306a36Sopenharmony_ci .id = MT6370_IDX_DSVNEG, 23062306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 23162306a36Sopenharmony_ci .owner = THIS_MODULE, 23262306a36Sopenharmony_ci .of_parse_cb = mt6370_of_parse_cb, 23362306a36Sopenharmony_ci .ops = &mt6370_dbvout_ops, 23462306a36Sopenharmony_ci .min_uV = MT6370_DBVOUT_MINUV, 23562306a36Sopenharmony_ci .uV_step = MT6370_DBVOUT_STPUV, 23662306a36Sopenharmony_ci .n_voltages = MT6370_DBVOUT_N_VOLT, 23762306a36Sopenharmony_ci .vsel_reg = MT6370_REG_DB_VNEG, 23862306a36Sopenharmony_ci .vsel_mask = MT6370_DBVOUT_MASK, 23962306a36Sopenharmony_ci .enable_reg = MT6370_REG_DB_CTRL2, 24062306a36Sopenharmony_ci .enable_mask = MT6370_DBVNEGEN_MASK, 24162306a36Sopenharmony_ci .ramp_reg = MT6370_REG_DB_VNEG, 24262306a36Sopenharmony_ci .ramp_mask = MT6370_DBSLEW_MASK, 24362306a36Sopenharmony_ci .ramp_delay_table = mt6370_vneg_ramp_tbl, 24462306a36Sopenharmony_ci .n_ramp_values = ARRAY_SIZE(mt6370_vneg_ramp_tbl), 24562306a36Sopenharmony_ci .active_discharge_reg = MT6370_REG_DB_CTRL2, 24662306a36Sopenharmony_ci .active_discharge_mask = MT6370_DBVNEGDISG_MASK, 24762306a36Sopenharmony_ci .active_discharge_on = MT6370_DBVNEGDISG_MASK, 24862306a36Sopenharmony_ci }, 24962306a36Sopenharmony_ci { 25062306a36Sopenharmony_ci .name = "mt6370-vib-ldo", 25162306a36Sopenharmony_ci .of_match = of_match_ptr("vibldo"), 25262306a36Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), 25362306a36Sopenharmony_ci .id = MT6370_IDX_VIBLDO, 25462306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, 25562306a36Sopenharmony_ci .owner = THIS_MODULE, 25662306a36Sopenharmony_ci .ops = &mt6370_ldo_ops, 25762306a36Sopenharmony_ci .min_uV = MT6370_LDO_MINUV, 25862306a36Sopenharmony_ci .uV_step = MT6370_LDO_STPUV, 25962306a36Sopenharmony_ci .n_voltages = MT6370_LDO_N_VOLT, 26062306a36Sopenharmony_ci .vsel_reg = MT6370_REG_LDO_VOUT, 26162306a36Sopenharmony_ci .vsel_mask = MT6370_LDOVOUT_MASK, 26262306a36Sopenharmony_ci .enable_reg = MT6370_REG_LDO_VOUT, 26362306a36Sopenharmony_ci .enable_mask = MT6370_LDOEN_MASK, 26462306a36Sopenharmony_ci .active_discharge_reg = MT6370_REG_LDO_CFG, 26562306a36Sopenharmony_ci .active_discharge_mask = MT6370_LDOOMS_MASK, 26662306a36Sopenharmony_ci .active_discharge_on = MT6370_LDOOMS_MASK, 26762306a36Sopenharmony_ci } 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic irqreturn_t mt6370_scp_handler(int irq, void *data) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci struct regulator_dev *rdev = data; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, 27562306a36Sopenharmony_ci NULL); 27662306a36Sopenharmony_ci return IRQ_HANDLED; 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic irqreturn_t mt6370_ocp_handler(int irq, void *data) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci struct regulator_dev *rdev = data; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); 28462306a36Sopenharmony_ci return IRQ_HANDLED; 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic int mt6370_regulator_irq_register(struct mt6370_priv *priv) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci struct platform_device *pdev = to_platform_device(priv->dev); 29062306a36Sopenharmony_ci static const struct { 29162306a36Sopenharmony_ci const char *name; 29262306a36Sopenharmony_ci int rid; 29362306a36Sopenharmony_ci irq_handler_t handler; 29462306a36Sopenharmony_ci } mt6370_irqs[] = { 29562306a36Sopenharmony_ci { "db_vpos_scp", MT6370_IDX_DSVPOS, mt6370_scp_handler }, 29662306a36Sopenharmony_ci { "db_vneg_scp", MT6370_IDX_DSVNEG, mt6370_scp_handler }, 29762306a36Sopenharmony_ci { "db_vbst_ocp", MT6370_IDX_DSVBOOST, mt6370_ocp_handler }, 29862306a36Sopenharmony_ci { "db_vpos_ocp", MT6370_IDX_DSVPOS, mt6370_ocp_handler }, 29962306a36Sopenharmony_ci { "db_vneg_ocp", MT6370_IDX_DSVNEG, mt6370_ocp_handler }, 30062306a36Sopenharmony_ci { "ldo_oc", MT6370_IDX_VIBLDO, mt6370_ocp_handler } 30162306a36Sopenharmony_ci }; 30262306a36Sopenharmony_ci struct regulator_dev *rdev; 30362306a36Sopenharmony_ci int i, irq, ret; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mt6370_irqs); i++) { 30662306a36Sopenharmony_ci irq = platform_get_irq_byname(pdev, mt6370_irqs[i].name); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci rdev = priv->rdev[mt6370_irqs[i].rid]; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci ret = devm_request_threaded_irq(priv->dev, irq, NULL, 31162306a36Sopenharmony_ci mt6370_irqs[i].handler, 0, 31262306a36Sopenharmony_ci mt6370_irqs[i].name, rdev); 31362306a36Sopenharmony_ci if (ret) { 31462306a36Sopenharmony_ci dev_err(priv->dev, 31562306a36Sopenharmony_ci "Failed to register (%d) interrupt\n", i); 31662306a36Sopenharmony_ci return ret; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci } 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci return 0; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistatic int mt6370_regualtor_register(struct mt6370_priv *priv) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci struct regulator_dev *rdev; 32662306a36Sopenharmony_ci struct regulator_config cfg = {}; 32762306a36Sopenharmony_ci struct device *parent = priv->dev->parent; 32862306a36Sopenharmony_ci int i; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci cfg.dev = parent; 33162306a36Sopenharmony_ci cfg.driver_data = priv; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci for (i = 0; i < MT6370_MAX_IDX; i++) { 33462306a36Sopenharmony_ci rdev = devm_regulator_register(priv->dev, 33562306a36Sopenharmony_ci mt6370_regulator_descs + i, 33662306a36Sopenharmony_ci &cfg); 33762306a36Sopenharmony_ci if (IS_ERR(rdev)) { 33862306a36Sopenharmony_ci dev_err(priv->dev, 33962306a36Sopenharmony_ci "Failed to register (%d) regulator\n", i); 34062306a36Sopenharmony_ci return PTR_ERR(rdev); 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci priv->rdev[i] = rdev; 34462306a36Sopenharmony_ci } 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci return 0; 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_cistatic int mt6370_regulator_probe(struct platform_device *pdev) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci struct mt6370_priv *priv; 35262306a36Sopenharmony_ci int ret; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 35562306a36Sopenharmony_ci if (!priv) 35662306a36Sopenharmony_ci return -ENOMEM; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci priv->dev = &pdev->dev; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci priv->regmap = dev_get_regmap(pdev->dev.parent, NULL); 36162306a36Sopenharmony_ci if (!priv->regmap) { 36262306a36Sopenharmony_ci dev_err(&pdev->dev, "Failed to init regmap\n"); 36362306a36Sopenharmony_ci return -ENODEV; 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci ret = mt6370_regualtor_register(priv); 36762306a36Sopenharmony_ci if (ret) 36862306a36Sopenharmony_ci return ret; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci return mt6370_regulator_irq_register(priv); 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_cistatic const struct platform_device_id mt6370_devid_table[] = { 37462306a36Sopenharmony_ci { "mt6370-regulator", 0}, 37562306a36Sopenharmony_ci {} 37662306a36Sopenharmony_ci}; 37762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(platform, mt6370_devid_table); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_cistatic struct platform_driver mt6370_regulator_driver = { 38062306a36Sopenharmony_ci .driver = { 38162306a36Sopenharmony_ci .name = "mt6370-regulator", 38262306a36Sopenharmony_ci .probe_type = PROBE_PREFER_ASYNCHRONOUS, 38362306a36Sopenharmony_ci }, 38462306a36Sopenharmony_ci .id_table = mt6370_devid_table, 38562306a36Sopenharmony_ci .probe = mt6370_regulator_probe, 38662306a36Sopenharmony_ci}; 38762306a36Sopenharmony_cimodule_platform_driver(mt6370_regulator_driver); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ciMODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 39062306a36Sopenharmony_ciMODULE_DESCRIPTION("Mediatek MT6370 Regulator Driver"); 39162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 392