Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 
0003 #include <linux/delay.h>
0004 #include <linux/gpio/consumer.h>
0005 #include <linux/i2c.h>
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/property.h>
0009 #include <linux/regmap.h>
0010 #include <linux/regulator/driver.h>
0011 #include <linux/regulator/of_regulator.h>
0012 
0013 #define RT6160_MODE_AUTO    0
0014 #define RT6160_MODE_FPWM    1
0015 
0016 #define RT6160_REG_CNTL     0x01
0017 #define RT6160_REG_STATUS   0x02
0018 #define RT6160_REG_DEVID    0x03
0019 #define RT6160_REG_VSELL    0x04
0020 #define RT6160_REG_VSELH    0x05
0021 #define RT6160_NUM_REGS     (RT6160_REG_VSELH + 1)
0022 
0023 #define RT6160_FPWM_MASK    BIT(3)
0024 #define RT6160_RAMPRATE_MASK    GENMASK(1, 0)
0025 #define RT6160_VID_MASK     GENMASK(7, 4)
0026 #define RT6160_VSEL_MASK    GENMASK(6, 0)
0027 #define RT6160_HDSTAT_MASK  BIT(4)
0028 #define RT6160_UVSTAT_MASK  BIT(3)
0029 #define RT6160_OCSTAT_MASK  BIT(2)
0030 #define RT6160_TSDSTAT_MASK BIT(1)
0031 #define RT6160_PGSTAT_MASK  BIT(0)
0032 
0033 #define RT6160_VENDOR_ID    0xA0
0034 #define RT6160_VOUT_MINUV   2025000
0035 #define RT6160_VOUT_MAXUV   5200000
0036 #define RT6160_VOUT_STPUV   25000
0037 #define RT6160_N_VOUTS      ((RT6160_VOUT_MAXUV - RT6160_VOUT_MINUV) / RT6160_VOUT_STPUV + 1)
0038 
0039 #define RT6160_I2CRDY_TIMEUS    100
0040 
0041 struct rt6160_priv {
0042     struct regulator_desc desc;
0043     struct gpio_desc *enable_gpio;
0044     struct regmap *regmap;
0045     bool enable_state;
0046 };
0047 
0048 static const unsigned int rt6160_ramp_tables[] = {
0049     1000, 2500, 5000, 10000
0050 };
0051 
0052 static int rt6160_enable(struct regulator_dev *rdev)
0053 {
0054     struct rt6160_priv *priv = rdev_get_drvdata(rdev);
0055 
0056     if (!priv->enable_gpio)
0057         return 0;
0058 
0059     gpiod_set_value_cansleep(priv->enable_gpio, 1);
0060     priv->enable_state = true;
0061 
0062     usleep_range(RT6160_I2CRDY_TIMEUS, RT6160_I2CRDY_TIMEUS + 100);
0063 
0064     regcache_cache_only(priv->regmap, false);
0065     return regcache_sync(priv->regmap);
0066 }
0067 
0068 static int rt6160_disable(struct regulator_dev *rdev)
0069 {
0070     struct rt6160_priv *priv = rdev_get_drvdata(rdev);
0071 
0072     if (!priv->enable_gpio)
0073         return -EINVAL;
0074 
0075     /* Mark regcache as dirty and cache only before HW disabled */
0076     regcache_cache_only(priv->regmap, true);
0077     regcache_mark_dirty(priv->regmap);
0078 
0079     priv->enable_state = false;
0080     gpiod_set_value_cansleep(priv->enable_gpio, 0);
0081 
0082     return 0;
0083 }
0084 
0085 static int rt6160_is_enabled(struct regulator_dev *rdev)
0086 {
0087     struct rt6160_priv *priv = rdev_get_drvdata(rdev);
0088 
0089     return priv->enable_state ? 1 : 0;
0090 }
0091 
0092 static int rt6160_set_mode(struct regulator_dev *rdev, unsigned int mode)
0093 {
0094     struct regmap *regmap = rdev_get_regmap(rdev);
0095     unsigned int mode_val;
0096 
0097     switch (mode) {
0098     case REGULATOR_MODE_FAST:
0099         mode_val = RT6160_FPWM_MASK;
0100         break;
0101     case REGULATOR_MODE_NORMAL:
0102         mode_val = 0;
0103         break;
0104     default:
0105         dev_err(&rdev->dev, "mode not supported\n");
0106         return -EINVAL;
0107     }
0108 
0109     return regmap_update_bits(regmap, RT6160_REG_CNTL, RT6160_FPWM_MASK, mode_val);
0110 }
0111 
0112 static unsigned int rt6160_get_mode(struct regulator_dev *rdev)
0113 {
0114     struct regmap *regmap = rdev_get_regmap(rdev);
0115     unsigned int val;
0116     int ret;
0117 
0118     ret = regmap_read(regmap, RT6160_REG_CNTL, &val);
0119     if (ret)
0120         return ret;
0121 
0122     if (val & RT6160_FPWM_MASK)
0123         return REGULATOR_MODE_FAST;
0124 
0125     return REGULATOR_MODE_NORMAL;
0126 }
0127 
0128 static int rt6160_set_suspend_voltage(struct regulator_dev *rdev, int uV)
0129 {
0130     struct regmap *regmap = rdev_get_regmap(rdev);
0131     unsigned int suspend_vsel_reg;
0132     int vsel;
0133 
0134     vsel = regulator_map_voltage_linear(rdev, uV, uV);
0135     if (vsel < 0)
0136         return vsel;
0137 
0138     if (rdev->desc->vsel_reg == RT6160_REG_VSELL)
0139         suspend_vsel_reg = RT6160_REG_VSELH;
0140     else
0141         suspend_vsel_reg = RT6160_REG_VSELL;
0142 
0143     return regmap_update_bits(regmap, suspend_vsel_reg,
0144                   RT6160_VSEL_MASK, vsel);
0145 }
0146 
0147 static int rt6160_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
0148 {
0149     struct regmap *regmap = rdev_get_regmap(rdev);
0150     unsigned int val, events = 0;
0151     int ret;
0152 
0153     ret = regmap_read(regmap, RT6160_REG_STATUS, &val);
0154     if (ret)
0155         return ret;
0156 
0157     if (val & (RT6160_HDSTAT_MASK | RT6160_TSDSTAT_MASK))
0158         events |= REGULATOR_ERROR_OVER_TEMP;
0159 
0160     if (val & RT6160_UVSTAT_MASK)
0161         events |= REGULATOR_ERROR_UNDER_VOLTAGE;
0162 
0163     if (val & RT6160_OCSTAT_MASK)
0164         events |= REGULATOR_ERROR_OVER_CURRENT;
0165 
0166     if (val & RT6160_PGSTAT_MASK)
0167         events |= REGULATOR_ERROR_FAIL;
0168 
0169     *flags = events;
0170     return 0;
0171 }
0172 
0173 static const struct regulator_ops rt6160_regulator_ops = {
0174     .list_voltage = regulator_list_voltage_linear,
0175     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0176     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0177 
0178     .enable = rt6160_enable,
0179     .disable = rt6160_disable,
0180     .is_enabled = rt6160_is_enabled,
0181 
0182     .set_mode = rt6160_set_mode,
0183     .get_mode = rt6160_get_mode,
0184     .set_suspend_voltage = rt6160_set_suspend_voltage,
0185     .set_ramp_delay = regulator_set_ramp_delay_regmap,
0186     .get_error_flags = rt6160_get_error_flags,
0187 };
0188 
0189 static unsigned int rt6160_of_map_mode(unsigned int mode)
0190 {
0191     switch (mode) {
0192     case RT6160_MODE_FPWM:
0193         return REGULATOR_MODE_FAST;
0194     case RT6160_MODE_AUTO:
0195         return REGULATOR_MODE_NORMAL;
0196     }
0197 
0198     return REGULATOR_MODE_INVALID;
0199 }
0200 
0201 static bool rt6160_is_accessible_reg(struct device *dev, unsigned int reg)
0202 {
0203     if (reg >= RT6160_REG_CNTL && reg <= RT6160_REG_VSELH)
0204         return true;
0205     return false;
0206 }
0207 
0208 static bool rt6160_is_volatile_reg(struct device *dev, unsigned int reg)
0209 {
0210     if (reg == RT6160_REG_STATUS)
0211         return true;
0212     return false;
0213 }
0214 
0215 static const struct regmap_config rt6160_regmap_config = {
0216     .reg_bits = 8,
0217     .val_bits = 8,
0218     .max_register = RT6160_REG_VSELH,
0219     .num_reg_defaults_raw = RT6160_NUM_REGS,
0220     .cache_type = REGCACHE_FLAT,
0221 
0222     .writeable_reg = rt6160_is_accessible_reg,
0223     .readable_reg = rt6160_is_accessible_reg,
0224     .volatile_reg = rt6160_is_volatile_reg,
0225 };
0226 
0227 static int rt6160_probe(struct i2c_client *i2c)
0228 {
0229     struct rt6160_priv *priv;
0230     struct regulator_config regulator_cfg = {};
0231     struct regulator_dev *rdev;
0232     bool vsel_active_low;
0233     unsigned int devid;
0234     int ret;
0235 
0236     priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
0237     if (!priv)
0238         return -ENOMEM;
0239 
0240     vsel_active_low =
0241         device_property_present(&i2c->dev, "richtek,vsel-active-low");
0242 
0243     priv->enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
0244     if (IS_ERR(priv->enable_gpio)) {
0245         dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
0246         return PTR_ERR(priv->enable_gpio);
0247     }
0248     priv->enable_state = true;
0249 
0250     usleep_range(RT6160_I2CRDY_TIMEUS, RT6160_I2CRDY_TIMEUS + 100);
0251 
0252     priv->regmap = devm_regmap_init_i2c(i2c, &rt6160_regmap_config);
0253     if (IS_ERR(priv->regmap)) {
0254         ret = PTR_ERR(priv->regmap);
0255         dev_err(&i2c->dev, "Failed to init regmap (%d)\n", ret);
0256         return ret;
0257     }
0258 
0259     ret = regmap_read(priv->regmap, RT6160_REG_DEVID, &devid);
0260     if (ret)
0261         return ret;
0262 
0263     if ((devid & RT6160_VID_MASK) != RT6160_VENDOR_ID) {
0264         dev_err(&i2c->dev, "VID not correct [0x%02x]\n", devid);
0265         return -ENODEV;
0266     }
0267 
0268     priv->desc.name = "rt6160-buckboost";
0269     priv->desc.type = REGULATOR_VOLTAGE;
0270     priv->desc.owner = THIS_MODULE;
0271     priv->desc.min_uV = RT6160_VOUT_MINUV;
0272     priv->desc.uV_step = RT6160_VOUT_STPUV;
0273     if (vsel_active_low)
0274         priv->desc.vsel_reg = RT6160_REG_VSELL;
0275     else
0276         priv->desc.vsel_reg = RT6160_REG_VSELH;
0277     priv->desc.vsel_mask = RT6160_VSEL_MASK;
0278     priv->desc.n_voltages = RT6160_N_VOUTS;
0279     priv->desc.ramp_reg = RT6160_REG_CNTL;
0280     priv->desc.ramp_mask = RT6160_RAMPRATE_MASK;
0281     priv->desc.ramp_delay_table = rt6160_ramp_tables;
0282     priv->desc.n_ramp_values = ARRAY_SIZE(rt6160_ramp_tables);
0283     priv->desc.of_map_mode = rt6160_of_map_mode;
0284     priv->desc.ops = &rt6160_regulator_ops;
0285 
0286     regulator_cfg.dev = &i2c->dev;
0287     regulator_cfg.of_node = i2c->dev.of_node;
0288     regulator_cfg.regmap = priv->regmap;
0289     regulator_cfg.driver_data = priv;
0290     regulator_cfg.init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node,
0291                                  &priv->desc);
0292 
0293     rdev = devm_regulator_register(&i2c->dev, &priv->desc, &regulator_cfg);
0294     if (IS_ERR(rdev)) {
0295         dev_err(&i2c->dev, "Failed to register regulator\n");
0296         return PTR_ERR(rdev);
0297     }
0298 
0299     return 0;
0300 }
0301 
0302 static const struct of_device_id __maybe_unused rt6160_of_match_table[] = {
0303     { .compatible = "richtek,rt6160", },
0304     {}
0305 };
0306 MODULE_DEVICE_TABLE(of, rt6160_of_match_table);
0307 
0308 static struct i2c_driver rt6160_driver = {
0309     .driver = {
0310         .name = "rt6160",
0311         .of_match_table = rt6160_of_match_table,
0312     },
0313     .probe_new = rt6160_probe,
0314 };
0315 module_i2c_driver(rt6160_driver);
0316 
0317 MODULE_DESCRIPTION("Richtek RT6160 voltage regulator driver");
0318 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
0319 MODULE_LICENSE("GPL v2");