Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Regulator driver for RICOH RC5T583 power management chip.
0004  *
0005  * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
0006  * Author: Laxman dewangan <ldewangan@nvidia.com>
0007  *
0008  * based on code
0009  *      Copyright (C) 2011 RICOH COMPANY,LTD
0010  */
0011 
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/slab.h>
0015 #include <linux/err.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regulator/driver.h>
0018 #include <linux/regulator/machine.h>
0019 #include <linux/gpio.h>
0020 #include <linux/mfd/rc5t583.h>
0021 
0022 struct rc5t583_regulator_info {
0023     int         deepsleep_id;
0024 
0025     /* Regulator register address.*/
0026     uint8_t         reg_disc_reg;
0027     uint8_t         disc_bit;
0028     uint8_t         deepsleep_reg;
0029 
0030     /* Regulator specific turn-on delay  and voltage settling time*/
0031     int         enable_uv_per_us;
0032 
0033     /* Used by regulator core */
0034     struct regulator_desc   desc;
0035 };
0036 
0037 static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
0038 {
0039     struct rc5t583_regulator_info *reg_info = rdev_get_drvdata(rdev);
0040     int vsel = regulator_get_voltage_sel_regmap(rdev);
0041     int curr_uV = regulator_list_voltage_linear(rdev, vsel);
0042 
0043     return DIV_ROUND_UP(curr_uV, reg_info->enable_uv_per_us);
0044 }
0045 
0046 static const struct regulator_ops rc5t583_ops = {
0047     .is_enabled     = regulator_is_enabled_regmap,
0048     .enable         = regulator_enable_regmap,
0049     .disable        = regulator_disable_regmap,
0050     .enable_time        = rc5t583_regulator_enable_time,
0051     .get_voltage_sel    = regulator_get_voltage_sel_regmap,
0052     .set_voltage_sel    = regulator_set_voltage_sel_regmap,
0053     .list_voltage       = regulator_list_voltage_linear,
0054     .map_voltage        = regulator_map_voltage_linear,
0055     .set_voltage_time_sel   = regulator_set_voltage_time_sel,
0056 };
0057 
0058 #define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
0059         _vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \
0060 {                               \
0061     .reg_disc_reg   = RC5T583_REG_##_disc_reg,      \
0062     .disc_bit   = _disc_bit,                \
0063     .deepsleep_reg  = RC5T583_REG_##_id##DAC_DS,        \
0064     .enable_uv_per_us = _enable_mv * 1000,          \
0065     .deepsleep_id   = RC5T583_DS_##_id,         \
0066     .desc = {                       \
0067         .name = "rc5t583-regulator-"#_id,       \
0068         .id = RC5T583_REGULATOR_##_id,          \
0069         .n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \
0070         .ops = &rc5t583_ops,                \
0071         .type = REGULATOR_VOLTAGE,          \
0072         .owner = THIS_MODULE,               \
0073         .vsel_reg = RC5T583_REG_##_id##DAC,     \
0074         .vsel_mask = _vout_mask,            \
0075         .enable_reg = RC5T583_REG_##_en_reg,        \
0076         .enable_mask = BIT(_en_bit),            \
0077         .min_uV = _min_mv * 1000,           \
0078         .uV_step = _step_uV,                \
0079         .ramp_delay = 40 * 1000,            \
0080     },                          \
0081 }
0082 
0083 static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = {
0084     RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4),
0085     RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14),
0086     RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14),
0087     RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14),
0088     RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160),
0089     RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160),
0090     RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160),
0091     RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160),
0092     RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133),
0093     RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267),
0094     RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133),
0095     RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233),
0096     RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233),
0097     RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
0098 };
0099 
0100 static int rc5t583_regulator_probe(struct platform_device *pdev)
0101 {
0102     struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
0103     struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
0104     struct regulator_config config = { };
0105     struct regulator_dev *rdev;
0106     struct rc5t583_regulator_info *ri;
0107     int ret;
0108     int id;
0109 
0110     if (!pdata) {
0111         dev_err(&pdev->dev, "No platform data, exiting...\n");
0112         return -ENODEV;
0113     }
0114 
0115     for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
0116         ri = &rc5t583_reg_info[id];
0117 
0118         if (ri->deepsleep_id == RC5T583_DS_NONE)
0119             goto skip_ext_pwr_config;
0120 
0121         ret = rc5t583_ext_power_req_config(rc5t583->dev,
0122                 ri->deepsleep_id,
0123                 pdata->regulator_ext_pwr_control[id],
0124                 pdata->regulator_deepsleep_slot[id]);
0125         /*
0126          * Configuring external control is not a major issue,
0127          * just give warning.
0128          */
0129         if (ret < 0)
0130             dev_warn(&pdev->dev,
0131                 "Failed to configure ext control %d\n", id);
0132 
0133 skip_ext_pwr_config:
0134         config.dev = &pdev->dev;
0135         config.init_data = pdata->reg_init_data[id];
0136         config.driver_data = ri;
0137         config.regmap = rc5t583->regmap;
0138 
0139         rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
0140         if (IS_ERR(rdev)) {
0141             dev_err(&pdev->dev, "Failed to register regulator %s\n",
0142                         ri->desc.name);
0143             return PTR_ERR(rdev);
0144         }
0145     }
0146     return 0;
0147 }
0148 
0149 static struct platform_driver rc5t583_regulator_driver = {
0150     .driver = {
0151         .name   = "rc5t583-regulator",
0152     },
0153     .probe      = rc5t583_regulator_probe,
0154 };
0155 
0156 static int __init rc5t583_regulator_init(void)
0157 {
0158     return platform_driver_register(&rc5t583_regulator_driver);
0159 }
0160 subsys_initcall(rc5t583_regulator_init);
0161 
0162 static void __exit rc5t583_regulator_exit(void)
0163 {
0164     platform_driver_unregister(&rc5t583_regulator_driver);
0165 }
0166 module_exit(rc5t583_regulator_exit);
0167 
0168 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
0169 MODULE_DESCRIPTION("RC5T583 regulator driver");
0170 MODULE_ALIAS("platform:rc5t583-regulator");
0171 MODULE_LICENSE("GPL v2");