1452534e5SVenu Byravarasu /* 2452534e5SVenu Byravarasu * Regulator driver for tps65090 power management chip. 3452534e5SVenu Byravarasu * 4452534e5SVenu Byravarasu * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 5452534e5SVenu Byravarasu 6452534e5SVenu Byravarasu * This program is free software; you can redistribute it and/or modify it 7452534e5SVenu Byravarasu * under the terms and conditions of the GNU General Public License, 8452534e5SVenu Byravarasu * version 2, as published by the Free Software Foundation. 9452534e5SVenu Byravarasu 10452534e5SVenu Byravarasu * This program is distributed in the hope it will be useful, but WITHOUT 11452534e5SVenu Byravarasu * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12452534e5SVenu Byravarasu * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13452534e5SVenu Byravarasu * more details. 14452534e5SVenu Byravarasu 15452534e5SVenu Byravarasu * You should have received a copy of the GNU General Public License 16452534e5SVenu Byravarasu * along with this program. If not, see <http://www.gnu.org/licenses/> 17452534e5SVenu Byravarasu */ 18452534e5SVenu Byravarasu 19452534e5SVenu Byravarasu #include <linux/module.h> 20452534e5SVenu Byravarasu #include <linux/delay.h> 21452534e5SVenu Byravarasu #include <linux/init.h> 22452534e5SVenu Byravarasu #include <linux/slab.h> 23452534e5SVenu Byravarasu #include <linux/err.h> 24452534e5SVenu Byravarasu #include <linux/platform_device.h> 25452534e5SVenu Byravarasu #include <linux/regulator/driver.h> 26452534e5SVenu Byravarasu #include <linux/regulator/machine.h> 27452534e5SVenu Byravarasu #include <linux/mfd/tps65090.h> 28452534e5SVenu Byravarasu #include <linux/regulator/tps65090-regulator.h> 29452534e5SVenu Byravarasu 30452534e5SVenu Byravarasu struct tps65090_regulator { 31452534e5SVenu Byravarasu int id; 32452534e5SVenu Byravarasu /* used by regulator core */ 33452534e5SVenu Byravarasu struct regulator_desc desc; 34452534e5SVenu Byravarasu 35452534e5SVenu Byravarasu /* Device */ 36452534e5SVenu Byravarasu struct device *dev; 37452534e5SVenu Byravarasu }; 38452534e5SVenu Byravarasu 39452534e5SVenu Byravarasu static struct regulator_ops tps65090_ops = { 4006c4998bSAxel Lin .enable = regulator_enable_regmap, 4106c4998bSAxel Lin .disable = regulator_disable_regmap, 4206c4998bSAxel Lin .is_enabled = regulator_is_enabled_regmap, 43452534e5SVenu Byravarasu }; 44452534e5SVenu Byravarasu 454b3bd55fSAxel Lin #define tps65090_REG(_id) \ 46452534e5SVenu Byravarasu { \ 47452534e5SVenu Byravarasu .id = TPS65090_ID_##_id, \ 48452534e5SVenu Byravarasu .desc = { \ 49452534e5SVenu Byravarasu .name = tps65090_rails(_id), \ 50452534e5SVenu Byravarasu .id = TPS65090_ID_##_id, \ 514b3bd55fSAxel Lin .ops = &tps65090_ops, \ 52452534e5SVenu Byravarasu .type = REGULATOR_VOLTAGE, \ 53452534e5SVenu Byravarasu .owner = THIS_MODULE, \ 5406c4998bSAxel Lin .enable_reg = (TPS65090_ID_##_id) + 12, \ 5506c4998bSAxel Lin .enable_mask = BIT(0), \ 56452534e5SVenu Byravarasu }, \ 57452534e5SVenu Byravarasu } 58452534e5SVenu Byravarasu 59452534e5SVenu Byravarasu static struct tps65090_regulator TPS65090_regulator[] = { 604b3bd55fSAxel Lin tps65090_REG(DCDC1), 614b3bd55fSAxel Lin tps65090_REG(DCDC2), 624b3bd55fSAxel Lin tps65090_REG(DCDC3), 634b3bd55fSAxel Lin tps65090_REG(FET1), 644b3bd55fSAxel Lin tps65090_REG(FET2), 654b3bd55fSAxel Lin tps65090_REG(FET3), 664b3bd55fSAxel Lin tps65090_REG(FET4), 674b3bd55fSAxel Lin tps65090_REG(FET5), 684b3bd55fSAxel Lin tps65090_REG(FET6), 694b3bd55fSAxel Lin tps65090_REG(FET7), 70452534e5SVenu Byravarasu }; 71452534e5SVenu Byravarasu 72452534e5SVenu Byravarasu static inline struct tps65090_regulator *find_regulator_info(int id) 73452534e5SVenu Byravarasu { 74452534e5SVenu Byravarasu struct tps65090_regulator *ri; 75452534e5SVenu Byravarasu int i; 76452534e5SVenu Byravarasu 77452534e5SVenu Byravarasu for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) { 78452534e5SVenu Byravarasu ri = &TPS65090_regulator[i]; 79452534e5SVenu Byravarasu if (ri->desc.id == id) 80452534e5SVenu Byravarasu return ri; 81452534e5SVenu Byravarasu } 82452534e5SVenu Byravarasu return NULL; 83452534e5SVenu Byravarasu } 84452534e5SVenu Byravarasu 85452534e5SVenu Byravarasu static int __devinit tps65090_regulator_probe(struct platform_device *pdev) 86452534e5SVenu Byravarasu { 8706c4998bSAxel Lin struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); 88452534e5SVenu Byravarasu struct tps65090_regulator *ri = NULL; 89c172708dSMark Brown struct regulator_config config = { }; 90452534e5SVenu Byravarasu struct regulator_dev *rdev; 91452534e5SVenu Byravarasu struct tps65090_regulator_platform_data *tps_pdata; 92452534e5SVenu Byravarasu int id = pdev->id; 93452534e5SVenu Byravarasu 94452534e5SVenu Byravarasu dev_dbg(&pdev->dev, "Probing regulator %d\n", id); 95452534e5SVenu Byravarasu 96452534e5SVenu Byravarasu ri = find_regulator_info(id); 97452534e5SVenu Byravarasu if (ri == NULL) { 98452534e5SVenu Byravarasu dev_err(&pdev->dev, "invalid regulator ID specified\n"); 99452534e5SVenu Byravarasu return -EINVAL; 100452534e5SVenu Byravarasu } 101452534e5SVenu Byravarasu tps_pdata = pdev->dev.platform_data; 102452534e5SVenu Byravarasu ri->dev = &pdev->dev; 103452534e5SVenu Byravarasu 104c172708dSMark Brown config.dev = &pdev->dev; 105c172708dSMark Brown config.init_data = &tps_pdata->regulator; 106c172708dSMark Brown config.driver_data = ri; 10706c4998bSAxel Lin config.regmap = tps65090_mfd->rmap; 108c172708dSMark Brown 109c172708dSMark Brown rdev = regulator_register(&ri->desc, &config); 1100ca2d6e6SAxel Lin if (IS_ERR(rdev)) { 111452534e5SVenu Byravarasu dev_err(&pdev->dev, "failed to register regulator %s\n", 112452534e5SVenu Byravarasu ri->desc.name); 113452534e5SVenu Byravarasu return PTR_ERR(rdev); 114452534e5SVenu Byravarasu } 115452534e5SVenu Byravarasu 116452534e5SVenu Byravarasu platform_set_drvdata(pdev, rdev); 117452534e5SVenu Byravarasu return 0; 118452534e5SVenu Byravarasu } 119452534e5SVenu Byravarasu 120452534e5SVenu Byravarasu static int __devexit tps65090_regulator_remove(struct platform_device *pdev) 121452534e5SVenu Byravarasu { 122452534e5SVenu Byravarasu struct regulator_dev *rdev = platform_get_drvdata(pdev); 123452534e5SVenu Byravarasu 124452534e5SVenu Byravarasu regulator_unregister(rdev); 125452534e5SVenu Byravarasu return 0; 126452534e5SVenu Byravarasu } 127452534e5SVenu Byravarasu 128452534e5SVenu Byravarasu static struct platform_driver tps65090_regulator_driver = { 129452534e5SVenu Byravarasu .driver = { 130452534e5SVenu Byravarasu .name = "tps65090-regulator", 131452534e5SVenu Byravarasu .owner = THIS_MODULE, 132452534e5SVenu Byravarasu }, 133452534e5SVenu Byravarasu .probe = tps65090_regulator_probe, 134452534e5SVenu Byravarasu .remove = __devexit_p(tps65090_regulator_remove), 135452534e5SVenu Byravarasu }; 136452534e5SVenu Byravarasu 137452534e5SVenu Byravarasu static int __init tps65090_regulator_init(void) 138452534e5SVenu Byravarasu { 139452534e5SVenu Byravarasu return platform_driver_register(&tps65090_regulator_driver); 140452534e5SVenu Byravarasu } 141452534e5SVenu Byravarasu subsys_initcall(tps65090_regulator_init); 142452534e5SVenu Byravarasu 143452534e5SVenu Byravarasu static void __exit tps65090_regulator_exit(void) 144452534e5SVenu Byravarasu { 145452534e5SVenu Byravarasu platform_driver_unregister(&tps65090_regulator_driver); 146452534e5SVenu Byravarasu } 147452534e5SVenu Byravarasu module_exit(tps65090_regulator_exit); 148452534e5SVenu Byravarasu 149452534e5SVenu Byravarasu MODULE_DESCRIPTION("tps65090 regulator driver"); 150452534e5SVenu Byravarasu MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); 151452534e5SVenu Byravarasu MODULE_LICENSE("GPL v2"); 152