Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TI LP8788 MFD - buck regulator driver
0004  *
0005  * Copyright 2012 Texas Instruments
0006  *
0007  * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/slab.h>
0012 #include <linux/err.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regulator/driver.h>
0015 #include <linux/mfd/lp8788.h>
0016 #include <linux/gpio.h>
0017 
0018 /* register address */
0019 #define LP8788_EN_BUCK          0x0C
0020 #define LP8788_BUCK_DVS_SEL     0x1D
0021 #define LP8788_BUCK1_VOUT0      0x1E
0022 #define LP8788_BUCK1_VOUT1      0x1F
0023 #define LP8788_BUCK1_VOUT2      0x20
0024 #define LP8788_BUCK1_VOUT3      0x21
0025 #define LP8788_BUCK2_VOUT0      0x22
0026 #define LP8788_BUCK2_VOUT1      0x23
0027 #define LP8788_BUCK2_VOUT2      0x24
0028 #define LP8788_BUCK2_VOUT3      0x25
0029 #define LP8788_BUCK3_VOUT       0x26
0030 #define LP8788_BUCK4_VOUT       0x27
0031 #define LP8788_BUCK1_TIMESTEP       0x28
0032 #define LP8788_BUCK_PWM         0x2D
0033 
0034 /* mask/shift bits */
0035 #define LP8788_EN_BUCK1_M       BIT(0)  /* Addr 0Ch */
0036 #define LP8788_EN_BUCK2_M       BIT(1)
0037 #define LP8788_EN_BUCK3_M       BIT(2)
0038 #define LP8788_EN_BUCK4_M       BIT(3)
0039 #define LP8788_BUCK1_DVS_SEL_M      0x04    /* Addr 1Dh */
0040 #define LP8788_BUCK1_DVS_M      0x03
0041 #define LP8788_BUCK1_DVS_S      0
0042 #define LP8788_BUCK2_DVS_SEL_M      0x40
0043 #define LP8788_BUCK2_DVS_M      0x30
0044 #define LP8788_BUCK2_DVS_S      4
0045 #define LP8788_BUCK1_DVS_I2C        BIT(2)
0046 #define LP8788_BUCK2_DVS_I2C        BIT(6)
0047 #define LP8788_BUCK1_DVS_PIN        (0 << 2)
0048 #define LP8788_BUCK2_DVS_PIN        (0 << 6)
0049 #define LP8788_VOUT_M           0x1F    /* Addr 1Eh ~ 27h */
0050 #define LP8788_STARTUP_TIME_M       0xF8    /* Addr 28h ~ 2Bh */
0051 #define LP8788_STARTUP_TIME_S       3
0052 #define LP8788_FPWM_BUCK1_M     BIT(0)  /* Addr 2Dh */
0053 #define LP8788_FPWM_BUCK1_S     0
0054 #define LP8788_FPWM_BUCK2_M     BIT(1)
0055 #define LP8788_FPWM_BUCK2_S     1
0056 #define LP8788_FPWM_BUCK3_M     BIT(2)
0057 #define LP8788_FPWM_BUCK3_S     2
0058 #define LP8788_FPWM_BUCK4_M     BIT(3)
0059 #define LP8788_FPWM_BUCK4_S     3
0060 
0061 #define INVALID_ADDR            0xFF
0062 #define LP8788_FORCE_PWM        1
0063 #define LP8788_AUTO_PWM         0
0064 #define PIN_LOW             0
0065 #define PIN_HIGH            1
0066 #define ENABLE_TIME_USEC        32
0067 
0068 #define BUCK_FPWM_MASK(x)       (1 << (x))
0069 #define BUCK_FPWM_SHIFT(x)      (x)
0070 
0071 enum lp8788_dvs_state {
0072     DVS_LOW  = GPIOF_OUT_INIT_LOW,
0073     DVS_HIGH = GPIOF_OUT_INIT_HIGH,
0074 };
0075 
0076 enum lp8788_dvs_mode {
0077     REGISTER,
0078     EXTPIN,
0079 };
0080 
0081 enum lp8788_buck_id {
0082     BUCK1,
0083     BUCK2,
0084     BUCK3,
0085     BUCK4,
0086 };
0087 
0088 struct lp8788_buck {
0089     struct lp8788 *lp;
0090     struct regulator_dev *regulator;
0091     void *dvs;
0092 };
0093 
0094 /* BUCK 1 ~ 4 voltage ranges */
0095 static const struct linear_range buck_volt_ranges[] = {
0096     REGULATOR_LINEAR_RANGE(500000, 0, 0, 0),
0097     REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000),
0098 };
0099 
0100 static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
0101 {
0102     struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs;
0103     enum lp8788_dvs_state pinstate;
0104 
0105     if (!dvs)
0106         return;
0107 
0108     pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH;
0109     if (gpio_is_valid(dvs->gpio))
0110         gpio_set_value(dvs->gpio, pinstate);
0111 }
0112 
0113 static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
0114 {
0115     struct lp8788_buck2_dvs *dvs = (struct lp8788_buck2_dvs *)buck->dvs;
0116     enum lp8788_dvs_state pin1, pin2;
0117 
0118     if (!dvs)
0119         return;
0120 
0121     switch (dvs->vsel) {
0122     case DVS_SEL_V0:
0123         pin1 = DVS_LOW;
0124         pin2 = DVS_LOW;
0125         break;
0126     case DVS_SEL_V1:
0127         pin1 = DVS_HIGH;
0128         pin2 = DVS_LOW;
0129         break;
0130     case DVS_SEL_V2:
0131         pin1 = DVS_LOW;
0132         pin2 = DVS_HIGH;
0133         break;
0134     case DVS_SEL_V3:
0135         pin1 = DVS_HIGH;
0136         pin2 = DVS_HIGH;
0137         break;
0138     default:
0139         return;
0140     }
0141 
0142     if (gpio_is_valid(dvs->gpio[0]))
0143         gpio_set_value(dvs->gpio[0], pin1);
0144 
0145     if (gpio_is_valid(dvs->gpio[1]))
0146         gpio_set_value(dvs->gpio[1], pin2);
0147 }
0148 
0149 static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
0150 {
0151     switch (id) {
0152     case BUCK1:
0153         lp8788_buck1_set_dvs(buck);
0154         break;
0155     case BUCK2:
0156         lp8788_buck2_set_dvs(buck);
0157         break;
0158     default:
0159         break;
0160     }
0161 }
0162 
0163 static enum lp8788_dvs_mode
0164 lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck *buck, enum lp8788_buck_id id)
0165 {
0166     u8 val, mask;
0167 
0168     switch (id) {
0169     case BUCK1:
0170         mask = LP8788_BUCK1_DVS_SEL_M;
0171         break;
0172     case BUCK2:
0173         mask = LP8788_BUCK2_DVS_SEL_M;
0174         break;
0175     default:
0176         return REGISTER;
0177     }
0178 
0179     lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
0180 
0181     return val & mask ? REGISTER : EXTPIN;
0182 }
0183 
0184 static bool lp8788_is_valid_buck_addr(u8 addr)
0185 {
0186     switch (addr) {
0187     case LP8788_BUCK1_VOUT0:
0188     case LP8788_BUCK1_VOUT1:
0189     case LP8788_BUCK1_VOUT2:
0190     case LP8788_BUCK1_VOUT3:
0191     case LP8788_BUCK2_VOUT0:
0192     case LP8788_BUCK2_VOUT1:
0193     case LP8788_BUCK2_VOUT2:
0194     case LP8788_BUCK2_VOUT3:
0195         return true;
0196     default:
0197         return false;
0198     }
0199 }
0200 
0201 static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
0202                     enum lp8788_buck_id id)
0203 {
0204     enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id);
0205     struct lp8788_buck1_dvs *b1_dvs;
0206     struct lp8788_buck2_dvs *b2_dvs;
0207     u8 val, idx, addr;
0208     int pin1, pin2;
0209 
0210     switch (id) {
0211     case BUCK1:
0212         if (mode == EXTPIN) {
0213             b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs;
0214             if (!b1_dvs)
0215                 goto err;
0216 
0217             idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0;
0218         } else {
0219             lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
0220             idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
0221         }
0222         addr = LP8788_BUCK1_VOUT0 + idx;
0223         break;
0224     case BUCK2:
0225         if (mode == EXTPIN) {
0226             b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs;
0227             if (!b2_dvs)
0228                 goto err;
0229 
0230             pin1 = gpio_get_value(b2_dvs->gpio[0]);
0231             pin2 = gpio_get_value(b2_dvs->gpio[1]);
0232 
0233             if (pin1 == PIN_LOW && pin2 == PIN_LOW)
0234                 idx = 0;
0235             else if (pin1 == PIN_LOW && pin2 == PIN_HIGH)
0236                 idx = 2;
0237             else if (pin1 == PIN_HIGH && pin2 == PIN_LOW)
0238                 idx = 1;
0239             else
0240                 idx = 3;
0241         } else {
0242             lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
0243             idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S;
0244         }
0245         addr = LP8788_BUCK2_VOUT0 + idx;
0246         break;
0247     default:
0248         goto err;
0249     }
0250 
0251     return addr;
0252 err:
0253     return INVALID_ADDR;
0254 }
0255 
0256 static int lp8788_buck12_set_voltage_sel(struct regulator_dev *rdev,
0257                     unsigned selector)
0258 {
0259     struct lp8788_buck *buck = rdev_get_drvdata(rdev);
0260     enum lp8788_buck_id id = rdev_get_id(rdev);
0261     u8 addr;
0262 
0263     if (buck->dvs)
0264         lp8788_set_dvs(buck, id);
0265 
0266     addr = lp8788_select_buck_vout_addr(buck, id);
0267     if (!lp8788_is_valid_buck_addr(addr))
0268         return -EINVAL;
0269 
0270     return lp8788_update_bits(buck->lp, addr, LP8788_VOUT_M, selector);
0271 }
0272 
0273 static int lp8788_buck12_get_voltage_sel(struct regulator_dev *rdev)
0274 {
0275     struct lp8788_buck *buck = rdev_get_drvdata(rdev);
0276     enum lp8788_buck_id id = rdev_get_id(rdev);
0277     int ret;
0278     u8 val, addr;
0279 
0280     addr = lp8788_select_buck_vout_addr(buck, id);
0281     if (!lp8788_is_valid_buck_addr(addr))
0282         return -EINVAL;
0283 
0284     ret = lp8788_read_byte(buck->lp, addr, &val);
0285     if (ret)
0286         return ret;
0287 
0288     return val & LP8788_VOUT_M;
0289 }
0290 
0291 static int lp8788_buck_enable_time(struct regulator_dev *rdev)
0292 {
0293     struct lp8788_buck *buck = rdev_get_drvdata(rdev);
0294     enum lp8788_buck_id id = rdev_get_id(rdev);
0295     u8 val, addr = LP8788_BUCK1_TIMESTEP + id;
0296 
0297     if (lp8788_read_byte(buck->lp, addr, &val))
0298         return -EINVAL;
0299 
0300     val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
0301 
0302     return ENABLE_TIME_USEC * val;
0303 }
0304 
0305 static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
0306 {
0307     struct lp8788_buck *buck = rdev_get_drvdata(rdev);
0308     enum lp8788_buck_id id = rdev_get_id(rdev);
0309     u8 mask, val;
0310 
0311     mask = BUCK_FPWM_MASK(id);
0312     switch (mode) {
0313     case REGULATOR_MODE_FAST:
0314         val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id);
0315         break;
0316     case REGULATOR_MODE_NORMAL:
0317         val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id);
0318         break;
0319     default:
0320         return -EINVAL;
0321     }
0322 
0323     return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val);
0324 }
0325 
0326 static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
0327 {
0328     struct lp8788_buck *buck = rdev_get_drvdata(rdev);
0329     enum lp8788_buck_id id = rdev_get_id(rdev);
0330     u8 val;
0331     int ret;
0332 
0333     ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val);
0334     if (ret)
0335         return ret;
0336 
0337     return val & BUCK_FPWM_MASK(id) ?
0338                 REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
0339 }
0340 
0341 static const struct regulator_ops lp8788_buck12_ops = {
0342     .list_voltage = regulator_list_voltage_linear_range,
0343     .map_voltage = regulator_map_voltage_linear_range,
0344     .set_voltage_sel = lp8788_buck12_set_voltage_sel,
0345     .get_voltage_sel = lp8788_buck12_get_voltage_sel,
0346     .enable = regulator_enable_regmap,
0347     .disable = regulator_disable_regmap,
0348     .is_enabled = regulator_is_enabled_regmap,
0349     .enable_time = lp8788_buck_enable_time,
0350     .set_mode = lp8788_buck_set_mode,
0351     .get_mode = lp8788_buck_get_mode,
0352 };
0353 
0354 static const struct regulator_ops lp8788_buck34_ops = {
0355     .list_voltage = regulator_list_voltage_linear_range,
0356     .map_voltage = regulator_map_voltage_linear_range,
0357     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0358     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0359     .enable = regulator_enable_regmap,
0360     .disable = regulator_disable_regmap,
0361     .is_enabled = regulator_is_enabled_regmap,
0362     .enable_time = lp8788_buck_enable_time,
0363     .set_mode = lp8788_buck_set_mode,
0364     .get_mode = lp8788_buck_get_mode,
0365 };
0366 
0367 static const struct regulator_desc lp8788_buck_desc[] = {
0368     {
0369         .name = "buck1",
0370         .id = BUCK1,
0371         .ops = &lp8788_buck12_ops,
0372         .n_voltages = 26,
0373         .linear_ranges = buck_volt_ranges,
0374         .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
0375         .type = REGULATOR_VOLTAGE,
0376         .owner = THIS_MODULE,
0377         .enable_reg = LP8788_EN_BUCK,
0378         .enable_mask = LP8788_EN_BUCK1_M,
0379     },
0380     {
0381         .name = "buck2",
0382         .id = BUCK2,
0383         .ops = &lp8788_buck12_ops,
0384         .n_voltages = 26,
0385         .linear_ranges = buck_volt_ranges,
0386         .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
0387         .type = REGULATOR_VOLTAGE,
0388         .owner = THIS_MODULE,
0389         .enable_reg = LP8788_EN_BUCK,
0390         .enable_mask = LP8788_EN_BUCK2_M,
0391     },
0392     {
0393         .name = "buck3",
0394         .id = BUCK3,
0395         .ops = &lp8788_buck34_ops,
0396         .n_voltages = 26,
0397         .linear_ranges = buck_volt_ranges,
0398         .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
0399         .type = REGULATOR_VOLTAGE,
0400         .owner = THIS_MODULE,
0401         .vsel_reg = LP8788_BUCK3_VOUT,
0402         .vsel_mask = LP8788_VOUT_M,
0403         .enable_reg = LP8788_EN_BUCK,
0404         .enable_mask = LP8788_EN_BUCK3_M,
0405     },
0406     {
0407         .name = "buck4",
0408         .id = BUCK4,
0409         .ops = &lp8788_buck34_ops,
0410         .n_voltages = 26,
0411         .linear_ranges = buck_volt_ranges,
0412         .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
0413         .type = REGULATOR_VOLTAGE,
0414         .owner = THIS_MODULE,
0415         .vsel_reg = LP8788_BUCK4_VOUT,
0416         .vsel_mask = LP8788_VOUT_M,
0417         .enable_reg = LP8788_EN_BUCK,
0418         .enable_mask = LP8788_EN_BUCK4_M,
0419     },
0420 };
0421 
0422 static int lp8788_dvs_gpio_request(struct platform_device *pdev,
0423                 struct lp8788_buck *buck,
0424                 enum lp8788_buck_id id)
0425 {
0426     struct lp8788_platform_data *pdata = buck->lp->pdata;
0427     char *b1_name = "LP8788_B1_DVS";
0428     char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" };
0429     int i, gpio, ret;
0430 
0431     switch (id) {
0432     case BUCK1:
0433         gpio = pdata->buck1_dvs->gpio;
0434         ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW,
0435                         b1_name);
0436         if (ret)
0437             return ret;
0438 
0439         buck->dvs = pdata->buck1_dvs;
0440         break;
0441     case BUCK2:
0442         for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) {
0443             gpio = pdata->buck2_dvs->gpio[i];
0444             ret = devm_gpio_request_one(&pdev->dev, gpio,
0445                             DVS_LOW, b2_name[i]);
0446             if (ret)
0447                 return ret;
0448         }
0449         buck->dvs = pdata->buck2_dvs;
0450         break;
0451     default:
0452         break;
0453     }
0454 
0455     return 0;
0456 }
0457 
0458 static int lp8788_init_dvs(struct platform_device *pdev,
0459             struct lp8788_buck *buck, enum lp8788_buck_id id)
0460 {
0461     struct lp8788_platform_data *pdata = buck->lp->pdata;
0462     u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
0463     u8 val[]  = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN };
0464     u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
0465 
0466     /* no dvs for buck3, 4 */
0467     if (id > BUCK2)
0468         return 0;
0469 
0470     /* no dvs platform data, then dvs will be selected by I2C registers */
0471     if (!pdata)
0472         goto set_default_dvs_mode;
0473 
0474     if ((id == BUCK1 && !pdata->buck1_dvs) ||
0475         (id == BUCK2 && !pdata->buck2_dvs))
0476         goto set_default_dvs_mode;
0477 
0478     if (lp8788_dvs_gpio_request(pdev, buck, id))
0479         goto set_default_dvs_mode;
0480 
0481     return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
0482                 val[id]);
0483 
0484 set_default_dvs_mode:
0485     return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
0486                   default_dvs_mode[id]);
0487 }
0488 
0489 static int lp8788_buck_probe(struct platform_device *pdev)
0490 {
0491     struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
0492     int id = pdev->id;
0493     struct lp8788_buck *buck;
0494     struct regulator_config cfg = { };
0495     struct regulator_dev *rdev;
0496     int ret;
0497 
0498     if (id >= LP8788_NUM_BUCKS)
0499         return -EINVAL;
0500 
0501     buck = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_buck), GFP_KERNEL);
0502     if (!buck)
0503         return -ENOMEM;
0504 
0505     buck->lp = lp;
0506 
0507     ret = lp8788_init_dvs(pdev, buck, id);
0508     if (ret)
0509         return ret;
0510 
0511     cfg.dev = pdev->dev.parent;
0512     cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL;
0513     cfg.driver_data = buck;
0514     cfg.regmap = lp->regmap;
0515 
0516     rdev = devm_regulator_register(&pdev->dev, &lp8788_buck_desc[id], &cfg);
0517     if (IS_ERR(rdev)) {
0518         ret = PTR_ERR(rdev);
0519         dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n",
0520                 id + 1, ret);
0521         return ret;
0522     }
0523 
0524     buck->regulator = rdev;
0525     platform_set_drvdata(pdev, buck);
0526 
0527     return 0;
0528 }
0529 
0530 static struct platform_driver lp8788_buck_driver = {
0531     .probe = lp8788_buck_probe,
0532     .driver = {
0533         .name = LP8788_DEV_BUCK,
0534     },
0535 };
0536 
0537 static int __init lp8788_buck_init(void)
0538 {
0539     return platform_driver_register(&lp8788_buck_driver);
0540 }
0541 subsys_initcall(lp8788_buck_init);
0542 
0543 static void __exit lp8788_buck_exit(void)
0544 {
0545     platform_driver_unregister(&lp8788_buck_driver);
0546 }
0547 module_exit(lp8788_buck_exit);
0548 
0549 MODULE_DESCRIPTION("TI LP8788 BUCK Driver");
0550 MODULE_AUTHOR("Milo Kim");
0551 MODULE_LICENSE("GPL");
0552 MODULE_ALIAS("platform:lp8788-buck");