13fa5b8e0SAnuj Aggarwal /* 23fa5b8e0SAnuj Aggarwal * tps6507x-regulator.c 33fa5b8e0SAnuj Aggarwal * 43fa5b8e0SAnuj Aggarwal * Regulator driver for TPS65073 PMIC 53fa5b8e0SAnuj Aggarwal * 63fa5b8e0SAnuj Aggarwal * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/ 73fa5b8e0SAnuj Aggarwal * 83fa5b8e0SAnuj Aggarwal * This program is free software; you can redistribute it and/or 93fa5b8e0SAnuj Aggarwal * modify it under the terms of the GNU General Public License as 103fa5b8e0SAnuj Aggarwal * published by the Free Software Foundation version 2. 113fa5b8e0SAnuj Aggarwal * 123fa5b8e0SAnuj Aggarwal * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, 133fa5b8e0SAnuj Aggarwal * whether express or implied; without even the implied warranty of 143fa5b8e0SAnuj Aggarwal * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 153fa5b8e0SAnuj Aggarwal * General Public License for more details. 163fa5b8e0SAnuj Aggarwal */ 173fa5b8e0SAnuj Aggarwal 183fa5b8e0SAnuj Aggarwal #include <linux/kernel.h> 193fa5b8e0SAnuj Aggarwal #include <linux/module.h> 203fa5b8e0SAnuj Aggarwal #include <linux/init.h> 213fa5b8e0SAnuj Aggarwal #include <linux/err.h> 223fa5b8e0SAnuj Aggarwal #include <linux/platform_device.h> 233fa5b8e0SAnuj Aggarwal #include <linux/regulator/driver.h> 243fa5b8e0SAnuj Aggarwal #include <linux/regulator/machine.h> 253fa5b8e0SAnuj Aggarwal #include <linux/delay.h> 265a0e3ad6STejun Heo #include <linux/slab.h> 27d183fcc9STodd Fischer #include <linux/mfd/tps6507x.h> 283fa5b8e0SAnuj Aggarwal 293fa5b8e0SAnuj Aggarwal /* DCDC's */ 303fa5b8e0SAnuj Aggarwal #define TPS6507X_DCDC_1 0 313fa5b8e0SAnuj Aggarwal #define TPS6507X_DCDC_2 1 323fa5b8e0SAnuj Aggarwal #define TPS6507X_DCDC_3 2 333fa5b8e0SAnuj Aggarwal /* LDOs */ 343fa5b8e0SAnuj Aggarwal #define TPS6507X_LDO_1 3 353fa5b8e0SAnuj Aggarwal #define TPS6507X_LDO_2 4 363fa5b8e0SAnuj Aggarwal 373fa5b8e0SAnuj Aggarwal #define TPS6507X_MAX_REG_ID TPS6507X_LDO_2 383fa5b8e0SAnuj Aggarwal 393fa5b8e0SAnuj Aggarwal /* Number of step-down converters available */ 403fa5b8e0SAnuj Aggarwal #define TPS6507X_NUM_DCDC 3 413fa5b8e0SAnuj Aggarwal /* Number of LDO voltage regulators available */ 423fa5b8e0SAnuj Aggarwal #define TPS6507X_NUM_LDO 2 433fa5b8e0SAnuj Aggarwal /* Number of total regulators available */ 443fa5b8e0SAnuj Aggarwal #define TPS6507X_NUM_REGULATOR (TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO) 453fa5b8e0SAnuj Aggarwal 463fa5b8e0SAnuj Aggarwal /* Supported voltage values for regulators (in milliVolts) */ 473fa5b8e0SAnuj Aggarwal static const u16 VDCDCx_VSEL_table[] = { 483fa5b8e0SAnuj Aggarwal 725, 750, 775, 800, 493fa5b8e0SAnuj Aggarwal 825, 850, 875, 900, 503fa5b8e0SAnuj Aggarwal 925, 950, 975, 1000, 513fa5b8e0SAnuj Aggarwal 1025, 1050, 1075, 1100, 523fa5b8e0SAnuj Aggarwal 1125, 1150, 1175, 1200, 533fa5b8e0SAnuj Aggarwal 1225, 1250, 1275, 1300, 543fa5b8e0SAnuj Aggarwal 1325, 1350, 1375, 1400, 553fa5b8e0SAnuj Aggarwal 1425, 1450, 1475, 1500, 563fa5b8e0SAnuj Aggarwal 1550, 1600, 1650, 1700, 573fa5b8e0SAnuj Aggarwal 1750, 1800, 1850, 1900, 583fa5b8e0SAnuj Aggarwal 1950, 2000, 2050, 2100, 593fa5b8e0SAnuj Aggarwal 2150, 2200, 2250, 2300, 603fa5b8e0SAnuj Aggarwal 2350, 2400, 2450, 2500, 613fa5b8e0SAnuj Aggarwal 2550, 2600, 2650, 2700, 623fa5b8e0SAnuj Aggarwal 2750, 2800, 2850, 2900, 633fa5b8e0SAnuj Aggarwal 3000, 3100, 3200, 3300, 643fa5b8e0SAnuj Aggarwal }; 653fa5b8e0SAnuj Aggarwal 663fa5b8e0SAnuj Aggarwal static const u16 LDO1_VSEL_table[] = { 673fa5b8e0SAnuj Aggarwal 1000, 1100, 1200, 1250, 683fa5b8e0SAnuj Aggarwal 1300, 1350, 1400, 1500, 693fa5b8e0SAnuj Aggarwal 1600, 1800, 2500, 2750, 703fa5b8e0SAnuj Aggarwal 2800, 3000, 3100, 3300, 713fa5b8e0SAnuj Aggarwal }; 723fa5b8e0SAnuj Aggarwal 733fa5b8e0SAnuj Aggarwal static const u16 LDO2_VSEL_table[] = { 743fa5b8e0SAnuj Aggarwal 725, 750, 775, 800, 753fa5b8e0SAnuj Aggarwal 825, 850, 875, 900, 763fa5b8e0SAnuj Aggarwal 925, 950, 975, 1000, 773fa5b8e0SAnuj Aggarwal 1025, 1050, 1075, 1100, 783fa5b8e0SAnuj Aggarwal 1125, 1150, 1175, 1200, 793fa5b8e0SAnuj Aggarwal 1225, 1250, 1275, 1300, 803fa5b8e0SAnuj Aggarwal 1325, 1350, 1375, 1400, 813fa5b8e0SAnuj Aggarwal 1425, 1450, 1475, 1500, 823fa5b8e0SAnuj Aggarwal 1550, 1600, 1650, 1700, 833fa5b8e0SAnuj Aggarwal 1750, 1800, 1850, 1900, 843fa5b8e0SAnuj Aggarwal 1950, 2000, 2050, 2100, 853fa5b8e0SAnuj Aggarwal 2150, 2200, 2250, 2300, 863fa5b8e0SAnuj Aggarwal 2350, 2400, 2450, 2500, 873fa5b8e0SAnuj Aggarwal 2550, 2600, 2650, 2700, 883fa5b8e0SAnuj Aggarwal 2750, 2800, 2850, 2900, 893fa5b8e0SAnuj Aggarwal 3000, 3100, 3200, 3300, 903fa5b8e0SAnuj Aggarwal }; 913fa5b8e0SAnuj Aggarwal 923fa5b8e0SAnuj Aggarwal static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDCx_VSEL_table), 933fa5b8e0SAnuj Aggarwal ARRAY_SIZE(VDCDCx_VSEL_table), 943fa5b8e0SAnuj Aggarwal ARRAY_SIZE(VDCDCx_VSEL_table), 953fa5b8e0SAnuj Aggarwal ARRAY_SIZE(LDO1_VSEL_table), 963fa5b8e0SAnuj Aggarwal ARRAY_SIZE(LDO2_VSEL_table)}; 973fa5b8e0SAnuj Aggarwal 983fa5b8e0SAnuj Aggarwal struct tps_info { 993fa5b8e0SAnuj Aggarwal const char *name; 1003fa5b8e0SAnuj Aggarwal unsigned min_uV; 1013fa5b8e0SAnuj Aggarwal unsigned max_uV; 1023fa5b8e0SAnuj Aggarwal u8 table_len; 1033fa5b8e0SAnuj Aggarwal const u16 *table; 1043fa5b8e0SAnuj Aggarwal }; 1053fa5b8e0SAnuj Aggarwal 106*31dd6a26STodd Fischer static const struct tps_info tps6507x_pmic_regs[] = { 107*31dd6a26STodd Fischer { 108*31dd6a26STodd Fischer .name = "VDCDC1", 109*31dd6a26STodd Fischer .min_uV = 725000, 110*31dd6a26STodd Fischer .max_uV = 3300000, 111*31dd6a26STodd Fischer .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), 112*31dd6a26STodd Fischer .table = VDCDCx_VSEL_table, 113*31dd6a26STodd Fischer }, 114*31dd6a26STodd Fischer { 115*31dd6a26STodd Fischer .name = "VDCDC2", 116*31dd6a26STodd Fischer .min_uV = 725000, 117*31dd6a26STodd Fischer .max_uV = 3300000, 118*31dd6a26STodd Fischer .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), 119*31dd6a26STodd Fischer .table = VDCDCx_VSEL_table, 120*31dd6a26STodd Fischer }, 121*31dd6a26STodd Fischer { 122*31dd6a26STodd Fischer .name = "VDCDC3", 123*31dd6a26STodd Fischer .min_uV = 725000, 124*31dd6a26STodd Fischer .max_uV = 3300000, 125*31dd6a26STodd Fischer .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), 126*31dd6a26STodd Fischer .table = VDCDCx_VSEL_table, 127*31dd6a26STodd Fischer }, 128*31dd6a26STodd Fischer { 129*31dd6a26STodd Fischer .name = "LDO1", 130*31dd6a26STodd Fischer .min_uV = 1000000, 131*31dd6a26STodd Fischer .max_uV = 3300000, 132*31dd6a26STodd Fischer .table_len = ARRAY_SIZE(LDO1_VSEL_table), 133*31dd6a26STodd Fischer .table = LDO1_VSEL_table, 134*31dd6a26STodd Fischer }, 135*31dd6a26STodd Fischer { 136*31dd6a26STodd Fischer .name = "LDO2", 137*31dd6a26STodd Fischer .min_uV = 725000, 138*31dd6a26STodd Fischer .max_uV = 3300000, 139*31dd6a26STodd Fischer .table_len = ARRAY_SIZE(LDO2_VSEL_table), 140*31dd6a26STodd Fischer .table = LDO2_VSEL_table, 141*31dd6a26STodd Fischer }, 142*31dd6a26STodd Fischer }; 143*31dd6a26STodd Fischer 1444ce5ba5bSTodd Fischer struct tps6507x_pmic { 1453fa5b8e0SAnuj Aggarwal struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; 146*31dd6a26STodd Fischer struct tps6507x_dev *mfd; 1473fa5b8e0SAnuj Aggarwal struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; 1483fa5b8e0SAnuj Aggarwal const struct tps_info *info[TPS6507X_NUM_REGULATOR]; 1493fa5b8e0SAnuj Aggarwal struct mutex io_lock; 1503fa5b8e0SAnuj Aggarwal }; 1514ce5ba5bSTodd Fischer static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg) 1523fa5b8e0SAnuj Aggarwal { 153*31dd6a26STodd Fischer u8 val; 154*31dd6a26STodd Fischer int err; 155*31dd6a26STodd Fischer 156*31dd6a26STodd Fischer err = tps->mfd->read_dev(tps->mfd, reg, 1, &val); 157*31dd6a26STodd Fischer 158*31dd6a26STodd Fischer if (err) 159*31dd6a26STodd Fischer return err; 160*31dd6a26STodd Fischer 161*31dd6a26STodd Fischer return val; 1623fa5b8e0SAnuj Aggarwal } 1633fa5b8e0SAnuj Aggarwal 1644ce5ba5bSTodd Fischer static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val) 1653fa5b8e0SAnuj Aggarwal { 166*31dd6a26STodd Fischer return tps->mfd->write_dev(tps->mfd, reg, 1, &val); 1673fa5b8e0SAnuj Aggarwal } 1683fa5b8e0SAnuj Aggarwal 1694ce5ba5bSTodd Fischer static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) 1703fa5b8e0SAnuj Aggarwal { 1713fa5b8e0SAnuj Aggarwal int err, data; 1723fa5b8e0SAnuj Aggarwal 1733fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 1743fa5b8e0SAnuj Aggarwal 1754ce5ba5bSTodd Fischer data = tps6507x_pmic_read(tps, reg); 1763fa5b8e0SAnuj Aggarwal if (data < 0) { 177*31dd6a26STodd Fischer dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); 1783fa5b8e0SAnuj Aggarwal err = data; 1793fa5b8e0SAnuj Aggarwal goto out; 1803fa5b8e0SAnuj Aggarwal } 1813fa5b8e0SAnuj Aggarwal 1823fa5b8e0SAnuj Aggarwal data |= mask; 1834ce5ba5bSTodd Fischer err = tps6507x_pmic_write(tps, reg, data); 1843fa5b8e0SAnuj Aggarwal if (err) 185*31dd6a26STodd Fischer dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); 1863fa5b8e0SAnuj Aggarwal 1873fa5b8e0SAnuj Aggarwal out: 1883fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 1893fa5b8e0SAnuj Aggarwal return err; 1903fa5b8e0SAnuj Aggarwal } 1913fa5b8e0SAnuj Aggarwal 1924ce5ba5bSTodd Fischer static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) 1933fa5b8e0SAnuj Aggarwal { 1943fa5b8e0SAnuj Aggarwal int err, data; 1953fa5b8e0SAnuj Aggarwal 1963fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 1973fa5b8e0SAnuj Aggarwal 1984ce5ba5bSTodd Fischer data = tps6507x_pmic_read(tps, reg); 1993fa5b8e0SAnuj Aggarwal if (data < 0) { 200*31dd6a26STodd Fischer dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); 2013fa5b8e0SAnuj Aggarwal err = data; 2023fa5b8e0SAnuj Aggarwal goto out; 2033fa5b8e0SAnuj Aggarwal } 2043fa5b8e0SAnuj Aggarwal 2053fa5b8e0SAnuj Aggarwal data &= ~mask; 2064ce5ba5bSTodd Fischer err = tps6507x_pmic_write(tps, reg, data); 2073fa5b8e0SAnuj Aggarwal if (err) 208*31dd6a26STodd Fischer dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); 2093fa5b8e0SAnuj Aggarwal 2103fa5b8e0SAnuj Aggarwal out: 2113fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 2123fa5b8e0SAnuj Aggarwal return err; 2133fa5b8e0SAnuj Aggarwal } 2143fa5b8e0SAnuj Aggarwal 2154ce5ba5bSTodd Fischer static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg) 2163fa5b8e0SAnuj Aggarwal { 2173fa5b8e0SAnuj Aggarwal int data; 2183fa5b8e0SAnuj Aggarwal 2193fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 2203fa5b8e0SAnuj Aggarwal 2214ce5ba5bSTodd Fischer data = tps6507x_pmic_read(tps, reg); 2223fa5b8e0SAnuj Aggarwal if (data < 0) 223*31dd6a26STodd Fischer dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); 2243fa5b8e0SAnuj Aggarwal 2253fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 2263fa5b8e0SAnuj Aggarwal return data; 2273fa5b8e0SAnuj Aggarwal } 2283fa5b8e0SAnuj Aggarwal 2294ce5ba5bSTodd Fischer static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val) 2303fa5b8e0SAnuj Aggarwal { 2313fa5b8e0SAnuj Aggarwal int err; 2323fa5b8e0SAnuj Aggarwal 2333fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 2343fa5b8e0SAnuj Aggarwal 2354ce5ba5bSTodd Fischer err = tps6507x_pmic_write(tps, reg, val); 2363fa5b8e0SAnuj Aggarwal if (err < 0) 237*31dd6a26STodd Fischer dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); 2383fa5b8e0SAnuj Aggarwal 2393fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 2403fa5b8e0SAnuj Aggarwal return err; 2413fa5b8e0SAnuj Aggarwal } 2423fa5b8e0SAnuj Aggarwal 2434ce5ba5bSTodd Fischer static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev) 2443fa5b8e0SAnuj Aggarwal { 2454ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 2463fa5b8e0SAnuj Aggarwal int data, dcdc = rdev_get_id(dev); 2473fa5b8e0SAnuj Aggarwal u8 shift; 2483fa5b8e0SAnuj Aggarwal 2493fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 2503fa5b8e0SAnuj Aggarwal return -EINVAL; 2513fa5b8e0SAnuj Aggarwal 2523fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - dcdc; 2534ce5ba5bSTodd Fischer data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); 2543fa5b8e0SAnuj Aggarwal 2553fa5b8e0SAnuj Aggarwal if (data < 0) 2563fa5b8e0SAnuj Aggarwal return data; 2573fa5b8e0SAnuj Aggarwal else 2583fa5b8e0SAnuj Aggarwal return (data & 1<<shift) ? 1 : 0; 2593fa5b8e0SAnuj Aggarwal } 2603fa5b8e0SAnuj Aggarwal 2614ce5ba5bSTodd Fischer static int tps6507x_pmic_ldo_is_enabled(struct regulator_dev *dev) 2623fa5b8e0SAnuj Aggarwal { 2634ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 2643fa5b8e0SAnuj Aggarwal int data, ldo = rdev_get_id(dev); 2653fa5b8e0SAnuj Aggarwal u8 shift; 2663fa5b8e0SAnuj Aggarwal 2673fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 2683fa5b8e0SAnuj Aggarwal return -EINVAL; 2693fa5b8e0SAnuj Aggarwal 2703fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - ldo; 2714ce5ba5bSTodd Fischer data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); 2723fa5b8e0SAnuj Aggarwal 2733fa5b8e0SAnuj Aggarwal if (data < 0) 2743fa5b8e0SAnuj Aggarwal return data; 2753fa5b8e0SAnuj Aggarwal else 2763fa5b8e0SAnuj Aggarwal return (data & 1<<shift) ? 1 : 0; 2773fa5b8e0SAnuj Aggarwal } 2783fa5b8e0SAnuj Aggarwal 2794ce5ba5bSTodd Fischer static int tps6507x_pmic_dcdc_enable(struct regulator_dev *dev) 2803fa5b8e0SAnuj Aggarwal { 2814ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 2823fa5b8e0SAnuj Aggarwal int dcdc = rdev_get_id(dev); 2833fa5b8e0SAnuj Aggarwal u8 shift; 2843fa5b8e0SAnuj Aggarwal 2853fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 2863fa5b8e0SAnuj Aggarwal return -EINVAL; 2873fa5b8e0SAnuj Aggarwal 2883fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - dcdc; 2894ce5ba5bSTodd Fischer return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 2903fa5b8e0SAnuj Aggarwal } 2913fa5b8e0SAnuj Aggarwal 2924ce5ba5bSTodd Fischer static int tps6507x_pmic_dcdc_disable(struct regulator_dev *dev) 2933fa5b8e0SAnuj Aggarwal { 2944ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 2953fa5b8e0SAnuj Aggarwal int dcdc = rdev_get_id(dev); 2963fa5b8e0SAnuj Aggarwal u8 shift; 2973fa5b8e0SAnuj Aggarwal 2983fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 2993fa5b8e0SAnuj Aggarwal return -EINVAL; 3003fa5b8e0SAnuj Aggarwal 3013fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - dcdc; 3024ce5ba5bSTodd Fischer return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 3034ce5ba5bSTodd Fischer 1 << shift); 3043fa5b8e0SAnuj Aggarwal } 3053fa5b8e0SAnuj Aggarwal 3064ce5ba5bSTodd Fischer static int tps6507x_pmic_ldo_enable(struct regulator_dev *dev) 3073fa5b8e0SAnuj Aggarwal { 3084ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 3093fa5b8e0SAnuj Aggarwal int ldo = rdev_get_id(dev); 3103fa5b8e0SAnuj Aggarwal u8 shift; 3113fa5b8e0SAnuj Aggarwal 3123fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 3133fa5b8e0SAnuj Aggarwal return -EINVAL; 3143fa5b8e0SAnuj Aggarwal 3153fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - ldo; 3164ce5ba5bSTodd Fischer return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 3173fa5b8e0SAnuj Aggarwal } 3183fa5b8e0SAnuj Aggarwal 3194ce5ba5bSTodd Fischer static int tps6507x_pmic_ldo_disable(struct regulator_dev *dev) 3203fa5b8e0SAnuj Aggarwal { 3214ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 3223fa5b8e0SAnuj Aggarwal int ldo = rdev_get_id(dev); 3233fa5b8e0SAnuj Aggarwal u8 shift; 3243fa5b8e0SAnuj Aggarwal 3253fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 3263fa5b8e0SAnuj Aggarwal return -EINVAL; 3273fa5b8e0SAnuj Aggarwal 3283fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - ldo; 3294ce5ba5bSTodd Fischer return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 3304ce5ba5bSTodd Fischer 1 << shift); 3313fa5b8e0SAnuj Aggarwal } 3323fa5b8e0SAnuj Aggarwal 3334ce5ba5bSTodd Fischer static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev) 3343fa5b8e0SAnuj Aggarwal { 3354ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 3363fa5b8e0SAnuj Aggarwal int data, dcdc = rdev_get_id(dev); 3373fa5b8e0SAnuj Aggarwal u8 reg; 3383fa5b8e0SAnuj Aggarwal 3393fa5b8e0SAnuj Aggarwal switch (dcdc) { 3403fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_1: 3413fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC1; 3423fa5b8e0SAnuj Aggarwal break; 3433fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_2: 3443fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC2_LOW; 3453fa5b8e0SAnuj Aggarwal break; 3463fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_3: 3473fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC3_LOW; 3483fa5b8e0SAnuj Aggarwal break; 3493fa5b8e0SAnuj Aggarwal default: 3503fa5b8e0SAnuj Aggarwal return -EINVAL; 3513fa5b8e0SAnuj Aggarwal } 3523fa5b8e0SAnuj Aggarwal 3534ce5ba5bSTodd Fischer data = tps6507x_pmic_reg_read(tps, reg); 3543fa5b8e0SAnuj Aggarwal if (data < 0) 3553fa5b8e0SAnuj Aggarwal return data; 3563fa5b8e0SAnuj Aggarwal 3573fa5b8e0SAnuj Aggarwal data &= TPS6507X_DEFDCDCX_DCDC_MASK; 3583fa5b8e0SAnuj Aggarwal return tps->info[dcdc]->table[data] * 1000; 3593fa5b8e0SAnuj Aggarwal } 3603fa5b8e0SAnuj Aggarwal 3614ce5ba5bSTodd Fischer static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, 3623fa5b8e0SAnuj Aggarwal int min_uV, int max_uV) 3633fa5b8e0SAnuj Aggarwal { 3644ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 3653fa5b8e0SAnuj Aggarwal int data, vsel, dcdc = rdev_get_id(dev); 3663fa5b8e0SAnuj Aggarwal u8 reg; 3673fa5b8e0SAnuj Aggarwal 3683fa5b8e0SAnuj Aggarwal switch (dcdc) { 3693fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_1: 3703fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC1; 3713fa5b8e0SAnuj Aggarwal break; 3723fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_2: 3733fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC2_LOW; 3743fa5b8e0SAnuj Aggarwal break; 3753fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_3: 3763fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC3_LOW; 3773fa5b8e0SAnuj Aggarwal break; 3783fa5b8e0SAnuj Aggarwal default: 3793fa5b8e0SAnuj Aggarwal return -EINVAL; 3803fa5b8e0SAnuj Aggarwal } 3813fa5b8e0SAnuj Aggarwal 3823fa5b8e0SAnuj Aggarwal if (min_uV < tps->info[dcdc]->min_uV 3833fa5b8e0SAnuj Aggarwal || min_uV > tps->info[dcdc]->max_uV) 3843fa5b8e0SAnuj Aggarwal return -EINVAL; 3853fa5b8e0SAnuj Aggarwal if (max_uV < tps->info[dcdc]->min_uV 3863fa5b8e0SAnuj Aggarwal || max_uV > tps->info[dcdc]->max_uV) 3873fa5b8e0SAnuj Aggarwal return -EINVAL; 3883fa5b8e0SAnuj Aggarwal 3893fa5b8e0SAnuj Aggarwal for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { 3903fa5b8e0SAnuj Aggarwal int mV = tps->info[dcdc]->table[vsel]; 3913fa5b8e0SAnuj Aggarwal int uV = mV * 1000; 3923fa5b8e0SAnuj Aggarwal 3933fa5b8e0SAnuj Aggarwal /* Break at the first in-range value */ 3943fa5b8e0SAnuj Aggarwal if (min_uV <= uV && uV <= max_uV) 3953fa5b8e0SAnuj Aggarwal break; 3963fa5b8e0SAnuj Aggarwal } 3973fa5b8e0SAnuj Aggarwal 3983fa5b8e0SAnuj Aggarwal /* write to the register in case we found a match */ 3993fa5b8e0SAnuj Aggarwal if (vsel == tps->info[dcdc]->table_len) 4003fa5b8e0SAnuj Aggarwal return -EINVAL; 4013fa5b8e0SAnuj Aggarwal 4024ce5ba5bSTodd Fischer data = tps6507x_pmic_reg_read(tps, reg); 4033fa5b8e0SAnuj Aggarwal if (data < 0) 4043fa5b8e0SAnuj Aggarwal return data; 4053fa5b8e0SAnuj Aggarwal 4063fa5b8e0SAnuj Aggarwal data &= ~TPS6507X_DEFDCDCX_DCDC_MASK; 4073fa5b8e0SAnuj Aggarwal data |= vsel; 4083fa5b8e0SAnuj Aggarwal 4094ce5ba5bSTodd Fischer return tps6507x_pmic_reg_write(tps, reg, data); 4103fa5b8e0SAnuj Aggarwal } 4113fa5b8e0SAnuj Aggarwal 4124ce5ba5bSTodd Fischer static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev) 4133fa5b8e0SAnuj Aggarwal { 4144ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 4153fa5b8e0SAnuj Aggarwal int data, ldo = rdev_get_id(dev); 4163fa5b8e0SAnuj Aggarwal u8 reg, mask; 4173fa5b8e0SAnuj Aggarwal 4183fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 4193fa5b8e0SAnuj Aggarwal return -EINVAL; 4203fa5b8e0SAnuj Aggarwal else { 4213fa5b8e0SAnuj Aggarwal reg = (ldo == TPS6507X_LDO_1 ? 4223fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); 4233fa5b8e0SAnuj Aggarwal mask = (ldo == TPS6507X_LDO_1 ? 4243fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1_LDO1_MASK : 4253fa5b8e0SAnuj Aggarwal TPS6507X_REG_DEFLDO2_LDO2_MASK); 4263fa5b8e0SAnuj Aggarwal } 4273fa5b8e0SAnuj Aggarwal 4284ce5ba5bSTodd Fischer data = tps6507x_pmic_reg_read(tps, reg); 4293fa5b8e0SAnuj Aggarwal if (data < 0) 4303fa5b8e0SAnuj Aggarwal return data; 4313fa5b8e0SAnuj Aggarwal 4323fa5b8e0SAnuj Aggarwal data &= mask; 4333fa5b8e0SAnuj Aggarwal return tps->info[ldo]->table[data] * 1000; 4343fa5b8e0SAnuj Aggarwal } 4353fa5b8e0SAnuj Aggarwal 4364ce5ba5bSTodd Fischer static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, 4373fa5b8e0SAnuj Aggarwal int min_uV, int max_uV) 4383fa5b8e0SAnuj Aggarwal { 4394ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 4403fa5b8e0SAnuj Aggarwal int data, vsel, ldo = rdev_get_id(dev); 4413fa5b8e0SAnuj Aggarwal u8 reg, mask; 4423fa5b8e0SAnuj Aggarwal 4433fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 4443fa5b8e0SAnuj Aggarwal return -EINVAL; 4453fa5b8e0SAnuj Aggarwal else { 4463fa5b8e0SAnuj Aggarwal reg = (ldo == TPS6507X_LDO_1 ? 4473fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); 4483fa5b8e0SAnuj Aggarwal mask = (ldo == TPS6507X_LDO_1 ? 4493fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1_LDO1_MASK : 4503fa5b8e0SAnuj Aggarwal TPS6507X_REG_DEFLDO2_LDO2_MASK); 4513fa5b8e0SAnuj Aggarwal } 4523fa5b8e0SAnuj Aggarwal 4533fa5b8e0SAnuj Aggarwal if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV) 4543fa5b8e0SAnuj Aggarwal return -EINVAL; 4553fa5b8e0SAnuj Aggarwal if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV) 4563fa5b8e0SAnuj Aggarwal return -EINVAL; 4573fa5b8e0SAnuj Aggarwal 4583fa5b8e0SAnuj Aggarwal for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) { 4593fa5b8e0SAnuj Aggarwal int mV = tps->info[ldo]->table[vsel]; 4603fa5b8e0SAnuj Aggarwal int uV = mV * 1000; 4613fa5b8e0SAnuj Aggarwal 4623fa5b8e0SAnuj Aggarwal /* Break at the first in-range value */ 4633fa5b8e0SAnuj Aggarwal if (min_uV <= uV && uV <= max_uV) 4643fa5b8e0SAnuj Aggarwal break; 4653fa5b8e0SAnuj Aggarwal } 4663fa5b8e0SAnuj Aggarwal 4673fa5b8e0SAnuj Aggarwal if (vsel == tps->info[ldo]->table_len) 4683fa5b8e0SAnuj Aggarwal return -EINVAL; 4693fa5b8e0SAnuj Aggarwal 4704ce5ba5bSTodd Fischer data = tps6507x_pmic_reg_read(tps, reg); 4713fa5b8e0SAnuj Aggarwal if (data < 0) 4723fa5b8e0SAnuj Aggarwal return data; 4733fa5b8e0SAnuj Aggarwal 4743fa5b8e0SAnuj Aggarwal data &= ~mask; 4753fa5b8e0SAnuj Aggarwal data |= vsel; 4763fa5b8e0SAnuj Aggarwal 4774ce5ba5bSTodd Fischer return tps6507x_pmic_reg_write(tps, reg, data); 4783fa5b8e0SAnuj Aggarwal } 4793fa5b8e0SAnuj Aggarwal 4804ce5ba5bSTodd Fischer static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev, 4813fa5b8e0SAnuj Aggarwal unsigned selector) 4823fa5b8e0SAnuj Aggarwal { 4834ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 4843fa5b8e0SAnuj Aggarwal int dcdc = rdev_get_id(dev); 4853fa5b8e0SAnuj Aggarwal 4863fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 4873fa5b8e0SAnuj Aggarwal return -EINVAL; 4883fa5b8e0SAnuj Aggarwal 4893fa5b8e0SAnuj Aggarwal if (selector >= tps->info[dcdc]->table_len) 4903fa5b8e0SAnuj Aggarwal return -EINVAL; 4913fa5b8e0SAnuj Aggarwal else 4923fa5b8e0SAnuj Aggarwal return tps->info[dcdc]->table[selector] * 1000; 4933fa5b8e0SAnuj Aggarwal } 4943fa5b8e0SAnuj Aggarwal 4954ce5ba5bSTodd Fischer static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev, 4963fa5b8e0SAnuj Aggarwal unsigned selector) 4973fa5b8e0SAnuj Aggarwal { 4984ce5ba5bSTodd Fischer struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 4993fa5b8e0SAnuj Aggarwal int ldo = rdev_get_id(dev); 5003fa5b8e0SAnuj Aggarwal 5013fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 5023fa5b8e0SAnuj Aggarwal return -EINVAL; 5033fa5b8e0SAnuj Aggarwal 5043fa5b8e0SAnuj Aggarwal if (selector >= tps->info[ldo]->table_len) 5053fa5b8e0SAnuj Aggarwal return -EINVAL; 5063fa5b8e0SAnuj Aggarwal else 5073fa5b8e0SAnuj Aggarwal return tps->info[ldo]->table[selector] * 1000; 5083fa5b8e0SAnuj Aggarwal } 5093fa5b8e0SAnuj Aggarwal 5103fa5b8e0SAnuj Aggarwal /* Operations permitted on VDCDCx */ 5114ce5ba5bSTodd Fischer static struct regulator_ops tps6507x_pmic_dcdc_ops = { 5124ce5ba5bSTodd Fischer .is_enabled = tps6507x_pmic_dcdc_is_enabled, 5134ce5ba5bSTodd Fischer .enable = tps6507x_pmic_dcdc_enable, 5144ce5ba5bSTodd Fischer .disable = tps6507x_pmic_dcdc_disable, 5154ce5ba5bSTodd Fischer .get_voltage = tps6507x_pmic_dcdc_get_voltage, 5164ce5ba5bSTodd Fischer .set_voltage = tps6507x_pmic_dcdc_set_voltage, 5174ce5ba5bSTodd Fischer .list_voltage = tps6507x_pmic_dcdc_list_voltage, 5183fa5b8e0SAnuj Aggarwal }; 5193fa5b8e0SAnuj Aggarwal 5203fa5b8e0SAnuj Aggarwal /* Operations permitted on LDOx */ 5214ce5ba5bSTodd Fischer static struct regulator_ops tps6507x_pmic_ldo_ops = { 5224ce5ba5bSTodd Fischer .is_enabled = tps6507x_pmic_ldo_is_enabled, 5234ce5ba5bSTodd Fischer .enable = tps6507x_pmic_ldo_enable, 5244ce5ba5bSTodd Fischer .disable = tps6507x_pmic_ldo_disable, 5254ce5ba5bSTodd Fischer .get_voltage = tps6507x_pmic_ldo_get_voltage, 5264ce5ba5bSTodd Fischer .set_voltage = tps6507x_pmic_ldo_set_voltage, 5274ce5ba5bSTodd Fischer .list_voltage = tps6507x_pmic_ldo_list_voltage, 5283fa5b8e0SAnuj Aggarwal }; 5293fa5b8e0SAnuj Aggarwal 530*31dd6a26STodd Fischer static __devinit 531*31dd6a26STodd Fischer int tps6507x_pmic_probe(struct platform_device *pdev) 5323fa5b8e0SAnuj Aggarwal { 533*31dd6a26STodd Fischer struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); 5343fa5b8e0SAnuj Aggarwal static int desc_id; 535*31dd6a26STodd Fischer const struct tps_info *info = &tps6507x_pmic_regs[0]; 5363fa5b8e0SAnuj Aggarwal struct regulator_init_data *init_data; 5373fa5b8e0SAnuj Aggarwal struct regulator_dev *rdev; 5384ce5ba5bSTodd Fischer struct tps6507x_pmic *tps; 5390bc20bbaSTodd Fischer struct tps6507x_board *tps_board; 5403fa5b8e0SAnuj Aggarwal int i; 54156c23492SDmitry Torokhov int error; 5423fa5b8e0SAnuj Aggarwal 5433fa5b8e0SAnuj Aggarwal /** 5440bc20bbaSTodd Fischer * tps_board points to pmic related constants 5450bc20bbaSTodd Fischer * coming from the board-evm file. 5460bc20bbaSTodd Fischer */ 5470bc20bbaSTodd Fischer 548*31dd6a26STodd Fischer tps_board = dev_get_platdata(tps6507x_dev->dev); 5490bc20bbaSTodd Fischer if (!tps_board) 5500bc20bbaSTodd Fischer return -EINVAL; 5510bc20bbaSTodd Fischer 5520bc20bbaSTodd Fischer /** 5533fa5b8e0SAnuj Aggarwal * init_data points to array of regulator_init structures 5543fa5b8e0SAnuj Aggarwal * coming from the board-evm file. 5553fa5b8e0SAnuj Aggarwal */ 5560bc20bbaSTodd Fischer init_data = tps_board->tps6507x_pmic_init_data; 5573fa5b8e0SAnuj Aggarwal if (!init_data) 5580bc20bbaSTodd Fischer return -EINVAL; 5593fa5b8e0SAnuj Aggarwal 5603fa5b8e0SAnuj Aggarwal tps = kzalloc(sizeof(*tps), GFP_KERNEL); 5613fa5b8e0SAnuj Aggarwal if (!tps) 5623fa5b8e0SAnuj Aggarwal return -ENOMEM; 5633fa5b8e0SAnuj Aggarwal 5643fa5b8e0SAnuj Aggarwal mutex_init(&tps->io_lock); 5653fa5b8e0SAnuj Aggarwal 5663fa5b8e0SAnuj Aggarwal /* common for all regulators */ 567*31dd6a26STodd Fischer tps->mfd = tps6507x_dev; 5683fa5b8e0SAnuj Aggarwal 5693fa5b8e0SAnuj Aggarwal for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { 5703fa5b8e0SAnuj Aggarwal /* Register the regulators */ 5713fa5b8e0SAnuj Aggarwal tps->info[i] = info; 5723fa5b8e0SAnuj Aggarwal tps->desc[i].name = info->name; 5733fa5b8e0SAnuj Aggarwal tps->desc[i].id = desc_id++; 5743fa5b8e0SAnuj Aggarwal tps->desc[i].n_voltages = num_voltages[i]; 5753fa5b8e0SAnuj Aggarwal tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? 5764ce5ba5bSTodd Fischer &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); 5773fa5b8e0SAnuj Aggarwal tps->desc[i].type = REGULATOR_VOLTAGE; 5783fa5b8e0SAnuj Aggarwal tps->desc[i].owner = THIS_MODULE; 5793fa5b8e0SAnuj Aggarwal 5803fa5b8e0SAnuj Aggarwal rdev = regulator_register(&tps->desc[i], 581*31dd6a26STodd Fischer tps6507x_dev->dev, init_data, tps); 5823fa5b8e0SAnuj Aggarwal if (IS_ERR(rdev)) { 583*31dd6a26STodd Fischer dev_err(tps6507x_dev->dev, 584*31dd6a26STodd Fischer "failed to register %s regulator\n", 585*31dd6a26STodd Fischer pdev->name); 58656c23492SDmitry Torokhov error = PTR_ERR(rdev); 58756c23492SDmitry Torokhov goto fail; 5883fa5b8e0SAnuj Aggarwal } 5893fa5b8e0SAnuj Aggarwal 5903fa5b8e0SAnuj Aggarwal /* Save regulator for cleanup */ 5913fa5b8e0SAnuj Aggarwal tps->rdev[i] = rdev; 5923fa5b8e0SAnuj Aggarwal } 5933fa5b8e0SAnuj Aggarwal 594*31dd6a26STodd Fischer tps6507x_dev->pmic = tps; 5953fa5b8e0SAnuj Aggarwal 5963fa5b8e0SAnuj Aggarwal return 0; 59756c23492SDmitry Torokhov 59856c23492SDmitry Torokhov fail: 59956c23492SDmitry Torokhov while (--i >= 0) 60056c23492SDmitry Torokhov regulator_unregister(tps->rdev[i]); 60156c23492SDmitry Torokhov 60256c23492SDmitry Torokhov kfree(tps); 60356c23492SDmitry Torokhov return error; 6043fa5b8e0SAnuj Aggarwal } 6053fa5b8e0SAnuj Aggarwal 6063fa5b8e0SAnuj Aggarwal /** 6074ce5ba5bSTodd Fischer * tps6507x_remove - TPS6507x driver i2c remove handler 6083fa5b8e0SAnuj Aggarwal * @client: i2c driver client device structure 6093fa5b8e0SAnuj Aggarwal * 6103fa5b8e0SAnuj Aggarwal * Unregister TPS driver as an i2c client device driver 6113fa5b8e0SAnuj Aggarwal */ 612*31dd6a26STodd Fischer static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) 6133fa5b8e0SAnuj Aggarwal { 614*31dd6a26STodd Fischer struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); 615*31dd6a26STodd Fischer struct tps6507x_pmic *tps = tps6507x_dev->pmic; 6163fa5b8e0SAnuj Aggarwal int i; 6173fa5b8e0SAnuj Aggarwal 6183fa5b8e0SAnuj Aggarwal for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) 6193fa5b8e0SAnuj Aggarwal regulator_unregister(tps->rdev[i]); 6203fa5b8e0SAnuj Aggarwal 6213fa5b8e0SAnuj Aggarwal kfree(tps); 6223fa5b8e0SAnuj Aggarwal 6233fa5b8e0SAnuj Aggarwal return 0; 6243fa5b8e0SAnuj Aggarwal } 6253fa5b8e0SAnuj Aggarwal 626*31dd6a26STodd Fischer static struct platform_driver tps6507x_pmic_driver = { 6273fa5b8e0SAnuj Aggarwal .driver = { 628*31dd6a26STodd Fischer .name = "tps6507x-pmic", 6293fa5b8e0SAnuj Aggarwal .owner = THIS_MODULE, 6303fa5b8e0SAnuj Aggarwal }, 6314ce5ba5bSTodd Fischer .probe = tps6507x_pmic_probe, 6324ce5ba5bSTodd Fischer .remove = __devexit_p(tps6507x_pmic_remove), 6333fa5b8e0SAnuj Aggarwal }; 6343fa5b8e0SAnuj Aggarwal 6353fa5b8e0SAnuj Aggarwal /** 6364ce5ba5bSTodd Fischer * tps6507x_pmic_init 6373fa5b8e0SAnuj Aggarwal * 6383fa5b8e0SAnuj Aggarwal * Module init function 6393fa5b8e0SAnuj Aggarwal */ 6404ce5ba5bSTodd Fischer static int __init tps6507x_pmic_init(void) 6413fa5b8e0SAnuj Aggarwal { 642*31dd6a26STodd Fischer return platform_driver_register(&tps6507x_pmic_driver); 6433fa5b8e0SAnuj Aggarwal } 6444ce5ba5bSTodd Fischer subsys_initcall(tps6507x_pmic_init); 6453fa5b8e0SAnuj Aggarwal 6463fa5b8e0SAnuj Aggarwal /** 6474ce5ba5bSTodd Fischer * tps6507x_pmic_cleanup 6483fa5b8e0SAnuj Aggarwal * 6493fa5b8e0SAnuj Aggarwal * Module exit function 6503fa5b8e0SAnuj Aggarwal */ 6514ce5ba5bSTodd Fischer static void __exit tps6507x_pmic_cleanup(void) 6523fa5b8e0SAnuj Aggarwal { 653*31dd6a26STodd Fischer platform_driver_unregister(&tps6507x_pmic_driver); 6543fa5b8e0SAnuj Aggarwal } 6554ce5ba5bSTodd Fischer module_exit(tps6507x_pmic_cleanup); 6563fa5b8e0SAnuj Aggarwal 6573fa5b8e0SAnuj Aggarwal MODULE_AUTHOR("Texas Instruments"); 6583fa5b8e0SAnuj Aggarwal MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); 6593fa5b8e0SAnuj Aggarwal MODULE_LICENSE("GPL v2"); 660*31dd6a26STodd Fischer MODULE_ALIAS("platform:tps6507x-pmic"); 661