16ffc3270SLaxman Dewangan /* 26ffc3270SLaxman Dewangan * Regulator driver for RICOH RC5T583 power management chip. 36ffc3270SLaxman Dewangan * 46ffc3270SLaxman Dewangan * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. 56ffc3270SLaxman Dewangan * Author: Laxman dewangan <ldewangan@nvidia.com> 66ffc3270SLaxman Dewangan * 76ffc3270SLaxman Dewangan * based on code 86ffc3270SLaxman Dewangan * Copyright (C) 2011 RICOH COMPANY,LTD 96ffc3270SLaxman Dewangan * 106ffc3270SLaxman Dewangan * 116ffc3270SLaxman Dewangan * This program is free software; you can redistribute it and/or modify it 126ffc3270SLaxman Dewangan * under the terms and conditions of the GNU General Public License, 136ffc3270SLaxman Dewangan * version 2, as published by the Free Software Foundation. 146ffc3270SLaxman Dewangan * 156ffc3270SLaxman Dewangan * This program is distributed in the hope it will be useful, but WITHOUT 166ffc3270SLaxman Dewangan * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 176ffc3270SLaxman Dewangan * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 186ffc3270SLaxman Dewangan * more details. 196ffc3270SLaxman Dewangan * 206ffc3270SLaxman Dewangan * You should have received a copy of the GNU General Public License 216ffc3270SLaxman Dewangan * along with this program. If not, see <http://www.gnu.org/licenses/>. 226ffc3270SLaxman Dewangan * 236ffc3270SLaxman Dewangan */ 246ffc3270SLaxman Dewangan 256ffc3270SLaxman Dewangan #include <linux/module.h> 266ffc3270SLaxman Dewangan #include <linux/delay.h> 276ffc3270SLaxman Dewangan #include <linux/init.h> 286ffc3270SLaxman Dewangan #include <linux/slab.h> 296ffc3270SLaxman Dewangan #include <linux/err.h> 306ffc3270SLaxman Dewangan #include <linux/platform_device.h> 316ffc3270SLaxman Dewangan #include <linux/regulator/driver.h> 326ffc3270SLaxman Dewangan #include <linux/regulator/machine.h> 336ffc3270SLaxman Dewangan #include <linux/gpio.h> 346ffc3270SLaxman Dewangan #include <linux/mfd/rc5t583.h> 356ffc3270SLaxman Dewangan 366ffc3270SLaxman Dewangan struct rc5t583_regulator_info { 376ffc3270SLaxman Dewangan int deepsleep_id; 386ffc3270SLaxman Dewangan 396ffc3270SLaxman Dewangan /* Regulator register address.*/ 406ffc3270SLaxman Dewangan uint8_t reg_en_reg; 416ffc3270SLaxman Dewangan uint8_t en_bit; 426ffc3270SLaxman Dewangan uint8_t reg_disc_reg; 436ffc3270SLaxman Dewangan uint8_t disc_bit; 446ffc3270SLaxman Dewangan uint8_t vout_reg; 456ffc3270SLaxman Dewangan uint8_t vout_mask; 466ffc3270SLaxman Dewangan uint8_t deepsleep_reg; 476ffc3270SLaxman Dewangan 486ffc3270SLaxman Dewangan /* Chip constraints on regulator behavior */ 496ffc3270SLaxman Dewangan int min_uV; 506ffc3270SLaxman Dewangan int max_uV; 516ffc3270SLaxman Dewangan int step_uV; 526ffc3270SLaxman Dewangan 536ffc3270SLaxman Dewangan /* Regulator specific turn-on delay and voltage settling time*/ 546ffc3270SLaxman Dewangan int enable_uv_per_us; 556ffc3270SLaxman Dewangan int change_uv_per_us; 566ffc3270SLaxman Dewangan 576ffc3270SLaxman Dewangan /* Used by regulator core */ 586ffc3270SLaxman Dewangan struct regulator_desc desc; 596ffc3270SLaxman Dewangan }; 606ffc3270SLaxman Dewangan 616ffc3270SLaxman Dewangan struct rc5t583_regulator { 626ffc3270SLaxman Dewangan struct rc5t583_regulator_info *reg_info; 636ffc3270SLaxman Dewangan 646ffc3270SLaxman Dewangan /* Devices */ 656ffc3270SLaxman Dewangan struct device *dev; 666ffc3270SLaxman Dewangan struct rc5t583 *mfd; 676ffc3270SLaxman Dewangan struct regulator_dev *rdev; 686ffc3270SLaxman Dewangan }; 696ffc3270SLaxman Dewangan 706ffc3270SLaxman Dewangan static int rc5t583_reg_is_enabled(struct regulator_dev *rdev) 716ffc3270SLaxman Dewangan { 726ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 736ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri = reg->reg_info; 746ffc3270SLaxman Dewangan uint8_t control; 756ffc3270SLaxman Dewangan int ret; 766ffc3270SLaxman Dewangan 776ffc3270SLaxman Dewangan ret = rc5t583_read(reg->mfd->dev, ri->reg_en_reg, &control); 786ffc3270SLaxman Dewangan if (ret < 0) { 796ffc3270SLaxman Dewangan dev_err(&rdev->dev, 806ffc3270SLaxman Dewangan "Error in reading the control register 0x%02x\n", 816ffc3270SLaxman Dewangan ri->reg_en_reg); 826ffc3270SLaxman Dewangan return ret; 836ffc3270SLaxman Dewangan } 846ffc3270SLaxman Dewangan return !!(control & BIT(ri->en_bit)); 856ffc3270SLaxman Dewangan } 866ffc3270SLaxman Dewangan 876ffc3270SLaxman Dewangan static int rc5t583_reg_enable(struct regulator_dev *rdev) 886ffc3270SLaxman Dewangan { 896ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 906ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri = reg->reg_info; 916ffc3270SLaxman Dewangan int ret; 926ffc3270SLaxman Dewangan 936ffc3270SLaxman Dewangan ret = rc5t583_set_bits(reg->mfd->dev, ri->reg_en_reg, 946ffc3270SLaxman Dewangan (1 << ri->en_bit)); 956ffc3270SLaxman Dewangan if (ret < 0) { 966ffc3270SLaxman Dewangan dev_err(&rdev->dev, 976ffc3270SLaxman Dewangan "Error in setting bit of STATE register 0x%02x\n", 986ffc3270SLaxman Dewangan ri->reg_en_reg); 996ffc3270SLaxman Dewangan return ret; 1006ffc3270SLaxman Dewangan } 1016ffc3270SLaxman Dewangan return ret; 1026ffc3270SLaxman Dewangan } 1036ffc3270SLaxman Dewangan 1046ffc3270SLaxman Dewangan static int rc5t583_reg_disable(struct regulator_dev *rdev) 1056ffc3270SLaxman Dewangan { 1066ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 1076ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri = reg->reg_info; 1086ffc3270SLaxman Dewangan int ret; 1096ffc3270SLaxman Dewangan 1106ffc3270SLaxman Dewangan ret = rc5t583_clear_bits(reg->mfd->dev, ri->reg_en_reg, 1116ffc3270SLaxman Dewangan (1 << ri->en_bit)); 1126ffc3270SLaxman Dewangan if (ret < 0) 1136ffc3270SLaxman Dewangan dev_err(&rdev->dev, 1146ffc3270SLaxman Dewangan "Error in clearing bit of STATE register 0x%02x\n", 1156ffc3270SLaxman Dewangan ri->reg_en_reg); 1166ffc3270SLaxman Dewangan 1176ffc3270SLaxman Dewangan return ret; 1186ffc3270SLaxman Dewangan } 1196ffc3270SLaxman Dewangan 1206ffc3270SLaxman Dewangan static int rc5t583_list_voltage(struct regulator_dev *rdev, unsigned selector) 1216ffc3270SLaxman Dewangan { 1226ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 1236ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri = reg->reg_info; 1246ffc3270SLaxman Dewangan return ri->min_uV + (ri->step_uV * selector); 1256ffc3270SLaxman Dewangan } 1266ffc3270SLaxman Dewangan 1276ffc3270SLaxman Dewangan static int rc5t583_set_voltage_sel(struct regulator_dev *rdev, 1286ffc3270SLaxman Dewangan unsigned int selector) 1296ffc3270SLaxman Dewangan { 1306ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 1316ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri = reg->reg_info; 1326ffc3270SLaxman Dewangan int ret; 133e3a7384cSAxel Lin if (selector >= rdev->desc->n_voltages) { 1346ffc3270SLaxman Dewangan dev_err(&rdev->dev, "Invalid selector 0x%02x\n", selector); 1356ffc3270SLaxman Dewangan return -EINVAL; 1366ffc3270SLaxman Dewangan } 1376ffc3270SLaxman Dewangan 1386ffc3270SLaxman Dewangan ret = rc5t583_update(reg->mfd->dev, ri->vout_reg, 1396ffc3270SLaxman Dewangan selector, ri->vout_mask); 1406ffc3270SLaxman Dewangan if (ret < 0) 1416ffc3270SLaxman Dewangan dev_err(&rdev->dev, 1426ffc3270SLaxman Dewangan "Error in update voltage register 0x%02x\n", ri->vout_reg); 1436ffc3270SLaxman Dewangan return ret; 1446ffc3270SLaxman Dewangan } 1456ffc3270SLaxman Dewangan 1466ffc3270SLaxman Dewangan static int rc5t583_get_voltage_sel(struct regulator_dev *rdev) 1476ffc3270SLaxman Dewangan { 1486ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 1496ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri = reg->reg_info; 1506ffc3270SLaxman Dewangan uint8_t vsel; 1516ffc3270SLaxman Dewangan int ret; 1526ffc3270SLaxman Dewangan ret = rc5t583_read(reg->mfd->dev, ri->vout_reg, &vsel); 1536ffc3270SLaxman Dewangan if (ret < 0) { 1546ffc3270SLaxman Dewangan dev_err(&rdev->dev, 1556ffc3270SLaxman Dewangan "Error in reading voltage register 0x%02x\n", ri->vout_reg); 1566ffc3270SLaxman Dewangan return ret; 1576ffc3270SLaxman Dewangan } 1586ffc3270SLaxman Dewangan return vsel & ri->vout_mask; 1596ffc3270SLaxman Dewangan } 1606ffc3270SLaxman Dewangan 1616ffc3270SLaxman Dewangan static int rc5t583_regulator_enable_time(struct regulator_dev *rdev) 1626ffc3270SLaxman Dewangan { 1636ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 1646ffc3270SLaxman Dewangan int vsel = rc5t583_get_voltage_sel(rdev); 1656ffc3270SLaxman Dewangan int curr_uV = rc5t583_list_voltage(rdev, vsel); 1666ffc3270SLaxman Dewangan return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us); 1676ffc3270SLaxman Dewangan } 1686ffc3270SLaxman Dewangan 1696ffc3270SLaxman Dewangan static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev, 1706ffc3270SLaxman Dewangan unsigned int old_selector, unsigned int new_selector) 1716ffc3270SLaxman Dewangan { 1726ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); 1736ffc3270SLaxman Dewangan int old_uV, new_uV; 1746ffc3270SLaxman Dewangan old_uV = rc5t583_list_voltage(rdev, old_selector); 1756ffc3270SLaxman Dewangan 1766ffc3270SLaxman Dewangan if (old_uV < 0) 1776ffc3270SLaxman Dewangan return old_uV; 1786ffc3270SLaxman Dewangan 1796ffc3270SLaxman Dewangan new_uV = rc5t583_list_voltage(rdev, new_selector); 1806ffc3270SLaxman Dewangan if (new_uV < 0) 1816ffc3270SLaxman Dewangan return new_uV; 1826ffc3270SLaxman Dewangan 1836ffc3270SLaxman Dewangan return DIV_ROUND_UP(abs(old_uV - new_uV), 1846ffc3270SLaxman Dewangan reg->reg_info->change_uv_per_us); 1856ffc3270SLaxman Dewangan } 1866ffc3270SLaxman Dewangan 1876ffc3270SLaxman Dewangan 1886ffc3270SLaxman Dewangan static struct regulator_ops rc5t583_ops = { 1896ffc3270SLaxman Dewangan .is_enabled = rc5t583_reg_is_enabled, 1906ffc3270SLaxman Dewangan .enable = rc5t583_reg_enable, 1916ffc3270SLaxman Dewangan .disable = rc5t583_reg_disable, 1926ffc3270SLaxman Dewangan .enable_time = rc5t583_regulator_enable_time, 1936ffc3270SLaxman Dewangan .get_voltage_sel = rc5t583_get_voltage_sel, 1946ffc3270SLaxman Dewangan .set_voltage_sel = rc5t583_set_voltage_sel, 1956ffc3270SLaxman Dewangan .list_voltage = rc5t583_list_voltage, 1966ffc3270SLaxman Dewangan .set_voltage_time_sel = rc5t583_set_voltage_time_sel, 1976ffc3270SLaxman Dewangan }; 1986ffc3270SLaxman Dewangan 19995e301baSAxel Lin #define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \ 20095e301baSAxel Lin _vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \ 2016ffc3270SLaxman Dewangan { \ 2026ffc3270SLaxman Dewangan .reg_en_reg = RC5T583_REG_##_en_reg, \ 2036ffc3270SLaxman Dewangan .en_bit = _en_bit, \ 2046ffc3270SLaxman Dewangan .reg_disc_reg = RC5T583_REG_##_disc_reg, \ 2056ffc3270SLaxman Dewangan .disc_bit = _disc_bit, \ 20695e301baSAxel Lin .vout_reg = RC5T583_REG_##_id##DAC, \ 2076ffc3270SLaxman Dewangan .vout_mask = _vout_mask, \ 20895e301baSAxel Lin .deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \ 2096ffc3270SLaxman Dewangan .min_uV = _min_mv * 1000, \ 2106ffc3270SLaxman Dewangan .max_uV = _max_mv * 1000, \ 2116ffc3270SLaxman Dewangan .step_uV = _step_uV, \ 2126ffc3270SLaxman Dewangan .enable_uv_per_us = _enable_mv * 1000, \ 2136ffc3270SLaxman Dewangan .change_uv_per_us = 40 * 1000, \ 2146ffc3270SLaxman Dewangan .deepsleep_id = RC5T583_DS_##_id, \ 2156ffc3270SLaxman Dewangan .desc = { \ 2166ffc3270SLaxman Dewangan .name = "rc5t583-regulator-"#_id, \ 2176ffc3270SLaxman Dewangan .id = RC5T583_REGULATOR_##_id, \ 218e3a7384cSAxel Lin .n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \ 2196ffc3270SLaxman Dewangan .ops = &rc5t583_ops, \ 2206ffc3270SLaxman Dewangan .type = REGULATOR_VOLTAGE, \ 2216ffc3270SLaxman Dewangan .owner = THIS_MODULE, \ 2226ffc3270SLaxman Dewangan }, \ 2236ffc3270SLaxman Dewangan } 2246ffc3270SLaxman Dewangan 2256ffc3270SLaxman Dewangan static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = { 22695e301baSAxel Lin RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4), 22795e301baSAxel Lin RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14), 22895e301baSAxel Lin RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14), 22995e301baSAxel Lin RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14), 23095e301baSAxel Lin RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160), 23195e301baSAxel Lin RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160), 23295e301baSAxel Lin RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160), 23395e301baSAxel Lin RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160), 23495e301baSAxel Lin RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133), 23595e301baSAxel Lin RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267), 23695e301baSAxel Lin RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133), 23795e301baSAxel Lin RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233), 23895e301baSAxel Lin RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233), 23995e301baSAxel Lin RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133), 2406ffc3270SLaxman Dewangan }; 2416ffc3270SLaxman Dewangan 2426ffc3270SLaxman Dewangan static int __devinit rc5t583_regulator_probe(struct platform_device *pdev) 2436ffc3270SLaxman Dewangan { 2446ffc3270SLaxman Dewangan struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); 2456ffc3270SLaxman Dewangan struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); 2466ffc3270SLaxman Dewangan struct regulator_init_data *reg_data; 2476ffc3270SLaxman Dewangan struct rc5t583_regulator *reg = NULL; 2486ffc3270SLaxman Dewangan struct rc5t583_regulator *regs; 2496ffc3270SLaxman Dewangan struct regulator_dev *rdev; 2506ffc3270SLaxman Dewangan struct rc5t583_regulator_info *ri; 2516ffc3270SLaxman Dewangan int ret; 2526ffc3270SLaxman Dewangan int id; 2536ffc3270SLaxman Dewangan 2546ffc3270SLaxman Dewangan if (!pdata) { 2556ffc3270SLaxman Dewangan dev_err(&pdev->dev, "No platform data, exiting...\n"); 2566ffc3270SLaxman Dewangan return -ENODEV; 2576ffc3270SLaxman Dewangan } 2586ffc3270SLaxman Dewangan 2596ffc3270SLaxman Dewangan regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * 2606ffc3270SLaxman Dewangan sizeof(struct rc5t583_regulator), GFP_KERNEL); 2616ffc3270SLaxman Dewangan if (!regs) { 2626ffc3270SLaxman Dewangan dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); 2636ffc3270SLaxman Dewangan return -ENOMEM; 2646ffc3270SLaxman Dewangan } 2656ffc3270SLaxman Dewangan 2666ffc3270SLaxman Dewangan 2676ffc3270SLaxman Dewangan for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { 2686ffc3270SLaxman Dewangan reg_data = pdata->reg_init_data[id]; 2696ffc3270SLaxman Dewangan 2706ffc3270SLaxman Dewangan /* No need to register if there is no regulator data */ 2716ffc3270SLaxman Dewangan if (!reg_data) 2726ffc3270SLaxman Dewangan continue; 2736ffc3270SLaxman Dewangan 2746ffc3270SLaxman Dewangan reg = ®s[id]; 2756ffc3270SLaxman Dewangan ri = &rc5t583_reg_info[id]; 2766ffc3270SLaxman Dewangan reg->reg_info = ri; 2776ffc3270SLaxman Dewangan reg->mfd = rc5t583; 2786ffc3270SLaxman Dewangan reg->dev = &pdev->dev; 2796ffc3270SLaxman Dewangan 2806ffc3270SLaxman Dewangan if (ri->deepsleep_id == RC5T583_DS_NONE) 2816ffc3270SLaxman Dewangan goto skip_ext_pwr_config; 2826ffc3270SLaxman Dewangan 2836ffc3270SLaxman Dewangan ret = rc5t583_ext_power_req_config(rc5t583->dev, 2846ffc3270SLaxman Dewangan ri->deepsleep_id, 2856ffc3270SLaxman Dewangan pdata->regulator_ext_pwr_control[id], 2866ffc3270SLaxman Dewangan pdata->regulator_deepsleep_slot[id]); 2876ffc3270SLaxman Dewangan /* 2886ffc3270SLaxman Dewangan * Configuring external control is not a major issue, 2896ffc3270SLaxman Dewangan * just give warning. 2906ffc3270SLaxman Dewangan */ 2916ffc3270SLaxman Dewangan if (ret < 0) 2926ffc3270SLaxman Dewangan dev_warn(&pdev->dev, 2936ffc3270SLaxman Dewangan "Failed to configure ext control %d\n", id); 2946ffc3270SLaxman Dewangan 2956ffc3270SLaxman Dewangan skip_ext_pwr_config: 2966ffc3270SLaxman Dewangan rdev = regulator_register(&ri->desc, &pdev->dev, 2976ffc3270SLaxman Dewangan reg_data, reg, NULL); 298a69df8a1SAxel Lin if (IS_ERR(rdev)) { 2996ffc3270SLaxman Dewangan dev_err(&pdev->dev, "Failed to register regulator %s\n", 3006ffc3270SLaxman Dewangan ri->desc.name); 3016ffc3270SLaxman Dewangan ret = PTR_ERR(rdev); 3026ffc3270SLaxman Dewangan goto clean_exit; 3036ffc3270SLaxman Dewangan } 3046ffc3270SLaxman Dewangan reg->rdev = rdev; 3056ffc3270SLaxman Dewangan } 3066ffc3270SLaxman Dewangan platform_set_drvdata(pdev, regs); 3076ffc3270SLaxman Dewangan return 0; 3086ffc3270SLaxman Dewangan 3096ffc3270SLaxman Dewangan clean_exit: 310a69df8a1SAxel Lin while (--id >= 0) 3116ffc3270SLaxman Dewangan regulator_unregister(regs[id].rdev); 3126ffc3270SLaxman Dewangan 3136ffc3270SLaxman Dewangan return ret; 3146ffc3270SLaxman Dewangan } 3156ffc3270SLaxman Dewangan 3166ffc3270SLaxman Dewangan static int __devexit rc5t583_regulator_remove(struct platform_device *pdev) 3176ffc3270SLaxman Dewangan { 3186ffc3270SLaxman Dewangan struct rc5t583_regulator *regs = platform_get_drvdata(pdev); 3196ffc3270SLaxman Dewangan int id; 3206ffc3270SLaxman Dewangan 3216ffc3270SLaxman Dewangan for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) 3226ffc3270SLaxman Dewangan regulator_unregister(regs[id].rdev); 3236ffc3270SLaxman Dewangan return 0; 3246ffc3270SLaxman Dewangan } 3256ffc3270SLaxman Dewangan 3266ffc3270SLaxman Dewangan static struct platform_driver rc5t583_regulator_driver = { 3276ffc3270SLaxman Dewangan .driver = { 3286ffc3270SLaxman Dewangan .name = "rc5t583-regulator", 3296ffc3270SLaxman Dewangan .owner = THIS_MODULE, 3306ffc3270SLaxman Dewangan }, 3316ffc3270SLaxman Dewangan .probe = rc5t583_regulator_probe, 3326ffc3270SLaxman Dewangan .remove = __devexit_p(rc5t583_regulator_remove), 3336ffc3270SLaxman Dewangan }; 3346ffc3270SLaxman Dewangan 3356ffc3270SLaxman Dewangan static int __init rc5t583_regulator_init(void) 3366ffc3270SLaxman Dewangan { 3376ffc3270SLaxman Dewangan return platform_driver_register(&rc5t583_regulator_driver); 3386ffc3270SLaxman Dewangan } 3396ffc3270SLaxman Dewangan subsys_initcall(rc5t583_regulator_init); 3406ffc3270SLaxman Dewangan 3416ffc3270SLaxman Dewangan static void __exit rc5t583_regulator_exit(void) 3426ffc3270SLaxman Dewangan { 3436ffc3270SLaxman Dewangan platform_driver_unregister(&rc5t583_regulator_driver); 3446ffc3270SLaxman Dewangan } 3456ffc3270SLaxman Dewangan module_exit(rc5t583_regulator_exit); 3466ffc3270SLaxman Dewangan 3476ffc3270SLaxman Dewangan MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 3486ffc3270SLaxman Dewangan MODULE_DESCRIPTION("RC5T583 regulator driver"); 3496ffc3270SLaxman Dewangan MODULE_ALIAS("platform:rc5t583-regulator"); 3506ffc3270SLaxman Dewangan MODULE_LICENSE("GPL V2"); 351