1 /* 2 * Regulator driver for tps65090 power management chip. 3 * 4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 5 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/> 17 */ 18 19 #include <linux/module.h> 20 #include <linux/init.h> 21 #include <linux/gpio.h> 22 #include <linux/slab.h> 23 #include <linux/err.h> 24 #include <linux/platform_device.h> 25 #include <linux/regulator/driver.h> 26 #include <linux/regulator/machine.h> 27 #include <linux/mfd/tps65090.h> 28 29 struct tps65090_regulator { 30 struct device *dev; 31 struct regulator_desc *desc; 32 struct regulator_dev *rdev; 33 }; 34 35 static struct regulator_ops tps65090_ext_control_ops = { 36 }; 37 38 static struct regulator_ops tps65090_reg_contol_ops = { 39 .enable = regulator_enable_regmap, 40 .disable = regulator_disable_regmap, 41 .is_enabled = regulator_is_enabled_regmap, 42 }; 43 44 static struct regulator_ops tps65090_ldo_ops = { 45 }; 46 47 #define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \ 48 { \ 49 .name = "TPS65090_RAILS"#_id, \ 50 .supply_name = _sname, \ 51 .id = TPS65090_REGULATOR_##_id, \ 52 .ops = &_ops, \ 53 .enable_reg = _en_reg, \ 54 .enable_mask = BIT(0), \ 55 .type = REGULATOR_VOLTAGE, \ 56 .owner = THIS_MODULE, \ 57 } 58 59 static struct regulator_desc tps65090_regulator_desc[] = { 60 tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_reg_contol_ops), 61 tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_reg_contol_ops), 62 tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_reg_contol_ops), 63 tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_reg_contol_ops), 64 tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_reg_contol_ops), 65 tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_reg_contol_ops), 66 tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_reg_contol_ops), 67 tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), 68 tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), 69 tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), 70 tps65090_REG_DESC(LDO1, "vsys_l1", 0, tps65090_ldo_ops), 71 tps65090_REG_DESC(LDO2, "vsys_l2", 0, tps65090_ldo_ops), 72 }; 73 74 static inline bool is_dcdc(int id) 75 { 76 switch (id) { 77 case TPS65090_REGULATOR_DCDC1: 78 case TPS65090_REGULATOR_DCDC2: 79 case TPS65090_REGULATOR_DCDC3: 80 return true; 81 default: 82 return false; 83 } 84 } 85 86 static int tps65090_config_ext_control( 87 struct tps65090_regulator *ri, bool enable) 88 { 89 int ret; 90 struct device *parent = ri->dev->parent; 91 unsigned int reg_en_reg = ri->desc->enable_reg; 92 93 if (enable) 94 ret = tps65090_set_bits(parent, reg_en_reg, 1); 95 else 96 ret = tps65090_clr_bits(parent, reg_en_reg, 1); 97 if (ret < 0) 98 dev_err(ri->dev, "Error in updating reg 0x%x\n", reg_en_reg); 99 return ret; 100 } 101 102 static int tps65090_regulator_disable_ext_control( 103 struct tps65090_regulator *ri, 104 struct tps65090_regulator_plat_data *tps_pdata) 105 { 106 int ret = 0; 107 struct device *parent = ri->dev->parent; 108 unsigned int reg_en_reg = ri->desc->enable_reg; 109 110 /* 111 * First enable output for internal control if require. 112 * And then disable external control. 113 */ 114 if (tps_pdata->reg_init_data->constraints.always_on || 115 tps_pdata->reg_init_data->constraints.boot_on) { 116 ret = tps65090_set_bits(parent, reg_en_reg, 0); 117 if (ret < 0) { 118 dev_err(ri->dev, "Error in set reg 0x%x\n", reg_en_reg); 119 return ret; 120 } 121 } 122 return tps65090_config_ext_control(ri, false); 123 } 124 125 static void tps65090_configure_regulator_config( 126 struct tps65090_regulator_plat_data *tps_pdata, 127 struct regulator_config *config) 128 { 129 if (gpio_is_valid(tps_pdata->gpio)) { 130 int gpio_flag = GPIOF_OUT_INIT_LOW; 131 132 if (tps_pdata->reg_init_data->constraints.always_on || 133 tps_pdata->reg_init_data->constraints.boot_on) 134 gpio_flag = GPIOF_OUT_INIT_HIGH; 135 136 config->ena_gpio = tps_pdata->gpio; 137 config->ena_gpio_flags = gpio_flag; 138 } 139 } 140 141 static int tps65090_regulator_probe(struct platform_device *pdev) 142 { 143 struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); 144 struct tps65090_regulator *ri = NULL; 145 struct regulator_config config = { }; 146 struct regulator_dev *rdev; 147 struct tps65090_regulator_plat_data *tps_pdata; 148 struct tps65090_regulator *pmic; 149 struct tps65090_platform_data *tps65090_pdata; 150 int num; 151 int ret; 152 153 dev_dbg(&pdev->dev, "Probing regulator\n"); 154 155 tps65090_pdata = dev_get_platdata(pdev->dev.parent); 156 if (!tps65090_pdata) { 157 dev_err(&pdev->dev, "Platform data missing\n"); 158 return -EINVAL; 159 } 160 161 pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), 162 GFP_KERNEL); 163 if (!pmic) { 164 dev_err(&pdev->dev, "mem alloc for pmic failed\n"); 165 return -ENOMEM; 166 } 167 168 for (num = 0; num < TPS65090_REGULATOR_MAX; num++) { 169 tps_pdata = tps65090_pdata->reg_pdata[num]; 170 171 ri = &pmic[num]; 172 ri->dev = &pdev->dev; 173 ri->desc = &tps65090_regulator_desc[num]; 174 175 /* 176 * TPS5090 DCDC support the control from external digital input. 177 * Configure it as per platform data. 178 */ 179 if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data) { 180 if (tps_pdata->enable_ext_control) { 181 tps65090_configure_regulator_config( 182 tps_pdata, &config); 183 ri->desc->ops = &tps65090_ext_control_ops; 184 } else { 185 ret = tps65090_regulator_disable_ext_control( 186 ri, tps_pdata); 187 if (ret < 0) { 188 dev_err(&pdev->dev, 189 "failed disable ext control\n"); 190 goto scrub; 191 } 192 } 193 } 194 195 config.dev = &pdev->dev; 196 config.driver_data = ri; 197 config.regmap = tps65090_mfd->rmap; 198 if (tps_pdata) 199 config.init_data = tps_pdata->reg_init_data; 200 else 201 config.init_data = NULL; 202 203 rdev = regulator_register(ri->desc, &config); 204 if (IS_ERR(rdev)) { 205 dev_err(&pdev->dev, "failed to register regulator %s\n", 206 ri->desc->name); 207 ret = PTR_ERR(rdev); 208 goto scrub; 209 } 210 ri->rdev = rdev; 211 212 /* Enable external control if it is require */ 213 if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && 214 tps_pdata->enable_ext_control) { 215 ret = tps65090_config_ext_control(ri, true); 216 if (ret < 0) { 217 /* Increment num to get unregister rdev */ 218 num++; 219 goto scrub; 220 } 221 } 222 } 223 224 platform_set_drvdata(pdev, pmic); 225 return 0; 226 227 scrub: 228 while (--num >= 0) { 229 ri = &pmic[num]; 230 regulator_unregister(ri->rdev); 231 } 232 return ret; 233 } 234 235 static int tps65090_regulator_remove(struct platform_device *pdev) 236 { 237 struct tps65090_regulator *pmic = platform_get_drvdata(pdev); 238 struct tps65090_regulator *ri; 239 int num; 240 241 for (num = 0; num < TPS65090_REGULATOR_MAX; ++num) { 242 ri = &pmic[num]; 243 regulator_unregister(ri->rdev); 244 } 245 return 0; 246 } 247 248 static struct platform_driver tps65090_regulator_driver = { 249 .driver = { 250 .name = "tps65090-pmic", 251 .owner = THIS_MODULE, 252 }, 253 .probe = tps65090_regulator_probe, 254 .remove = tps65090_regulator_remove, 255 }; 256 257 static int __init tps65090_regulator_init(void) 258 { 259 return platform_driver_register(&tps65090_regulator_driver); 260 } 261 subsys_initcall(tps65090_regulator_init); 262 263 static void __exit tps65090_regulator_exit(void) 264 { 265 platform_driver_unregister(&tps65090_regulator_driver); 266 } 267 module_exit(tps65090_regulator_exit); 268 269 MODULE_DESCRIPTION("tps65090 regulator driver"); 270 MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); 271 MODULE_LICENSE("GPL v2"); 272 MODULE_ALIAS("platform:tps65090-pmic"); 273