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/i2c.h> 263fa5b8e0SAnuj Aggarwal #include <linux/delay.h> 275a0e3ad6STejun Heo #include <linux/slab.h> 28d183fcc9STodd Fischer #include <linux/mfd/tps6507x.h> 293fa5b8e0SAnuj Aggarwal 303fa5b8e0SAnuj Aggarwal /* DCDC's */ 313fa5b8e0SAnuj Aggarwal #define TPS6507X_DCDC_1 0 323fa5b8e0SAnuj Aggarwal #define TPS6507X_DCDC_2 1 333fa5b8e0SAnuj Aggarwal #define TPS6507X_DCDC_3 2 343fa5b8e0SAnuj Aggarwal /* LDOs */ 353fa5b8e0SAnuj Aggarwal #define TPS6507X_LDO_1 3 363fa5b8e0SAnuj Aggarwal #define TPS6507X_LDO_2 4 373fa5b8e0SAnuj Aggarwal 383fa5b8e0SAnuj Aggarwal #define TPS6507X_MAX_REG_ID TPS6507X_LDO_2 393fa5b8e0SAnuj Aggarwal 403fa5b8e0SAnuj Aggarwal /* Number of step-down converters available */ 413fa5b8e0SAnuj Aggarwal #define TPS6507X_NUM_DCDC 3 423fa5b8e0SAnuj Aggarwal /* Number of LDO voltage regulators available */ 433fa5b8e0SAnuj Aggarwal #define TPS6507X_NUM_LDO 2 443fa5b8e0SAnuj Aggarwal /* Number of total regulators available */ 453fa5b8e0SAnuj Aggarwal #define TPS6507X_NUM_REGULATOR (TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO) 463fa5b8e0SAnuj Aggarwal 473fa5b8e0SAnuj Aggarwal /* Supported voltage values for regulators (in milliVolts) */ 483fa5b8e0SAnuj Aggarwal static const u16 VDCDCx_VSEL_table[] = { 493fa5b8e0SAnuj Aggarwal 725, 750, 775, 800, 503fa5b8e0SAnuj Aggarwal 825, 850, 875, 900, 513fa5b8e0SAnuj Aggarwal 925, 950, 975, 1000, 523fa5b8e0SAnuj Aggarwal 1025, 1050, 1075, 1100, 533fa5b8e0SAnuj Aggarwal 1125, 1150, 1175, 1200, 543fa5b8e0SAnuj Aggarwal 1225, 1250, 1275, 1300, 553fa5b8e0SAnuj Aggarwal 1325, 1350, 1375, 1400, 563fa5b8e0SAnuj Aggarwal 1425, 1450, 1475, 1500, 573fa5b8e0SAnuj Aggarwal 1550, 1600, 1650, 1700, 583fa5b8e0SAnuj Aggarwal 1750, 1800, 1850, 1900, 593fa5b8e0SAnuj Aggarwal 1950, 2000, 2050, 2100, 603fa5b8e0SAnuj Aggarwal 2150, 2200, 2250, 2300, 613fa5b8e0SAnuj Aggarwal 2350, 2400, 2450, 2500, 623fa5b8e0SAnuj Aggarwal 2550, 2600, 2650, 2700, 633fa5b8e0SAnuj Aggarwal 2750, 2800, 2850, 2900, 643fa5b8e0SAnuj Aggarwal 3000, 3100, 3200, 3300, 653fa5b8e0SAnuj Aggarwal }; 663fa5b8e0SAnuj Aggarwal 673fa5b8e0SAnuj Aggarwal static const u16 LDO1_VSEL_table[] = { 683fa5b8e0SAnuj Aggarwal 1000, 1100, 1200, 1250, 693fa5b8e0SAnuj Aggarwal 1300, 1350, 1400, 1500, 703fa5b8e0SAnuj Aggarwal 1600, 1800, 2500, 2750, 713fa5b8e0SAnuj Aggarwal 2800, 3000, 3100, 3300, 723fa5b8e0SAnuj Aggarwal }; 733fa5b8e0SAnuj Aggarwal 743fa5b8e0SAnuj Aggarwal static const u16 LDO2_VSEL_table[] = { 753fa5b8e0SAnuj Aggarwal 725, 750, 775, 800, 763fa5b8e0SAnuj Aggarwal 825, 850, 875, 900, 773fa5b8e0SAnuj Aggarwal 925, 950, 975, 1000, 783fa5b8e0SAnuj Aggarwal 1025, 1050, 1075, 1100, 793fa5b8e0SAnuj Aggarwal 1125, 1150, 1175, 1200, 803fa5b8e0SAnuj Aggarwal 1225, 1250, 1275, 1300, 813fa5b8e0SAnuj Aggarwal 1325, 1350, 1375, 1400, 823fa5b8e0SAnuj Aggarwal 1425, 1450, 1475, 1500, 833fa5b8e0SAnuj Aggarwal 1550, 1600, 1650, 1700, 843fa5b8e0SAnuj Aggarwal 1750, 1800, 1850, 1900, 853fa5b8e0SAnuj Aggarwal 1950, 2000, 2050, 2100, 863fa5b8e0SAnuj Aggarwal 2150, 2200, 2250, 2300, 873fa5b8e0SAnuj Aggarwal 2350, 2400, 2450, 2500, 883fa5b8e0SAnuj Aggarwal 2550, 2600, 2650, 2700, 893fa5b8e0SAnuj Aggarwal 2750, 2800, 2850, 2900, 903fa5b8e0SAnuj Aggarwal 3000, 3100, 3200, 3300, 913fa5b8e0SAnuj Aggarwal }; 923fa5b8e0SAnuj Aggarwal 933fa5b8e0SAnuj Aggarwal static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDCx_VSEL_table), 943fa5b8e0SAnuj Aggarwal ARRAY_SIZE(VDCDCx_VSEL_table), 953fa5b8e0SAnuj Aggarwal ARRAY_SIZE(VDCDCx_VSEL_table), 963fa5b8e0SAnuj Aggarwal ARRAY_SIZE(LDO1_VSEL_table), 973fa5b8e0SAnuj Aggarwal ARRAY_SIZE(LDO2_VSEL_table)}; 983fa5b8e0SAnuj Aggarwal 993fa5b8e0SAnuj Aggarwal struct tps_info { 1003fa5b8e0SAnuj Aggarwal const char *name; 1013fa5b8e0SAnuj Aggarwal unsigned min_uV; 1023fa5b8e0SAnuj Aggarwal unsigned max_uV; 1033fa5b8e0SAnuj Aggarwal u8 table_len; 1043fa5b8e0SAnuj Aggarwal const u16 *table; 1053fa5b8e0SAnuj Aggarwal }; 1063fa5b8e0SAnuj Aggarwal 1073fa5b8e0SAnuj Aggarwal struct tps_pmic { 1083fa5b8e0SAnuj Aggarwal struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; 1093fa5b8e0SAnuj Aggarwal struct i2c_client *client; 1103fa5b8e0SAnuj Aggarwal struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; 1113fa5b8e0SAnuj Aggarwal const struct tps_info *info[TPS6507X_NUM_REGULATOR]; 1123fa5b8e0SAnuj Aggarwal struct mutex io_lock; 1133fa5b8e0SAnuj Aggarwal }; 1143fa5b8e0SAnuj Aggarwal 1153fa5b8e0SAnuj Aggarwal static inline int tps_6507x_read(struct tps_pmic *tps, u8 reg) 1163fa5b8e0SAnuj Aggarwal { 1173fa5b8e0SAnuj Aggarwal return i2c_smbus_read_byte_data(tps->client, reg); 1183fa5b8e0SAnuj Aggarwal } 1193fa5b8e0SAnuj Aggarwal 1203fa5b8e0SAnuj Aggarwal static inline int tps_6507x_write(struct tps_pmic *tps, u8 reg, u8 val) 1213fa5b8e0SAnuj Aggarwal { 1223fa5b8e0SAnuj Aggarwal return i2c_smbus_write_byte_data(tps->client, reg, val); 1233fa5b8e0SAnuj Aggarwal } 1243fa5b8e0SAnuj Aggarwal 1253fa5b8e0SAnuj Aggarwal static int tps_6507x_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) 1263fa5b8e0SAnuj Aggarwal { 1273fa5b8e0SAnuj Aggarwal int err, data; 1283fa5b8e0SAnuj Aggarwal 1293fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 1303fa5b8e0SAnuj Aggarwal 1313fa5b8e0SAnuj Aggarwal data = tps_6507x_read(tps, reg); 1323fa5b8e0SAnuj Aggarwal if (data < 0) { 1333fa5b8e0SAnuj Aggarwal dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); 1343fa5b8e0SAnuj Aggarwal err = data; 1353fa5b8e0SAnuj Aggarwal goto out; 1363fa5b8e0SAnuj Aggarwal } 1373fa5b8e0SAnuj Aggarwal 1383fa5b8e0SAnuj Aggarwal data |= mask; 1393fa5b8e0SAnuj Aggarwal err = tps_6507x_write(tps, reg, data); 1403fa5b8e0SAnuj Aggarwal if (err) 1413fa5b8e0SAnuj Aggarwal dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); 1423fa5b8e0SAnuj Aggarwal 1433fa5b8e0SAnuj Aggarwal out: 1443fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 1453fa5b8e0SAnuj Aggarwal return err; 1463fa5b8e0SAnuj Aggarwal } 1473fa5b8e0SAnuj Aggarwal 1483fa5b8e0SAnuj Aggarwal static int tps_6507x_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) 1493fa5b8e0SAnuj Aggarwal { 1503fa5b8e0SAnuj Aggarwal int err, data; 1513fa5b8e0SAnuj Aggarwal 1523fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 1533fa5b8e0SAnuj Aggarwal 1543fa5b8e0SAnuj Aggarwal data = tps_6507x_read(tps, reg); 1553fa5b8e0SAnuj Aggarwal if (data < 0) { 1563fa5b8e0SAnuj Aggarwal dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); 1573fa5b8e0SAnuj Aggarwal err = data; 1583fa5b8e0SAnuj Aggarwal goto out; 1593fa5b8e0SAnuj Aggarwal } 1603fa5b8e0SAnuj Aggarwal 1613fa5b8e0SAnuj Aggarwal data &= ~mask; 1623fa5b8e0SAnuj Aggarwal err = tps_6507x_write(tps, reg, data); 1633fa5b8e0SAnuj Aggarwal if (err) 1643fa5b8e0SAnuj Aggarwal dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); 1653fa5b8e0SAnuj Aggarwal 1663fa5b8e0SAnuj Aggarwal out: 1673fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 1683fa5b8e0SAnuj Aggarwal return err; 1693fa5b8e0SAnuj Aggarwal } 1703fa5b8e0SAnuj Aggarwal 1713fa5b8e0SAnuj Aggarwal static int tps_6507x_reg_read(struct tps_pmic *tps, u8 reg) 1723fa5b8e0SAnuj Aggarwal { 1733fa5b8e0SAnuj Aggarwal int data; 1743fa5b8e0SAnuj Aggarwal 1753fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 1763fa5b8e0SAnuj Aggarwal 1773fa5b8e0SAnuj Aggarwal data = tps_6507x_read(tps, reg); 1783fa5b8e0SAnuj Aggarwal if (data < 0) 1793fa5b8e0SAnuj Aggarwal dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); 1803fa5b8e0SAnuj Aggarwal 1813fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 1823fa5b8e0SAnuj Aggarwal return data; 1833fa5b8e0SAnuj Aggarwal } 1843fa5b8e0SAnuj Aggarwal 1853fa5b8e0SAnuj Aggarwal static int tps_6507x_reg_write(struct tps_pmic *tps, u8 reg, u8 val) 1863fa5b8e0SAnuj Aggarwal { 1873fa5b8e0SAnuj Aggarwal int err; 1883fa5b8e0SAnuj Aggarwal 1893fa5b8e0SAnuj Aggarwal mutex_lock(&tps->io_lock); 1903fa5b8e0SAnuj Aggarwal 1913fa5b8e0SAnuj Aggarwal err = tps_6507x_write(tps, reg, val); 1923fa5b8e0SAnuj Aggarwal if (err < 0) 1933fa5b8e0SAnuj Aggarwal dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); 1943fa5b8e0SAnuj Aggarwal 1953fa5b8e0SAnuj Aggarwal mutex_unlock(&tps->io_lock); 1963fa5b8e0SAnuj Aggarwal return err; 1973fa5b8e0SAnuj Aggarwal } 1983fa5b8e0SAnuj Aggarwal 1993fa5b8e0SAnuj Aggarwal static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) 2003fa5b8e0SAnuj Aggarwal { 2013fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2023fa5b8e0SAnuj Aggarwal int data, dcdc = rdev_get_id(dev); 2033fa5b8e0SAnuj Aggarwal u8 shift; 2043fa5b8e0SAnuj Aggarwal 2053fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 2063fa5b8e0SAnuj Aggarwal return -EINVAL; 2073fa5b8e0SAnuj Aggarwal 2083fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - dcdc; 2093fa5b8e0SAnuj Aggarwal data = tps_6507x_reg_read(tps, TPS6507X_REG_CON_CTRL1); 2103fa5b8e0SAnuj Aggarwal 2113fa5b8e0SAnuj Aggarwal if (data < 0) 2123fa5b8e0SAnuj Aggarwal return data; 2133fa5b8e0SAnuj Aggarwal else 2143fa5b8e0SAnuj Aggarwal return (data & 1<<shift) ? 1 : 0; 2153fa5b8e0SAnuj Aggarwal } 2163fa5b8e0SAnuj Aggarwal 2173fa5b8e0SAnuj Aggarwal static int tps6507x_ldo_is_enabled(struct regulator_dev *dev) 2183fa5b8e0SAnuj Aggarwal { 2193fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2203fa5b8e0SAnuj Aggarwal int data, ldo = rdev_get_id(dev); 2213fa5b8e0SAnuj Aggarwal u8 shift; 2223fa5b8e0SAnuj Aggarwal 2233fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 2243fa5b8e0SAnuj Aggarwal return -EINVAL; 2253fa5b8e0SAnuj Aggarwal 2263fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - ldo; 2273fa5b8e0SAnuj Aggarwal data = tps_6507x_reg_read(tps, TPS6507X_REG_CON_CTRL1); 2283fa5b8e0SAnuj Aggarwal 2293fa5b8e0SAnuj Aggarwal if (data < 0) 2303fa5b8e0SAnuj Aggarwal return data; 2313fa5b8e0SAnuj Aggarwal else 2323fa5b8e0SAnuj Aggarwal return (data & 1<<shift) ? 1 : 0; 2333fa5b8e0SAnuj Aggarwal } 2343fa5b8e0SAnuj Aggarwal 2353fa5b8e0SAnuj Aggarwal static int tps6507x_dcdc_enable(struct regulator_dev *dev) 2363fa5b8e0SAnuj Aggarwal { 2373fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2383fa5b8e0SAnuj Aggarwal int dcdc = rdev_get_id(dev); 2393fa5b8e0SAnuj Aggarwal u8 shift; 2403fa5b8e0SAnuj Aggarwal 2413fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 2423fa5b8e0SAnuj Aggarwal return -EINVAL; 2433fa5b8e0SAnuj Aggarwal 2443fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - dcdc; 2453fa5b8e0SAnuj Aggarwal return tps_6507x_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 2463fa5b8e0SAnuj Aggarwal } 2473fa5b8e0SAnuj Aggarwal 2483fa5b8e0SAnuj Aggarwal static int tps6507x_dcdc_disable(struct regulator_dev *dev) 2493fa5b8e0SAnuj Aggarwal { 2503fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2513fa5b8e0SAnuj Aggarwal int dcdc = rdev_get_id(dev); 2523fa5b8e0SAnuj Aggarwal u8 shift; 2533fa5b8e0SAnuj Aggarwal 2543fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 2553fa5b8e0SAnuj Aggarwal return -EINVAL; 2563fa5b8e0SAnuj Aggarwal 2573fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - dcdc; 2583fa5b8e0SAnuj Aggarwal return tps_6507x_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 2593fa5b8e0SAnuj Aggarwal } 2603fa5b8e0SAnuj Aggarwal 2613fa5b8e0SAnuj Aggarwal static int tps6507x_ldo_enable(struct regulator_dev *dev) 2623fa5b8e0SAnuj Aggarwal { 2633fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2643fa5b8e0SAnuj Aggarwal int 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; 2713fa5b8e0SAnuj Aggarwal return tps_6507x_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 2723fa5b8e0SAnuj Aggarwal } 2733fa5b8e0SAnuj Aggarwal 2743fa5b8e0SAnuj Aggarwal static int tps6507x_ldo_disable(struct regulator_dev *dev) 2753fa5b8e0SAnuj Aggarwal { 2763fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2773fa5b8e0SAnuj Aggarwal int ldo = rdev_get_id(dev); 2783fa5b8e0SAnuj Aggarwal u8 shift; 2793fa5b8e0SAnuj Aggarwal 2803fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 2813fa5b8e0SAnuj Aggarwal return -EINVAL; 2823fa5b8e0SAnuj Aggarwal 2833fa5b8e0SAnuj Aggarwal shift = TPS6507X_MAX_REG_ID - ldo; 2843fa5b8e0SAnuj Aggarwal return tps_6507x_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 2853fa5b8e0SAnuj Aggarwal } 2863fa5b8e0SAnuj Aggarwal 2873fa5b8e0SAnuj Aggarwal static int tps6507x_dcdc_get_voltage(struct regulator_dev *dev) 2883fa5b8e0SAnuj Aggarwal { 2893fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 2903fa5b8e0SAnuj Aggarwal int data, dcdc = rdev_get_id(dev); 2913fa5b8e0SAnuj Aggarwal u8 reg; 2923fa5b8e0SAnuj Aggarwal 2933fa5b8e0SAnuj Aggarwal switch (dcdc) { 2943fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_1: 2953fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC1; 2963fa5b8e0SAnuj Aggarwal break; 2973fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_2: 2983fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC2_LOW; 2993fa5b8e0SAnuj Aggarwal break; 3003fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_3: 3013fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC3_LOW; 3023fa5b8e0SAnuj Aggarwal break; 3033fa5b8e0SAnuj Aggarwal default: 3043fa5b8e0SAnuj Aggarwal return -EINVAL; 3053fa5b8e0SAnuj Aggarwal } 3063fa5b8e0SAnuj Aggarwal 3073fa5b8e0SAnuj Aggarwal data = tps_6507x_reg_read(tps, reg); 3083fa5b8e0SAnuj Aggarwal if (data < 0) 3093fa5b8e0SAnuj Aggarwal return data; 3103fa5b8e0SAnuj Aggarwal 3113fa5b8e0SAnuj Aggarwal data &= TPS6507X_DEFDCDCX_DCDC_MASK; 3123fa5b8e0SAnuj Aggarwal return tps->info[dcdc]->table[data] * 1000; 3133fa5b8e0SAnuj Aggarwal } 3143fa5b8e0SAnuj Aggarwal 3153fa5b8e0SAnuj Aggarwal static int tps6507x_dcdc_set_voltage(struct regulator_dev *dev, 3163fa5b8e0SAnuj Aggarwal int min_uV, int max_uV) 3173fa5b8e0SAnuj Aggarwal { 3183fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 3193fa5b8e0SAnuj Aggarwal int data, vsel, dcdc = rdev_get_id(dev); 3203fa5b8e0SAnuj Aggarwal u8 reg; 3213fa5b8e0SAnuj Aggarwal 3223fa5b8e0SAnuj Aggarwal switch (dcdc) { 3233fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_1: 3243fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC1; 3253fa5b8e0SAnuj Aggarwal break; 3263fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_2: 3273fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC2_LOW; 3283fa5b8e0SAnuj Aggarwal break; 3293fa5b8e0SAnuj Aggarwal case TPS6507X_DCDC_3: 3303fa5b8e0SAnuj Aggarwal reg = TPS6507X_REG_DEFDCDC3_LOW; 3313fa5b8e0SAnuj Aggarwal break; 3323fa5b8e0SAnuj Aggarwal default: 3333fa5b8e0SAnuj Aggarwal return -EINVAL; 3343fa5b8e0SAnuj Aggarwal } 3353fa5b8e0SAnuj Aggarwal 3363fa5b8e0SAnuj Aggarwal if (min_uV < tps->info[dcdc]->min_uV 3373fa5b8e0SAnuj Aggarwal || min_uV > tps->info[dcdc]->max_uV) 3383fa5b8e0SAnuj Aggarwal return -EINVAL; 3393fa5b8e0SAnuj Aggarwal if (max_uV < tps->info[dcdc]->min_uV 3403fa5b8e0SAnuj Aggarwal || max_uV > tps->info[dcdc]->max_uV) 3413fa5b8e0SAnuj Aggarwal return -EINVAL; 3423fa5b8e0SAnuj Aggarwal 3433fa5b8e0SAnuj Aggarwal for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { 3443fa5b8e0SAnuj Aggarwal int mV = tps->info[dcdc]->table[vsel]; 3453fa5b8e0SAnuj Aggarwal int uV = mV * 1000; 3463fa5b8e0SAnuj Aggarwal 3473fa5b8e0SAnuj Aggarwal /* Break at the first in-range value */ 3483fa5b8e0SAnuj Aggarwal if (min_uV <= uV && uV <= max_uV) 3493fa5b8e0SAnuj Aggarwal break; 3503fa5b8e0SAnuj Aggarwal } 3513fa5b8e0SAnuj Aggarwal 3523fa5b8e0SAnuj Aggarwal /* write to the register in case we found a match */ 3533fa5b8e0SAnuj Aggarwal if (vsel == tps->info[dcdc]->table_len) 3543fa5b8e0SAnuj Aggarwal return -EINVAL; 3553fa5b8e0SAnuj Aggarwal 3563fa5b8e0SAnuj Aggarwal data = tps_6507x_reg_read(tps, reg); 3573fa5b8e0SAnuj Aggarwal if (data < 0) 3583fa5b8e0SAnuj Aggarwal return data; 3593fa5b8e0SAnuj Aggarwal 3603fa5b8e0SAnuj Aggarwal data &= ~TPS6507X_DEFDCDCX_DCDC_MASK; 3613fa5b8e0SAnuj Aggarwal data |= vsel; 3623fa5b8e0SAnuj Aggarwal 3633fa5b8e0SAnuj Aggarwal return tps_6507x_reg_write(tps, reg, data); 3643fa5b8e0SAnuj Aggarwal } 3653fa5b8e0SAnuj Aggarwal 3663fa5b8e0SAnuj Aggarwal static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) 3673fa5b8e0SAnuj Aggarwal { 3683fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 3693fa5b8e0SAnuj Aggarwal int data, ldo = rdev_get_id(dev); 3703fa5b8e0SAnuj Aggarwal u8 reg, mask; 3713fa5b8e0SAnuj Aggarwal 3723fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 3733fa5b8e0SAnuj Aggarwal return -EINVAL; 3743fa5b8e0SAnuj Aggarwal else { 3753fa5b8e0SAnuj Aggarwal reg = (ldo == TPS6507X_LDO_1 ? 3763fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); 3773fa5b8e0SAnuj Aggarwal mask = (ldo == TPS6507X_LDO_1 ? 3783fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1_LDO1_MASK : 3793fa5b8e0SAnuj Aggarwal TPS6507X_REG_DEFLDO2_LDO2_MASK); 3803fa5b8e0SAnuj Aggarwal } 3813fa5b8e0SAnuj Aggarwal 3823fa5b8e0SAnuj Aggarwal data = tps_6507x_reg_read(tps, reg); 3833fa5b8e0SAnuj Aggarwal if (data < 0) 3843fa5b8e0SAnuj Aggarwal return data; 3853fa5b8e0SAnuj Aggarwal 3863fa5b8e0SAnuj Aggarwal data &= mask; 3873fa5b8e0SAnuj Aggarwal return tps->info[ldo]->table[data] * 1000; 3883fa5b8e0SAnuj Aggarwal } 3893fa5b8e0SAnuj Aggarwal 3903fa5b8e0SAnuj Aggarwal static int tps6507x_ldo_set_voltage(struct regulator_dev *dev, 3913fa5b8e0SAnuj Aggarwal int min_uV, int max_uV) 3923fa5b8e0SAnuj Aggarwal { 3933fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 3943fa5b8e0SAnuj Aggarwal int data, vsel, ldo = rdev_get_id(dev); 3953fa5b8e0SAnuj Aggarwal u8 reg, mask; 3963fa5b8e0SAnuj Aggarwal 3973fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 3983fa5b8e0SAnuj Aggarwal return -EINVAL; 3993fa5b8e0SAnuj Aggarwal else { 4003fa5b8e0SAnuj Aggarwal reg = (ldo == TPS6507X_LDO_1 ? 4013fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); 4023fa5b8e0SAnuj Aggarwal mask = (ldo == TPS6507X_LDO_1 ? 4033fa5b8e0SAnuj Aggarwal TPS6507X_REG_LDO_CTRL1_LDO1_MASK : 4043fa5b8e0SAnuj Aggarwal TPS6507X_REG_DEFLDO2_LDO2_MASK); 4053fa5b8e0SAnuj Aggarwal } 4063fa5b8e0SAnuj Aggarwal 4073fa5b8e0SAnuj Aggarwal if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV) 4083fa5b8e0SAnuj Aggarwal return -EINVAL; 4093fa5b8e0SAnuj Aggarwal if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV) 4103fa5b8e0SAnuj Aggarwal return -EINVAL; 4113fa5b8e0SAnuj Aggarwal 4123fa5b8e0SAnuj Aggarwal for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) { 4133fa5b8e0SAnuj Aggarwal int mV = tps->info[ldo]->table[vsel]; 4143fa5b8e0SAnuj Aggarwal int uV = mV * 1000; 4153fa5b8e0SAnuj Aggarwal 4163fa5b8e0SAnuj Aggarwal /* Break at the first in-range value */ 4173fa5b8e0SAnuj Aggarwal if (min_uV <= uV && uV <= max_uV) 4183fa5b8e0SAnuj Aggarwal break; 4193fa5b8e0SAnuj Aggarwal } 4203fa5b8e0SAnuj Aggarwal 4213fa5b8e0SAnuj Aggarwal if (vsel == tps->info[ldo]->table_len) 4223fa5b8e0SAnuj Aggarwal return -EINVAL; 4233fa5b8e0SAnuj Aggarwal 4243fa5b8e0SAnuj Aggarwal data = tps_6507x_reg_read(tps, reg); 4253fa5b8e0SAnuj Aggarwal if (data < 0) 4263fa5b8e0SAnuj Aggarwal return data; 4273fa5b8e0SAnuj Aggarwal 4283fa5b8e0SAnuj Aggarwal data &= ~mask; 4293fa5b8e0SAnuj Aggarwal data |= vsel; 4303fa5b8e0SAnuj Aggarwal 4313fa5b8e0SAnuj Aggarwal return tps_6507x_reg_write(tps, reg, data); 4323fa5b8e0SAnuj Aggarwal } 4333fa5b8e0SAnuj Aggarwal 4343fa5b8e0SAnuj Aggarwal static int tps6507x_dcdc_list_voltage(struct regulator_dev *dev, 4353fa5b8e0SAnuj Aggarwal unsigned selector) 4363fa5b8e0SAnuj Aggarwal { 4373fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 4383fa5b8e0SAnuj Aggarwal int dcdc = rdev_get_id(dev); 4393fa5b8e0SAnuj Aggarwal 4403fa5b8e0SAnuj Aggarwal if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 4413fa5b8e0SAnuj Aggarwal return -EINVAL; 4423fa5b8e0SAnuj Aggarwal 4433fa5b8e0SAnuj Aggarwal if (selector >= tps->info[dcdc]->table_len) 4443fa5b8e0SAnuj Aggarwal return -EINVAL; 4453fa5b8e0SAnuj Aggarwal else 4463fa5b8e0SAnuj Aggarwal return tps->info[dcdc]->table[selector] * 1000; 4473fa5b8e0SAnuj Aggarwal } 4483fa5b8e0SAnuj Aggarwal 4493fa5b8e0SAnuj Aggarwal static int tps6507x_ldo_list_voltage(struct regulator_dev *dev, 4503fa5b8e0SAnuj Aggarwal unsigned selector) 4513fa5b8e0SAnuj Aggarwal { 4523fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = rdev_get_drvdata(dev); 4533fa5b8e0SAnuj Aggarwal int ldo = rdev_get_id(dev); 4543fa5b8e0SAnuj Aggarwal 4553fa5b8e0SAnuj Aggarwal if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 4563fa5b8e0SAnuj Aggarwal return -EINVAL; 4573fa5b8e0SAnuj Aggarwal 4583fa5b8e0SAnuj Aggarwal if (selector >= tps->info[ldo]->table_len) 4593fa5b8e0SAnuj Aggarwal return -EINVAL; 4603fa5b8e0SAnuj Aggarwal else 4613fa5b8e0SAnuj Aggarwal return tps->info[ldo]->table[selector] * 1000; 4623fa5b8e0SAnuj Aggarwal } 4633fa5b8e0SAnuj Aggarwal 4643fa5b8e0SAnuj Aggarwal /* Operations permitted on VDCDCx */ 4653fa5b8e0SAnuj Aggarwal static struct regulator_ops tps6507x_dcdc_ops = { 4663fa5b8e0SAnuj Aggarwal .is_enabled = tps6507x_dcdc_is_enabled, 4673fa5b8e0SAnuj Aggarwal .enable = tps6507x_dcdc_enable, 4683fa5b8e0SAnuj Aggarwal .disable = tps6507x_dcdc_disable, 4693fa5b8e0SAnuj Aggarwal .get_voltage = tps6507x_dcdc_get_voltage, 4703fa5b8e0SAnuj Aggarwal .set_voltage = tps6507x_dcdc_set_voltage, 4713fa5b8e0SAnuj Aggarwal .list_voltage = tps6507x_dcdc_list_voltage, 4723fa5b8e0SAnuj Aggarwal }; 4733fa5b8e0SAnuj Aggarwal 4743fa5b8e0SAnuj Aggarwal /* Operations permitted on LDOx */ 4753fa5b8e0SAnuj Aggarwal static struct regulator_ops tps6507x_ldo_ops = { 4763fa5b8e0SAnuj Aggarwal .is_enabled = tps6507x_ldo_is_enabled, 4773fa5b8e0SAnuj Aggarwal .enable = tps6507x_ldo_enable, 4783fa5b8e0SAnuj Aggarwal .disable = tps6507x_ldo_disable, 4793fa5b8e0SAnuj Aggarwal .get_voltage = tps6507x_ldo_get_voltage, 4803fa5b8e0SAnuj Aggarwal .set_voltage = tps6507x_ldo_set_voltage, 4813fa5b8e0SAnuj Aggarwal .list_voltage = tps6507x_ldo_list_voltage, 4823fa5b8e0SAnuj Aggarwal }; 4833fa5b8e0SAnuj Aggarwal 48456c23492SDmitry Torokhov static int __devinit tps_6507x_probe(struct i2c_client *client, 48556c23492SDmitry Torokhov const struct i2c_device_id *id) 4863fa5b8e0SAnuj Aggarwal { 4873fa5b8e0SAnuj Aggarwal static int desc_id; 4883fa5b8e0SAnuj Aggarwal const struct tps_info *info = (void *)id->driver_data; 4893fa5b8e0SAnuj Aggarwal struct regulator_init_data *init_data; 4903fa5b8e0SAnuj Aggarwal struct regulator_dev *rdev; 4913fa5b8e0SAnuj Aggarwal struct tps_pmic *tps; 492*0bc20bbaSTodd Fischer struct tps6507x_board *tps_board; 4933fa5b8e0SAnuj Aggarwal int i; 49456c23492SDmitry Torokhov int error; 4953fa5b8e0SAnuj Aggarwal 4963fa5b8e0SAnuj Aggarwal if (!i2c_check_functionality(client->adapter, 4973fa5b8e0SAnuj Aggarwal I2C_FUNC_SMBUS_BYTE_DATA)) 4983fa5b8e0SAnuj Aggarwal return -EIO; 4993fa5b8e0SAnuj Aggarwal 5003fa5b8e0SAnuj Aggarwal /** 501*0bc20bbaSTodd Fischer * tps_board points to pmic related constants 502*0bc20bbaSTodd Fischer * coming from the board-evm file. 503*0bc20bbaSTodd Fischer */ 504*0bc20bbaSTodd Fischer 505*0bc20bbaSTodd Fischer tps_board = dev_get_platdata(&client->dev); 506*0bc20bbaSTodd Fischer if (!tps_board) 507*0bc20bbaSTodd Fischer return -EINVAL; 508*0bc20bbaSTodd Fischer 509*0bc20bbaSTodd Fischer /** 5103fa5b8e0SAnuj Aggarwal * init_data points to array of regulator_init structures 5113fa5b8e0SAnuj Aggarwal * coming from the board-evm file. 5123fa5b8e0SAnuj Aggarwal */ 513*0bc20bbaSTodd Fischer init_data = tps_board->tps6507x_pmic_init_data; 5143fa5b8e0SAnuj Aggarwal if (!init_data) 515*0bc20bbaSTodd Fischer return -EINVAL; 5163fa5b8e0SAnuj Aggarwal 5173fa5b8e0SAnuj Aggarwal tps = kzalloc(sizeof(*tps), GFP_KERNEL); 5183fa5b8e0SAnuj Aggarwal if (!tps) 5193fa5b8e0SAnuj Aggarwal return -ENOMEM; 5203fa5b8e0SAnuj Aggarwal 5213fa5b8e0SAnuj Aggarwal mutex_init(&tps->io_lock); 5223fa5b8e0SAnuj Aggarwal 5233fa5b8e0SAnuj Aggarwal /* common for all regulators */ 5243fa5b8e0SAnuj Aggarwal tps->client = client; 5253fa5b8e0SAnuj Aggarwal 5263fa5b8e0SAnuj Aggarwal for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { 5273fa5b8e0SAnuj Aggarwal /* Register the regulators */ 5283fa5b8e0SAnuj Aggarwal tps->info[i] = info; 5293fa5b8e0SAnuj Aggarwal tps->desc[i].name = info->name; 5303fa5b8e0SAnuj Aggarwal tps->desc[i].id = desc_id++; 5313fa5b8e0SAnuj Aggarwal tps->desc[i].n_voltages = num_voltages[i]; 5323fa5b8e0SAnuj Aggarwal tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? 5333fa5b8e0SAnuj Aggarwal &tps6507x_ldo_ops : &tps6507x_dcdc_ops); 5343fa5b8e0SAnuj Aggarwal tps->desc[i].type = REGULATOR_VOLTAGE; 5353fa5b8e0SAnuj Aggarwal tps->desc[i].owner = THIS_MODULE; 5363fa5b8e0SAnuj Aggarwal 5373fa5b8e0SAnuj Aggarwal rdev = regulator_register(&tps->desc[i], 5383fa5b8e0SAnuj Aggarwal &client->dev, init_data, tps); 5393fa5b8e0SAnuj Aggarwal if (IS_ERR(rdev)) { 5403fa5b8e0SAnuj Aggarwal dev_err(&client->dev, "failed to register %s\n", 5413fa5b8e0SAnuj Aggarwal id->name); 54256c23492SDmitry Torokhov error = PTR_ERR(rdev); 54356c23492SDmitry Torokhov goto fail; 5443fa5b8e0SAnuj Aggarwal } 5453fa5b8e0SAnuj Aggarwal 5463fa5b8e0SAnuj Aggarwal /* Save regulator for cleanup */ 5473fa5b8e0SAnuj Aggarwal tps->rdev[i] = rdev; 5483fa5b8e0SAnuj Aggarwal } 5493fa5b8e0SAnuj Aggarwal 5503fa5b8e0SAnuj Aggarwal i2c_set_clientdata(client, tps); 5513fa5b8e0SAnuj Aggarwal 5523fa5b8e0SAnuj Aggarwal return 0; 55356c23492SDmitry Torokhov 55456c23492SDmitry Torokhov fail: 55556c23492SDmitry Torokhov while (--i >= 0) 55656c23492SDmitry Torokhov regulator_unregister(tps->rdev[i]); 55756c23492SDmitry Torokhov 55856c23492SDmitry Torokhov kfree(tps); 55956c23492SDmitry Torokhov return error; 5603fa5b8e0SAnuj Aggarwal } 5613fa5b8e0SAnuj Aggarwal 5623fa5b8e0SAnuj Aggarwal /** 5633fa5b8e0SAnuj Aggarwal * tps_6507x_remove - TPS6507x driver i2c remove handler 5643fa5b8e0SAnuj Aggarwal * @client: i2c driver client device structure 5653fa5b8e0SAnuj Aggarwal * 5663fa5b8e0SAnuj Aggarwal * Unregister TPS driver as an i2c client device driver 5673fa5b8e0SAnuj Aggarwal */ 5683fa5b8e0SAnuj Aggarwal static int __devexit tps_6507x_remove(struct i2c_client *client) 5693fa5b8e0SAnuj Aggarwal { 5703fa5b8e0SAnuj Aggarwal struct tps_pmic *tps = i2c_get_clientdata(client); 5713fa5b8e0SAnuj Aggarwal int i; 5723fa5b8e0SAnuj Aggarwal 57356c23492SDmitry Torokhov /* clear the client data in i2c */ 57456c23492SDmitry Torokhov i2c_set_clientdata(client, NULL); 57556c23492SDmitry Torokhov 5763fa5b8e0SAnuj Aggarwal for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) 5773fa5b8e0SAnuj Aggarwal regulator_unregister(tps->rdev[i]); 5783fa5b8e0SAnuj Aggarwal 5793fa5b8e0SAnuj Aggarwal kfree(tps); 5803fa5b8e0SAnuj Aggarwal 5813fa5b8e0SAnuj Aggarwal return 0; 5823fa5b8e0SAnuj Aggarwal } 5833fa5b8e0SAnuj Aggarwal 5843fa5b8e0SAnuj Aggarwal static const struct tps_info tps6507x_regs[] = { 5853fa5b8e0SAnuj Aggarwal { 5863fa5b8e0SAnuj Aggarwal .name = "VDCDC1", 5873fa5b8e0SAnuj Aggarwal .min_uV = 725000, 5883fa5b8e0SAnuj Aggarwal .max_uV = 3300000, 5893fa5b8e0SAnuj Aggarwal .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), 5903fa5b8e0SAnuj Aggarwal .table = VDCDCx_VSEL_table, 5913fa5b8e0SAnuj Aggarwal }, 5923fa5b8e0SAnuj Aggarwal { 5933fa5b8e0SAnuj Aggarwal .name = "VDCDC2", 5943fa5b8e0SAnuj Aggarwal .min_uV = 725000, 5953fa5b8e0SAnuj Aggarwal .max_uV = 3300000, 5963fa5b8e0SAnuj Aggarwal .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), 5973fa5b8e0SAnuj Aggarwal .table = VDCDCx_VSEL_table, 5983fa5b8e0SAnuj Aggarwal }, 5993fa5b8e0SAnuj Aggarwal { 6003fa5b8e0SAnuj Aggarwal .name = "VDCDC3", 6013fa5b8e0SAnuj Aggarwal .min_uV = 725000, 6023fa5b8e0SAnuj Aggarwal .max_uV = 3300000, 6033fa5b8e0SAnuj Aggarwal .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), 6043fa5b8e0SAnuj Aggarwal .table = VDCDCx_VSEL_table, 6053fa5b8e0SAnuj Aggarwal }, 6063fa5b8e0SAnuj Aggarwal { 6073fa5b8e0SAnuj Aggarwal .name = "LDO1", 6083fa5b8e0SAnuj Aggarwal .min_uV = 1000000, 6093fa5b8e0SAnuj Aggarwal .max_uV = 3300000, 6103fa5b8e0SAnuj Aggarwal .table_len = ARRAY_SIZE(LDO1_VSEL_table), 6113fa5b8e0SAnuj Aggarwal .table = LDO1_VSEL_table, 6123fa5b8e0SAnuj Aggarwal }, 6133fa5b8e0SAnuj Aggarwal { 6143fa5b8e0SAnuj Aggarwal .name = "LDO2", 6153fa5b8e0SAnuj Aggarwal .min_uV = 725000, 6163fa5b8e0SAnuj Aggarwal .max_uV = 3300000, 6173fa5b8e0SAnuj Aggarwal .table_len = ARRAY_SIZE(LDO2_VSEL_table), 6183fa5b8e0SAnuj Aggarwal .table = LDO2_VSEL_table, 6193fa5b8e0SAnuj Aggarwal }, 6203fa5b8e0SAnuj Aggarwal }; 6213fa5b8e0SAnuj Aggarwal 6229e108d33SLiam Girdwood static const struct i2c_device_id tps_6507x_id[] = { 6239e108d33SLiam Girdwood {.name = "tps6507x", 6249e108d33SLiam Girdwood .driver_data = (unsigned long) tps6507x_regs,}, 6259e108d33SLiam Girdwood { }, 6263fa5b8e0SAnuj Aggarwal }; 6273fa5b8e0SAnuj Aggarwal MODULE_DEVICE_TABLE(i2c, tps_6507x_id); 6283fa5b8e0SAnuj Aggarwal 6293fa5b8e0SAnuj Aggarwal static struct i2c_driver tps_6507x_i2c_driver = { 6303fa5b8e0SAnuj Aggarwal .driver = { 6313fa5b8e0SAnuj Aggarwal .name = "tps6507x", 6323fa5b8e0SAnuj Aggarwal .owner = THIS_MODULE, 6333fa5b8e0SAnuj Aggarwal }, 6343fa5b8e0SAnuj Aggarwal .probe = tps_6507x_probe, 6353fa5b8e0SAnuj Aggarwal .remove = __devexit_p(tps_6507x_remove), 6369e108d33SLiam Girdwood .id_table = tps_6507x_id, 6373fa5b8e0SAnuj Aggarwal }; 6383fa5b8e0SAnuj Aggarwal 6393fa5b8e0SAnuj Aggarwal /** 6403fa5b8e0SAnuj Aggarwal * tps_6507x_init 6413fa5b8e0SAnuj Aggarwal * 6423fa5b8e0SAnuj Aggarwal * Module init function 6433fa5b8e0SAnuj Aggarwal */ 6443fa5b8e0SAnuj Aggarwal static int __init tps_6507x_init(void) 6453fa5b8e0SAnuj Aggarwal { 6463fa5b8e0SAnuj Aggarwal return i2c_add_driver(&tps_6507x_i2c_driver); 6473fa5b8e0SAnuj Aggarwal } 6483fa5b8e0SAnuj Aggarwal subsys_initcall(tps_6507x_init); 6493fa5b8e0SAnuj Aggarwal 6503fa5b8e0SAnuj Aggarwal /** 6513fa5b8e0SAnuj Aggarwal * tps_6507x_cleanup 6523fa5b8e0SAnuj Aggarwal * 6533fa5b8e0SAnuj Aggarwal * Module exit function 6543fa5b8e0SAnuj Aggarwal */ 6553fa5b8e0SAnuj Aggarwal static void __exit tps_6507x_cleanup(void) 6563fa5b8e0SAnuj Aggarwal { 6573fa5b8e0SAnuj Aggarwal i2c_del_driver(&tps_6507x_i2c_driver); 6583fa5b8e0SAnuj Aggarwal } 6593fa5b8e0SAnuj Aggarwal module_exit(tps_6507x_cleanup); 6603fa5b8e0SAnuj Aggarwal 6613fa5b8e0SAnuj Aggarwal MODULE_AUTHOR("Texas Instruments"); 6623fa5b8e0SAnuj Aggarwal MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); 6633fa5b8e0SAnuj Aggarwal MODULE_LICENSE("GPL v2"); 664