Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * TI TPS65132 Regulator driver
0003  *
0004  * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
0005  *
0006  * Author: Venkat Reddy Talla <vreddytalla@nvidia.com>
0007  *      Laxman Dewangan <ldewangan@nvidia.com>
0008  *
0009  * This program is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU General Public License as
0011  * published by the Free Software Foundation; either version 2 of the
0012  * License, or (at your option) any later version.
0013  *
0014  * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
0015  * whether express or implied; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * General Public License for more details.
0018  */
0019 
0020 #include <linux/delay.h>
0021 #include <linux/err.h>
0022 #include <linux/gpio/consumer.h>
0023 #include <linux/i2c.h>
0024 #include <linux/module.h>
0025 #include <linux/regmap.h>
0026 #include <linux/regulator/driver.h>
0027 #include <linux/regulator/machine.h>
0028 
0029 #define TPS65132_REG_VPOS       0x00
0030 #define TPS65132_REG_VNEG       0x01
0031 #define TPS65132_REG_APPS_DISP_DISN 0x03
0032 #define TPS65132_REG_CONTROL        0x0FF
0033 
0034 #define TPS65132_VOUT_MASK      0x1F
0035 #define TPS65132_VOUT_N_VOLTAGE     0x15
0036 #define TPS65132_VOUT_VMIN      4000000
0037 #define TPS65132_VOUT_VMAX      6000000
0038 #define TPS65132_VOUT_STEP      100000
0039 
0040 #define TPS65132_REG_APPS_DIS_VPOS      BIT(0)
0041 #define TPS65132_REG_APPS_DIS_VNEG      BIT(1)
0042 
0043 #define TPS65132_REGULATOR_ID_VPOS  0
0044 #define TPS65132_REGULATOR_ID_VNEG  1
0045 #define TPS65132_MAX_REGULATORS     2
0046 
0047 #define TPS65132_ACT_DIS_TIME_SLACK     1000
0048 
0049 struct tps65132_reg_pdata {
0050     struct gpio_desc *en_gpiod;
0051     struct gpio_desc *act_dis_gpiod;
0052     unsigned int act_dis_time_us;
0053     int ena_gpio_state;
0054 };
0055 
0056 struct tps65132_regulator {
0057     struct device *dev;
0058     struct tps65132_reg_pdata reg_pdata[TPS65132_MAX_REGULATORS];
0059 };
0060 
0061 static int tps65132_regulator_enable(struct regulator_dev *rdev)
0062 {
0063     struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
0064     int id = rdev_get_id(rdev);
0065     struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
0066     int ret;
0067 
0068     if (!IS_ERR(rpdata->en_gpiod)) {
0069         gpiod_set_value_cansleep(rpdata->en_gpiod, 1);
0070         rpdata->ena_gpio_state = 1;
0071     }
0072 
0073     /* Hardware automatically enable discharge bit in enable */
0074     if (rdev->constraints->active_discharge ==
0075             REGULATOR_ACTIVE_DISCHARGE_DISABLE) {
0076         ret = regulator_set_active_discharge_regmap(rdev, false);
0077         if (ret < 0) {
0078             dev_err(tps->dev, "Failed to disable active discharge: %d\n",
0079                 ret);
0080             return ret;
0081         }
0082     }
0083 
0084     return 0;
0085 }
0086 
0087 static int tps65132_regulator_disable(struct regulator_dev *rdev)
0088 {
0089     struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
0090     int id = rdev_get_id(rdev);
0091     struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
0092 
0093     if (!IS_ERR(rpdata->en_gpiod)) {
0094         gpiod_set_value_cansleep(rpdata->en_gpiod, 0);
0095         rpdata->ena_gpio_state = 0;
0096     }
0097 
0098     if (!IS_ERR(rpdata->act_dis_gpiod)) {
0099         gpiod_set_value_cansleep(rpdata->act_dis_gpiod, 1);
0100         usleep_range(rpdata->act_dis_time_us, rpdata->act_dis_time_us +
0101                  TPS65132_ACT_DIS_TIME_SLACK);
0102         gpiod_set_value_cansleep(rpdata->act_dis_gpiod, 0);
0103     }
0104 
0105     return 0;
0106 }
0107 
0108 static int tps65132_regulator_is_enabled(struct regulator_dev *rdev)
0109 {
0110     struct tps65132_regulator *tps = rdev_get_drvdata(rdev);
0111     int id = rdev_get_id(rdev);
0112     struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[id];
0113 
0114     if (!IS_ERR(rpdata->en_gpiod))
0115         return rpdata->ena_gpio_state;
0116 
0117     return 1;
0118 }
0119 
0120 static const struct regulator_ops tps65132_regulator_ops = {
0121     .enable = tps65132_regulator_enable,
0122     .disable = tps65132_regulator_disable,
0123     .is_enabled = tps65132_regulator_is_enabled,
0124     .list_voltage = regulator_list_voltage_linear,
0125     .map_voltage = regulator_map_voltage_linear,
0126     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0127     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0128     .set_active_discharge = regulator_set_active_discharge_regmap,
0129 };
0130 
0131 static int tps65132_of_parse_cb(struct device_node *np,
0132                 const struct regulator_desc *desc,
0133                 struct regulator_config *config)
0134 {
0135     struct tps65132_regulator *tps = config->driver_data;
0136     struct tps65132_reg_pdata *rpdata = &tps->reg_pdata[desc->id];
0137     int ret;
0138 
0139     rpdata->en_gpiod = devm_fwnode_gpiod_get(tps->dev, of_fwnode_handle(np),
0140                          "enable", GPIOD_ASIS,
0141                          "enable");
0142     if (IS_ERR(rpdata->en_gpiod)) {
0143         ret = PTR_ERR(rpdata->en_gpiod);
0144 
0145         /* Ignore the error other than probe defer */
0146         if (ret == -EPROBE_DEFER)
0147             return ret;
0148         return 0;
0149     }
0150 
0151     rpdata->act_dis_gpiod = devm_fwnode_gpiod_get(tps->dev,
0152                               of_fwnode_handle(np),
0153                               "active-discharge",
0154                               GPIOD_ASIS,
0155                               "active-discharge");
0156     if (IS_ERR(rpdata->act_dis_gpiod)) {
0157         ret = PTR_ERR(rpdata->act_dis_gpiod);
0158 
0159         /* Ignore the error other than probe defer */
0160         if (ret == -EPROBE_DEFER)
0161             return ret;
0162 
0163         return 0;
0164     }
0165 
0166     ret = of_property_read_u32(np, "ti,active-discharge-time-us",
0167                    &rpdata->act_dis_time_us);
0168     if (ret < 0) {
0169         dev_err(tps->dev, "Failed to read active discharge time:%d\n",
0170             ret);
0171         return ret;
0172     }
0173 
0174     return 0;
0175 }
0176 
0177 #define TPS65132_REGULATOR_DESC(_id, _name)     \
0178     [TPS65132_REGULATOR_ID_##_id] = {       \
0179         .name = "tps65132-"#_name,      \
0180         .supply_name = "vin",           \
0181         .id = TPS65132_REGULATOR_ID_##_id,  \
0182         .of_match = of_match_ptr(#_name),   \
0183         .of_parse_cb    = tps65132_of_parse_cb, \
0184         .ops = &tps65132_regulator_ops,     \
0185         .n_voltages = TPS65132_VOUT_N_VOLTAGE,  \
0186         .min_uV = TPS65132_VOUT_VMIN,       \
0187         .uV_step = TPS65132_VOUT_STEP,      \
0188         .enable_time = 500,         \
0189         .vsel_mask = TPS65132_VOUT_MASK,    \
0190         .vsel_reg = TPS65132_REG_##_id,     \
0191         .active_discharge_off = 0,          \
0192         .active_discharge_on = TPS65132_REG_APPS_DIS_##_id, \
0193         .active_discharge_mask = TPS65132_REG_APPS_DIS_##_id, \
0194         .active_discharge_reg = TPS65132_REG_APPS_DISP_DISN, \
0195         .type = REGULATOR_VOLTAGE,      \
0196         .owner = THIS_MODULE,           \
0197     }
0198 
0199 static const struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = {
0200     TPS65132_REGULATOR_DESC(VPOS, outp),
0201     TPS65132_REGULATOR_DESC(VNEG, outn),
0202 };
0203 
0204 static const struct regmap_range tps65132_no_reg_ranges[] = {
0205     regmap_reg_range(TPS65132_REG_APPS_DISP_DISN + 1,
0206              TPS65132_REG_CONTROL - 1),
0207 };
0208 
0209 static const struct regmap_access_table tps65132_no_reg_table = {
0210     .no_ranges = tps65132_no_reg_ranges,
0211     .n_no_ranges = ARRAY_SIZE(tps65132_no_reg_ranges),
0212 };
0213 
0214 static const struct regmap_config tps65132_regmap_config = {
0215     .reg_bits   = 8,
0216     .val_bits   = 8,
0217     .max_register   = TPS65132_REG_CONTROL,
0218     .cache_type = REGCACHE_NONE,
0219     .rd_table   = &tps65132_no_reg_table,
0220     .wr_table   = &tps65132_no_reg_table,
0221 };
0222 
0223 static int tps65132_probe(struct i2c_client *client)
0224 {
0225     struct device *dev = &client->dev;
0226     struct tps65132_regulator *tps;
0227     struct regulator_dev *rdev;
0228     struct regmap *rmap;
0229     struct regulator_config config = { };
0230     int id;
0231     int ret;
0232 
0233     tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
0234     if (!tps)
0235         return -ENOMEM;
0236 
0237     rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config);
0238     if (IS_ERR(rmap)) {
0239         ret = PTR_ERR(rmap);
0240         dev_err(dev, "regmap init failed: %d\n", ret);
0241         return ret;
0242     }
0243 
0244     i2c_set_clientdata(client, tps);
0245     tps->dev = dev;
0246 
0247     for (id = 0; id < TPS65132_MAX_REGULATORS; ++id) {
0248         config.regmap = rmap;
0249         config.dev = dev;
0250         config.driver_data = tps;
0251 
0252         rdev = devm_regulator_register(dev, &tps_regs_desc[id],
0253                            &config);
0254         if (IS_ERR(rdev)) {
0255             ret = PTR_ERR(rdev);
0256             dev_err(dev, "regulator %s register failed: %d\n",
0257                 tps_regs_desc[id].name, ret);
0258             return ret;
0259         }
0260     }
0261     return 0;
0262 }
0263 
0264 static const struct i2c_device_id tps65132_id[] = {
0265     {.name = "tps65132",},
0266     {},
0267 };
0268 MODULE_DEVICE_TABLE(i2c, tps65132_id);
0269 
0270 static struct i2c_driver tps65132_i2c_driver = {
0271     .driver = {
0272         .name = "tps65132",
0273     },
0274     .probe_new = tps65132_probe,
0275     .id_table = tps65132_id,
0276 };
0277 
0278 module_i2c_driver(tps65132_i2c_driver);
0279 
0280 MODULE_DESCRIPTION("tps65132 regulator driver");
0281 MODULE_AUTHOR("Venkat Reddy Talla <vreddytalla@nvidia.com>");
0282 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
0283 MODULE_LICENSE("GPL v2");