Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // Copyright 2014 Embest Technology Co. Ltd. Inc.
0004 // bd71815-regulator.c ROHM BD71815 regulator driver
0005 //
0006 // Author: Tony Luo <luofc@embedinfo.com>
0007 //
0008 // Partially rewritten at 2021 by
0009 // Matti Vaittinen <matti.vaitinen@fi.rohmeurope.com>
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/err.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/of.h>
0017 #include <linux/gpio/consumer.h>
0018 #include <linux/regulator/driver.h>
0019 #include <linux/delay.h>
0020 #include <linux/slab.h>
0021 #include <linux/gpio.h>
0022 #include <linux/mfd/rohm-generic.h>
0023 #include <linux/mfd/rohm-bd71815.h>
0024 #include <linux/regulator/of_regulator.h>
0025 
0026 struct bd71815_regulator {
0027     struct regulator_desc desc;
0028     const struct rohm_dvs_config *dvs;
0029 };
0030 
0031 static const int bd7181x_wled_currents[] = {
0032     10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000,
0033     5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,
0034     16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000,
0035 };
0036 
0037 static const struct rohm_dvs_config buck1_dvs = {
0038     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0039                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0040     .run_reg        = BD71815_REG_BUCK1_VOLT_H,
0041     .run_mask       = BD71815_VOLT_MASK,
0042     .run_on_mask        = BD71815_BUCK_RUN_ON,
0043     .snvs_on_mask       = BD71815_BUCK_SNVS_ON,
0044     .suspend_reg        = BD71815_REG_BUCK1_VOLT_L,
0045     .suspend_mask       = BD71815_VOLT_MASK,
0046     .suspend_on_mask    = BD71815_BUCK_SUSP_ON,
0047     .lpsr_reg       = BD71815_REG_BUCK1_VOLT_L,
0048     .lpsr_mask      = BD71815_VOLT_MASK,
0049     .lpsr_on_mask       = BD71815_BUCK_LPSR_ON,
0050 };
0051 
0052 static const struct rohm_dvs_config buck2_dvs = {
0053     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0054                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0055     .run_reg        = BD71815_REG_BUCK2_VOLT_H,
0056     .run_mask       = BD71815_VOLT_MASK,
0057     .run_on_mask        = BD71815_BUCK_RUN_ON,
0058     .snvs_on_mask       = BD71815_BUCK_SNVS_ON,
0059     .suspend_reg        = BD71815_REG_BUCK2_VOLT_L,
0060     .suspend_mask       = BD71815_VOLT_MASK,
0061     .suspend_on_mask    = BD71815_BUCK_SUSP_ON,
0062     .lpsr_reg       = BD71815_REG_BUCK2_VOLT_L,
0063     .lpsr_mask      = BD71815_VOLT_MASK,
0064     .lpsr_on_mask       = BD71815_BUCK_LPSR_ON,
0065 };
0066 
0067 static const struct rohm_dvs_config buck3_dvs = {
0068     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0069                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0070     .run_reg        = BD71815_REG_BUCK3_VOLT,
0071     .run_mask       = BD71815_VOLT_MASK,
0072     .run_on_mask        = BD71815_BUCK_RUN_ON,
0073     .snvs_on_mask       = BD71815_BUCK_SNVS_ON,
0074     .suspend_on_mask    = BD71815_BUCK_SUSP_ON,
0075     .lpsr_on_mask       = BD71815_BUCK_LPSR_ON,
0076 };
0077 
0078 static const struct rohm_dvs_config buck4_dvs = {
0079     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0080                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0081     .run_reg        = BD71815_REG_BUCK4_VOLT,
0082     .run_mask       = BD71815_VOLT_MASK,
0083     .run_on_mask        = BD71815_BUCK_RUN_ON,
0084     .snvs_on_mask       = BD71815_BUCK_SNVS_ON,
0085     .suspend_on_mask    = BD71815_BUCK_SUSP_ON,
0086     .lpsr_on_mask       = BD71815_BUCK_LPSR_ON,
0087 };
0088 
0089 static const struct rohm_dvs_config ldo1_dvs = {
0090     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0091                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0092     .run_reg        = BD71815_REG_LDO_MODE1,
0093     .run_mask       = BD71815_VOLT_MASK,
0094     .run_on_mask        = LDO1_RUN_ON,
0095     .snvs_on_mask       = LDO1_SNVS_ON,
0096     .suspend_on_mask    = LDO1_SUSP_ON,
0097     .lpsr_on_mask       = LDO1_LPSR_ON,
0098 };
0099 
0100 static const struct rohm_dvs_config ldo2_dvs = {
0101     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0102                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0103     .run_reg        = BD71815_REG_LDO_MODE2,
0104     .run_mask       = BD71815_VOLT_MASK,
0105     .run_on_mask        = LDO2_RUN_ON,
0106     .snvs_on_mask       = LDO2_SNVS_ON,
0107     .suspend_on_mask    = LDO2_SUSP_ON,
0108     .lpsr_on_mask       = LDO2_LPSR_ON,
0109 };
0110 
0111 static const struct rohm_dvs_config ldo3_dvs = {
0112     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0113                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0114     .run_reg        = BD71815_REG_LDO_MODE2,
0115     .run_mask       = BD71815_VOLT_MASK,
0116     .run_on_mask        = LDO3_RUN_ON,
0117     .snvs_on_mask       = LDO3_SNVS_ON,
0118     .suspend_on_mask    = LDO3_SUSP_ON,
0119     .lpsr_on_mask       = LDO3_LPSR_ON,
0120 };
0121 
0122 static const struct rohm_dvs_config ldo4_dvs = {
0123     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0124                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0125     .run_reg        = BD71815_REG_LDO_MODE3,
0126     .run_mask       = BD71815_VOLT_MASK,
0127     .run_on_mask        = LDO4_RUN_ON,
0128     .snvs_on_mask       = LDO4_SNVS_ON,
0129     .suspend_on_mask    = LDO4_SUSP_ON,
0130     .lpsr_on_mask       = LDO4_LPSR_ON,
0131 };
0132 
0133 static const struct rohm_dvs_config ldo5_dvs = {
0134     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0135                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0136     .run_reg        = BD71815_REG_LDO_MODE3,
0137     .run_mask       = BD71815_VOLT_MASK,
0138     .run_on_mask        = LDO5_RUN_ON,
0139     .snvs_on_mask       = LDO5_SNVS_ON,
0140     .suspend_on_mask    = LDO5_SUSP_ON,
0141     .lpsr_on_mask       = LDO5_LPSR_ON,
0142 };
0143 
0144 static const struct rohm_dvs_config dvref_dvs = {
0145     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0146                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0147     .run_on_mask        = DVREF_RUN_ON,
0148     .snvs_on_mask       = DVREF_SNVS_ON,
0149     .suspend_on_mask    = DVREF_SUSP_ON,
0150     .lpsr_on_mask       = DVREF_LPSR_ON,
0151 };
0152 
0153 static const struct rohm_dvs_config ldolpsr_dvs = {
0154     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0155                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0156     .run_on_mask        = DVREF_RUN_ON,
0157     .snvs_on_mask       = DVREF_SNVS_ON,
0158     .suspend_on_mask    = DVREF_SUSP_ON,
0159     .lpsr_on_mask       = DVREF_LPSR_ON,
0160 };
0161 
0162 static const struct rohm_dvs_config buck5_dvs = {
0163     .level_map      = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
0164                   ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
0165     .run_reg        = BD71815_REG_BUCK5_VOLT,
0166     .run_mask       = BD71815_VOLT_MASK,
0167     .run_on_mask        = BD71815_BUCK_RUN_ON,
0168     .snvs_on_mask       = BD71815_BUCK_SNVS_ON,
0169     .suspend_on_mask    = BD71815_BUCK_SUSP_ON,
0170     .lpsr_on_mask       = BD71815_BUCK_LPSR_ON,
0171 };
0172 
0173 static int set_hw_dvs_levels(struct device_node *np,
0174                  const struct regulator_desc *desc,
0175                  struct regulator_config *cfg)
0176 {
0177     struct bd71815_regulator *data;
0178 
0179     data = container_of(desc, struct bd71815_regulator, desc);
0180     return rohm_regulator_set_dvs_levels(data->dvs, np, desc, cfg->regmap);
0181 }
0182 
0183 /*
0184  * Bucks 1 and 2 have two voltage selection registers where selected
0185  * voltage can be set. Which of the registers is used can be either controlled
0186  * by a control bit in register - or by HW state. If HW state specific voltages
0187  * are given - then we assume HW state based control should be used.
0188  *
0189  * If volatge value is updated to currently selected register - then output
0190  * voltage is immediately changed no matter what is set as ramp rate. Thus we
0191  * default changing voltage by writing new value to inactive register and
0192  * then updating the 'register selection' bit. This naturally only works when
0193  * HW state machine is not used to select the voltage.
0194  */
0195 static int buck12_set_hw_dvs_levels(struct device_node *np,
0196                     const struct regulator_desc *desc,
0197                     struct regulator_config *cfg)
0198 {
0199     struct bd71815_regulator *data;
0200     int ret = 0, val;
0201 
0202     data = container_of(desc, struct bd71815_regulator, desc);
0203 
0204     if (of_find_property(np, "rohm,dvs-run-voltage", NULL) ||
0205         of_find_property(np, "rohm,dvs-suspend-voltage", NULL) ||
0206         of_find_property(np, "rohm,dvs-lpsr-voltage", NULL) ||
0207         of_find_property(np, "rohm,dvs-snvs-voltage", NULL)) {
0208         ret = regmap_read(cfg->regmap, desc->vsel_reg, &val);
0209         if (ret)
0210             return ret;
0211 
0212         if (!(BD71815_BUCK_STBY_DVS & val) &&
0213             !(BD71815_BUCK_DVSSEL & val)) {
0214             int val2;
0215 
0216             /*
0217              * We are currently using voltage from _L.
0218              * We'd better copy it to _H and switch to it to
0219              * avoid shutting us down if LPSR or SUSPEND is set to
0220              * disabled. _L value is at reg _H + 1
0221              */
0222             ret = regmap_read(cfg->regmap, desc->vsel_reg + 1,
0223                       &val2);
0224             if (ret)
0225                 return ret;
0226 
0227             ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,
0228                          BD71815_VOLT_MASK |
0229                          BD71815_BUCK_DVSSEL,
0230                          val2 | BD71815_BUCK_DVSSEL);
0231             if (ret)
0232                 return ret;
0233         }
0234         ret = rohm_regulator_set_dvs_levels(data->dvs, np, desc,
0235                             cfg->regmap);
0236         if (ret)
0237             return ret;
0238         /*
0239          * DVS levels were given => use HW-state machine for voltage
0240          * controls. NOTE: AFAIK, This means that if voltage is changed
0241          * by SW the ramp-rate is not respected. Should we disable
0242          * SW voltage control when the HW state machine is used?
0243          */
0244         ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,
0245                      BD71815_BUCK_STBY_DVS,
0246                      BD71815_BUCK_STBY_DVS);
0247     }
0248 
0249     return ret;
0250 }
0251 
0252 /*
0253  * BUCK1/2
0254  * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
0255  * 00: 10.00mV/usec 10mV 1uS
0256  * 01: 5.00mV/usec  10mV 2uS
0257  * 10: 2.50mV/usec  10mV 4uS
0258  * 11: 1.25mV/usec  10mV 8uS
0259  */
0260 static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 };
0261 
0262 static int bd7181x_led_set_current_limit(struct regulator_dev *rdev,
0263                     int min_uA, int max_uA)
0264 {
0265     int ret;
0266     int onstatus;
0267 
0268     onstatus = regulator_is_enabled_regmap(rdev);
0269 
0270     ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA);
0271     if (!ret) {
0272         int newstatus;
0273 
0274         newstatus = regulator_is_enabled_regmap(rdev);
0275         if (onstatus != newstatus) {
0276             /*
0277              * HW FIX: spurious led status change detected. Toggle
0278              * state as a workaround
0279              */
0280             if (onstatus)
0281                 ret = regulator_enable_regmap(rdev);
0282             else
0283                 ret = regulator_disable_regmap(rdev);
0284 
0285             if (ret)
0286                 dev_err(rdev_get_dev(rdev),
0287                     "failed to revert the LED state (%d)\n",
0288                     ret);
0289         }
0290     }
0291 
0292     return ret;
0293 }
0294 
0295 static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
0296 {
0297     int rid = rdev_get_id(rdev);
0298     int ret, regh, regl, val;
0299 
0300     regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2;
0301     regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2;
0302 
0303     ret = regmap_read(rdev->regmap, regh, &val);
0304     if (ret)
0305         return ret;
0306 
0307     /*
0308      * If we use HW state machine based voltage reg selection - then we
0309      * return BD71815_REG_BUCK1_VOLT_H which is used at RUN.
0310      * Else we do return the BD71815_REG_BUCK1_VOLT_H or
0311      * BD71815_REG_BUCK1_VOLT_L depending on which is selected to be used
0312      * by BD71815_BUCK_DVSSEL bit
0313      */
0314     if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))
0315         ret = regmap_read(rdev->regmap, regl, &val);
0316 
0317     if (ret)
0318         return ret;
0319 
0320     return val & BD71815_VOLT_MASK;
0321 }
0322 
0323 /*
0324  * For Buck 1/2.
0325  */
0326 static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
0327                       unsigned int sel)
0328 {
0329     int rid = rdev_get_id(rdev);
0330     int ret, val, reg, regh, regl;
0331 
0332     regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2;
0333     regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2;
0334 
0335     ret = regmap_read(rdev->regmap, regh, &val);
0336     if (ret)
0337         return ret;
0338 
0339     /*
0340      * If bucks 1 & 2 are controlled by state machine - then the RUN state
0341      * voltage is set to BD71815_REG_BUCK1_VOLT_H. Changing SUSPEND/LPSR
0342      * voltages at runtime is not supported by this driver.
0343      */
0344     if (((val & BD71815_BUCK_STBY_DVS))) {
0345         return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,
0346                       sel);
0347     }
0348     /* Update new voltage to the register which is not selected now */
0349     if (val & BD71815_BUCK_DVSSEL)
0350         reg = regl;
0351     else
0352         reg = regh;
0353 
0354     ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel);
0355     if (ret)
0356         return ret;
0357 
0358     /* Select the other DVS register to be used */
0359     return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,
0360                   ~val);
0361 }
0362 
0363 static const struct regulator_ops bd7181x_ldo_regulator_ops = {
0364     .enable = regulator_enable_regmap,
0365     .disable = regulator_disable_regmap,
0366     .is_enabled = regulator_is_enabled_regmap,
0367     .list_voltage = regulator_list_voltage_linear,
0368     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0369     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0370 };
0371 
0372 static const struct regulator_ops bd7181x_fixed_regulator_ops = {
0373     .enable = regulator_enable_regmap,
0374     .disable = regulator_disable_regmap,
0375     .is_enabled = regulator_is_enabled_regmap,
0376     .list_voltage = regulator_list_voltage_linear,
0377 };
0378 
0379 static const struct regulator_ops bd7181x_buck_regulator_ops = {
0380     .enable = regulator_enable_regmap,
0381     .disable = regulator_disable_regmap,
0382     .is_enabled = regulator_is_enabled_regmap,
0383     .list_voltage = regulator_list_voltage_linear,
0384     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0385     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0386     .set_voltage_time_sel = regulator_set_voltage_time_sel,
0387 };
0388 
0389 static const struct regulator_ops bd7181x_buck12_regulator_ops = {
0390     .enable = regulator_enable_regmap,
0391     .disable = regulator_disable_regmap,
0392     .is_enabled = regulator_is_enabled_regmap,
0393     .list_voltage = regulator_list_voltage_linear,
0394     .set_voltage_sel = bd7181x_buck12_set_voltage_sel,
0395     .get_voltage_sel = bd7181x_buck12_get_voltage_sel,
0396     .set_voltage_time_sel = regulator_set_voltage_time_sel,
0397     .set_ramp_delay = regulator_set_ramp_delay_regmap,
0398 };
0399 
0400 static const struct regulator_ops bd7181x_led_regulator_ops = {
0401     .enable = regulator_enable_regmap,
0402     .disable = regulator_disable_regmap,
0403     .is_enabled = regulator_is_enabled_regmap,
0404     .set_current_limit = bd7181x_led_set_current_limit,
0405     .get_current_limit = regulator_get_current_limit_regmap,
0406 };
0407 
0408 #define BD71815_FIXED_REG(_name, _id, ereg, emsk, voltage, _dvs)    \
0409     [(_id)] = {                         \
0410         .desc = {                       \
0411             .name = #_name,                 \
0412             .of_match = of_match_ptr(#_name),       \
0413             .regulators_node = of_match_ptr("regulators"),  \
0414             .n_voltages = 1,                \
0415             .ops = &bd7181x_fixed_regulator_ops,        \
0416             .type = REGULATOR_VOLTAGE,          \
0417             .id = (_id),                    \
0418             .owner = THIS_MODULE,               \
0419             .min_uV = (voltage),                \
0420             .enable_reg = (ereg),               \
0421             .enable_mask = (emsk),              \
0422             .of_parse_cb = set_hw_dvs_levels,       \
0423         },                          \
0424         .dvs = (_dvs),                      \
0425     }
0426 
0427 #define BD71815_BUCK_REG(_name, _id, vsel, ereg, min, max, step, _dvs)  \
0428     [(_id)] = {                         \
0429         .desc = {                       \
0430             .name = #_name,                 \
0431             .of_match = of_match_ptr(#_name),       \
0432             .regulators_node = of_match_ptr("regulators"),  \
0433             .n_voltages = ((max) - (min)) / (step) + 1, \
0434             .ops = &bd7181x_buck_regulator_ops,     \
0435             .type = REGULATOR_VOLTAGE,          \
0436             .id = (_id),                    \
0437             .owner = THIS_MODULE,               \
0438             .min_uV = (min),                \
0439             .uV_step = (step),              \
0440             .vsel_reg = (vsel),             \
0441             .vsel_mask = BD71815_VOLT_MASK,         \
0442             .enable_reg = (ereg),               \
0443             .enable_mask = BD71815_BUCK_RUN_ON,     \
0444             .of_parse_cb = set_hw_dvs_levels,       \
0445         },                          \
0446         .dvs = (_dvs),                      \
0447     }
0448 
0449 #define BD71815_BUCK12_REG(_name, _id, vsel, ereg, min, max, step,  \
0450                _dvs)                    \
0451     [(_id)] = {                         \
0452         .desc = {                       \
0453             .name = #_name,                 \
0454             .of_match = of_match_ptr(#_name),       \
0455             .regulators_node = of_match_ptr("regulators"),  \
0456             .n_voltages = ((max) - (min)) / (step) + 1, \
0457             .ops = &bd7181x_buck12_regulator_ops,       \
0458             .type = REGULATOR_VOLTAGE,          \
0459             .id = (_id),                    \
0460             .owner = THIS_MODULE,               \
0461             .min_uV = (min),                \
0462             .uV_step = (step),              \
0463             .vsel_reg = (vsel),             \
0464             .vsel_mask = BD71815_VOLT_MASK,         \
0465             .enable_reg = (ereg),               \
0466             .enable_mask = BD71815_BUCK_RUN_ON,     \
0467             .ramp_reg = (ereg),             \
0468             .ramp_mask = BD71815_BUCK_RAMPRATE_MASK,    \
0469             .ramp_delay_table = bd7181x_ramp_table,     \
0470             .n_ramp_values = ARRAY_SIZE(bd7181x_ramp_table),\
0471             .of_parse_cb = buck12_set_hw_dvs_levels,    \
0472         },                          \
0473         .dvs = (_dvs),                      \
0474     }
0475 
0476 #define BD71815_LED_REG(_name, _id, csel, mask, ereg, emsk, currents)   \
0477     [(_id)] = {                         \
0478         .desc = {                       \
0479             .name = #_name,                 \
0480             .of_match = of_match_ptr(#_name),       \
0481             .regulators_node = of_match_ptr("regulators"),  \
0482             .n_current_limits = ARRAY_SIZE(currents),   \
0483             .ops = &bd7181x_led_regulator_ops,      \
0484             .type = REGULATOR_CURRENT,          \
0485             .id = (_id),                    \
0486             .owner = THIS_MODULE,               \
0487             .curr_table = currents,             \
0488             .csel_reg = (csel),             \
0489             .csel_mask = (mask),                \
0490             .enable_reg = (ereg),               \
0491             .enable_mask = (emsk),              \
0492         },                          \
0493     }
0494 
0495 #define BD71815_LDO_REG(_name, _id, vsel, ereg, emsk, min, max, step,   \
0496             _dvs)                       \
0497     [(_id)] = {                         \
0498         .desc = {                       \
0499             .name = #_name,                 \
0500             .of_match = of_match_ptr(#_name),       \
0501             .regulators_node = of_match_ptr("regulators"),  \
0502             .n_voltages = ((max) - (min)) / (step) + 1, \
0503             .ops = &bd7181x_ldo_regulator_ops,      \
0504             .type = REGULATOR_VOLTAGE,          \
0505             .id = (_id),                    \
0506             .owner = THIS_MODULE,               \
0507             .min_uV = (min),                \
0508             .uV_step = (step),              \
0509             .vsel_reg = (vsel),             \
0510             .vsel_mask = BD71815_VOLT_MASK,         \
0511             .enable_reg = (ereg),               \
0512             .enable_mask = (emsk),              \
0513             .of_parse_cb = set_hw_dvs_levels,       \
0514         },                          \
0515         .dvs = (_dvs),                      \
0516     }
0517 
0518 static const struct bd71815_regulator bd71815_regulators[] = {
0519     BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H,
0520                BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000,
0521                &buck1_dvs),
0522     BD71815_BUCK12_REG(buck2, BD71815_BUCK2, BD71815_REG_BUCK2_VOLT_H,
0523                BD71815_REG_BUCK2_MODE, 800000, 2000000, 25000,
0524                &buck2_dvs),
0525     BD71815_BUCK_REG(buck3, BD71815_BUCK3, BD71815_REG_BUCK3_VOLT,
0526              BD71815_REG_BUCK3_MODE,  1200000, 2700000, 50000,
0527              &buck3_dvs),
0528     BD71815_BUCK_REG(buck4, BD71815_BUCK4, BD71815_REG_BUCK4_VOLT,
0529              BD71815_REG_BUCK4_MODE,  1100000, 1850000, 25000,
0530              &buck4_dvs),
0531     BD71815_BUCK_REG(buck5, BD71815_BUCK5, BD71815_REG_BUCK5_VOLT,
0532              BD71815_REG_BUCK5_MODE,  1800000, 3300000, 50000,
0533              &buck5_dvs),
0534     BD71815_LDO_REG(ldo1, BD71815_LDO1, BD71815_REG_LDO1_VOLT,
0535             BD71815_REG_LDO_MODE1, LDO1_RUN_ON, 800000, 3300000,
0536             50000, &ldo1_dvs),
0537     BD71815_LDO_REG(ldo2, BD71815_LDO2, BD71815_REG_LDO2_VOLT,
0538             BD71815_REG_LDO_MODE2, LDO2_RUN_ON, 800000, 3300000,
0539             50000, &ldo2_dvs),
0540     /*
0541      * Let's default LDO3 to be enabled by SW. We can override ops if DT
0542      * says LDO3 should be enabled by HW when DCIN is connected.
0543      */
0544     BD71815_LDO_REG(ldo3, BD71815_LDO3, BD71815_REG_LDO3_VOLT,
0545             BD71815_REG_LDO_MODE2, LDO3_RUN_ON, 800000, 3300000,
0546             50000, &ldo3_dvs),
0547     BD71815_LDO_REG(ldo4, BD71815_LDO4, BD71815_REG_LDO4_VOLT,
0548             BD71815_REG_LDO_MODE3, LDO4_RUN_ON, 800000, 3300000,
0549             50000, &ldo4_dvs),
0550     BD71815_LDO_REG(ldo5, BD71815_LDO5, BD71815_REG_LDO5_VOLT_H,
0551             BD71815_REG_LDO_MODE3, LDO5_RUN_ON, 800000, 3300000,
0552             50000, &ldo5_dvs),
0553     BD71815_FIXED_REG(ldodvref, BD71815_LDODVREF, BD71815_REG_LDO_MODE4,
0554               DVREF_RUN_ON, 3000000, &dvref_dvs),
0555     BD71815_FIXED_REG(ldolpsr, BD71815_LDOLPSR, BD71815_REG_LDO_MODE4,
0556               LDO_LPSR_RUN_ON, 1800000, &ldolpsr_dvs),
0557     BD71815_LED_REG(wled, BD71815_WLED, BD71815_REG_LED_DIMM, LED_DIMM_MASK,
0558             BD71815_REG_LED_CTRL, LED_RUN_ON,
0559             bd7181x_wled_currents),
0560 };
0561 
0562 static int bd7181x_probe(struct platform_device *pdev)
0563 {
0564     struct regulator_config config = {};
0565     int i, ret;
0566     struct gpio_desc *ldo4_en;
0567     struct regmap *regmap;
0568 
0569     regmap = dev_get_regmap(pdev->dev.parent, NULL);
0570     if (!regmap) {
0571         dev_err(&pdev->dev, "No parent regmap\n");
0572         return -ENODEV;
0573     }
0574     ldo4_en = devm_gpiod_get_from_of_node(&pdev->dev,
0575                           pdev->dev.parent->of_node,
0576                          "rohm,vsel-gpios", 0,
0577                          GPIOD_ASIS, "ldo4-en");
0578 
0579     if (IS_ERR(ldo4_en)) {
0580         ret = PTR_ERR(ldo4_en);
0581         if (ret != -ENOENT)
0582             return ret;
0583         ldo4_en = NULL;
0584     }
0585 
0586     /* Disable to go to ship-mode */
0587     ret = regmap_update_bits(regmap, BD71815_REG_PWRCTRL, RESTARTEN, 0);
0588     if (ret)
0589         return ret;
0590 
0591     config.dev = pdev->dev.parent;
0592     config.regmap = regmap;
0593 
0594     for (i = 0; i < BD71815_REGULATOR_CNT; i++) {
0595         const struct regulator_desc *desc;
0596         struct regulator_dev *rdev;
0597 
0598         desc = &bd71815_regulators[i].desc;
0599 
0600         if (i == BD71815_LDO4)
0601             config.ena_gpiod = ldo4_en;
0602         else
0603             config.ena_gpiod = NULL;
0604 
0605         rdev = devm_regulator_register(&pdev->dev, desc, &config);
0606         if (IS_ERR(rdev)) {
0607             dev_err(&pdev->dev,
0608                 "failed to register %s regulator\n",
0609                 desc->name);
0610             return PTR_ERR(rdev);
0611         }
0612     }
0613     return 0;
0614 }
0615 
0616 static const struct platform_device_id bd7181x_pmic_id[] = {
0617     { "bd71815-pmic", ROHM_CHIP_TYPE_BD71815 },
0618     { },
0619 };
0620 MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);
0621 
0622 static struct platform_driver bd7181x_regulator = {
0623     .driver = {
0624         .name = "bd7181x-pmic",
0625     },
0626     .probe = bd7181x_probe,
0627     .id_table = bd7181x_pmic_id,
0628 };
0629 module_platform_driver(bd7181x_regulator);
0630 
0631 MODULE_AUTHOR("Tony Luo <luofc@embedinfo.com>");
0632 MODULE_DESCRIPTION("BD71815 voltage regulator driver");
0633 MODULE_LICENSE("GPL v2");
0634 MODULE_ALIAS("platform:bd7181x-pmic");