Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 
0003 #include <linux/bitops.h>
0004 #include <linux/delay.h>
0005 #include <linux/gpio/consumer.h>
0006 #include <linux/i2c.h>
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/regmap.h>
0010 #include <linux/regulator/driver.h>
0011 #include <linux/regulator/of_regulator.h>
0012 
0013 #define RT6245_VIRT_OCLIMIT 0x00
0014 #define RT6245_VIRT_OTLEVEL 0x01
0015 #define RT6245_VIRT_PGDLYTIME   0x02
0016 #define RT6245_VIRT_SLEWRATE    0x03
0017 #define RT6245_VIRT_SWFREQ  0x04
0018 #define RT6245_VIRT_VOUT    0x05
0019 
0020 #define RT6245_VOUT_MASK    GENMASK(6, 0)
0021 #define RT6245_SLEW_MASK    GENMASK(2, 0)
0022 #define RT6245_CHKSUM_MASK  BIT(7)
0023 #define RT6245_CODE_MASK    GENMASK(6, 0)
0024 
0025 /* HW Enable + Soft start time */
0026 #define RT6245_ENTIME_IN_US 5000
0027 
0028 #define RT6245_VOUT_MINUV   437500
0029 #define RT6245_VOUT_MAXUV   1387500
0030 #define RT6245_VOUT_STEPUV  12500
0031 #define RT6245_NUM_VOUT     ((RT6245_VOUT_MAXUV - RT6245_VOUT_MINUV) / RT6245_VOUT_STEPUV + 1)
0032 
0033 struct rt6245_priv {
0034     struct gpio_desc *enable_gpio;
0035     bool enable_state;
0036 };
0037 
0038 static int rt6245_enable(struct regulator_dev *rdev)
0039 {
0040     struct rt6245_priv *priv = rdev_get_drvdata(rdev);
0041     struct regmap *regmap = rdev_get_regmap(rdev);
0042     int ret;
0043 
0044     if (!priv->enable_gpio)
0045         return 0;
0046 
0047     gpiod_direction_output(priv->enable_gpio, 1);
0048     usleep_range(RT6245_ENTIME_IN_US, RT6245_ENTIME_IN_US + 1000);
0049 
0050     regcache_cache_only(regmap, false);
0051     ret = regcache_sync(regmap);
0052     if (ret)
0053         return ret;
0054 
0055     priv->enable_state = true;
0056     return 0;
0057 }
0058 
0059 static int rt6245_disable(struct regulator_dev *rdev)
0060 {
0061     struct rt6245_priv *priv = rdev_get_drvdata(rdev);
0062     struct regmap *regmap = rdev_get_regmap(rdev);
0063 
0064     if (!priv->enable_gpio)
0065         return -EINVAL;
0066 
0067     regcache_cache_only(regmap, true);
0068     regcache_mark_dirty(regmap);
0069 
0070     gpiod_direction_output(priv->enable_gpio, 0);
0071 
0072     priv->enable_state = false;
0073     return 0;
0074 }
0075 
0076 static int rt6245_is_enabled(struct regulator_dev *rdev)
0077 {
0078     struct rt6245_priv *priv = rdev_get_drvdata(rdev);
0079 
0080     return priv->enable_state ? 1 : 0;
0081 }
0082 
0083 static const struct regulator_ops rt6245_regulator_ops = {
0084     .list_voltage = regulator_list_voltage_linear,
0085     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0086     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0087     .set_ramp_delay = regulator_set_ramp_delay_regmap,
0088     .enable = rt6245_enable,
0089     .disable = rt6245_disable,
0090     .is_enabled = rt6245_is_enabled,
0091 };
0092 
0093 /* ramp delay dividend is 12500 uV/uS, and divisor from 1 to 8 */
0094 static const unsigned int rt6245_ramp_delay_table[] = {
0095     12500, 6250, 4167, 3125, 2500, 2083, 1786, 1562
0096 };
0097 
0098 static const struct regulator_desc rt6245_regulator_desc = {
0099     .name = "rt6245-regulator",
0100     .ops = &rt6245_regulator_ops,
0101     .type = REGULATOR_VOLTAGE,
0102     .min_uV = RT6245_VOUT_MINUV,
0103     .uV_step = RT6245_VOUT_STEPUV,
0104     .n_voltages = RT6245_NUM_VOUT,
0105     .ramp_delay_table = rt6245_ramp_delay_table,
0106     .n_ramp_values = ARRAY_SIZE(rt6245_ramp_delay_table),
0107     .owner = THIS_MODULE,
0108     .vsel_reg = RT6245_VIRT_VOUT,
0109     .vsel_mask = RT6245_VOUT_MASK,
0110     .ramp_reg = RT6245_VIRT_SLEWRATE,
0111     .ramp_mask = RT6245_SLEW_MASK,
0112 };
0113 
0114 static int rt6245_init_device_properties(struct device *dev)
0115 {
0116     const struct {
0117         const char *name;
0118         unsigned int reg;
0119     } rt6245_props[] = {
0120         { "richtek,oc-level-select",  RT6245_VIRT_OCLIMIT },
0121         { "richtek,ot-level-select", RT6245_VIRT_OTLEVEL },
0122         { "richtek,pgdly-time-select", RT6245_VIRT_PGDLYTIME },
0123         { "richtek,switch-freq-select", RT6245_VIRT_SWFREQ }
0124     };
0125     struct regmap *regmap = dev_get_regmap(dev, NULL);
0126     u8 propval;
0127     int i, ret;
0128 
0129     for (i = 0; i < ARRAY_SIZE(rt6245_props); i++) {
0130         ret = device_property_read_u8(dev, rt6245_props[i].name, &propval);
0131         if (ret)
0132             continue;
0133 
0134         ret = regmap_write(regmap, rt6245_props[i].reg, propval);
0135         if (ret) {
0136             dev_err(dev, "Fail to apply [%s:%d]\n", rt6245_props[i].name, propval);
0137             return ret;
0138         }
0139     }
0140 
0141     return 0;
0142 }
0143 
0144 static int rt6245_reg_write(void *context, unsigned int reg, unsigned int val)
0145 {
0146     struct i2c_client *i2c = context;
0147     static const u8 func_base[] = { 0x6F, 0x73, 0x78, 0x61, 0x7C, 0 };
0148     unsigned int code, bit_count;
0149 
0150     code = func_base[reg];
0151     code += val;
0152 
0153     /* xor checksum for bit 6 to 0 */
0154     bit_count = hweight8(code & RT6245_CODE_MASK);
0155     if (bit_count % 2)
0156         code |= RT6245_CHKSUM_MASK;
0157     else
0158         code &= ~RT6245_CHKSUM_MASK;
0159 
0160     return i2c_smbus_write_byte(i2c, code);
0161 }
0162 
0163 static const struct reg_default rt6245_reg_defaults[] = {
0164     /* Default over current 14A */
0165     { RT6245_VIRT_OCLIMIT, 2 },
0166     /* Default over temperature 150'c */
0167     { RT6245_VIRT_OTLEVEL, 0 },
0168     /* Default power good delay time 10us */
0169     { RT6245_VIRT_PGDLYTIME, 1 },
0170     /* Default slewrate 12.5mV/uS */
0171     { RT6245_VIRT_SLEWRATE, 0 },
0172     /* Default switch frequency 800KHz */
0173     { RT6245_VIRT_SWFREQ, 1 },
0174     /* Default voltage 750mV */
0175     { RT6245_VIRT_VOUT, 0x19 }
0176 };
0177 
0178 static const struct regmap_config rt6245_regmap_config = {
0179     .reg_bits = 8,
0180     .val_bits = 8,
0181     .max_register = RT6245_VIRT_VOUT,
0182     .cache_type = REGCACHE_FLAT,
0183     .reg_defaults = rt6245_reg_defaults,
0184     .num_reg_defaults = ARRAY_SIZE(rt6245_reg_defaults),
0185     .reg_write = rt6245_reg_write,
0186 };
0187 
0188 static int rt6245_probe(struct i2c_client *i2c)
0189 {
0190     struct rt6245_priv *priv;
0191     struct regmap *regmap;
0192     struct regulator_config regulator_cfg = {};
0193     struct regulator_dev *rdev;
0194     int ret;
0195 
0196     priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
0197     if (!priv)
0198         return -ENOMEM;
0199 
0200     priv->enable_state = true;
0201 
0202     priv->enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
0203     if (IS_ERR(priv->enable_gpio)) {
0204         dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
0205         return PTR_ERR(priv->enable_gpio);
0206     }
0207 
0208     usleep_range(RT6245_ENTIME_IN_US, RT6245_ENTIME_IN_US + 1000);
0209 
0210     regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt6245_regmap_config);
0211     if (IS_ERR(regmap)) {
0212         dev_err(&i2c->dev, "Failed to initialize the regmap\n");
0213         return PTR_ERR(regmap);
0214     }
0215 
0216     ret = rt6245_init_device_properties(&i2c->dev);
0217     if (ret) {
0218         dev_err(&i2c->dev, "Failed to initialize device properties\n");
0219         return ret;
0220     }
0221 
0222     regulator_cfg.dev = &i2c->dev;
0223     regulator_cfg.of_node = i2c->dev.of_node;
0224     regulator_cfg.regmap = regmap;
0225     regulator_cfg.driver_data = priv;
0226     regulator_cfg.init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node,
0227                                  &rt6245_regulator_desc);
0228     rdev = devm_regulator_register(&i2c->dev, &rt6245_regulator_desc, &regulator_cfg);
0229     if (IS_ERR(rdev)) {
0230         dev_err(&i2c->dev, "Failed to register regulator\n");
0231         return PTR_ERR(rdev);
0232     }
0233 
0234     return 0;
0235 }
0236 
0237 static const struct of_device_id __maybe_unused rt6245_of_match_table[] = {
0238     { .compatible = "richtek,rt6245", },
0239     {}
0240 };
0241 MODULE_DEVICE_TABLE(of, rt6245_of_match_table);
0242 
0243 static struct i2c_driver rt6245_driver = {
0244     .driver = {
0245         .name = "rt6245",
0246         .of_match_table = rt6245_of_match_table,
0247     },
0248     .probe_new = rt6245_probe,
0249 };
0250 module_i2c_driver(rt6245_driver);
0251 
0252 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
0253 MODULE_DESCRIPTION("Richtek RT6245 Regulator Driver");
0254 MODULE_LICENSE("GPL v2");