diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2011-05-26 13:53:59 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:43:12 -0800 |
commit | e4ad5570cb075826e19fa1ca13251f8d72c4f7a3 (patch) | |
tree | 002c8394baf3dcbd22d5fdd0c36c83b09ca0cb2c /drivers/regulator/tps80031-regulator.c | |
parent | 926531b4a4fc2aaa0dfcfb63fb09ad4c0438f83b (diff) |
arm: mfd/regulator: Adding driver for tps80031
Adding core and regulator driver for the TI pmu device tps80031.
Following functionality is added:
- Basic core driver interface to access register.
- Regulator driver.
- gpio driver.
- interrupt support from pmu.
- clock 32 initialization.
bug 830904
bug 829658
Original-Change-Id: I41e732c0b5d0472209798552b5264038e5a97ee4
Reviewed-on: http://git-master/r/33109
Tested-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Thomas Cherry <tcherry@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Rebase-Id: R72919d00e28138767da61d673c9e805f74911341
Diffstat (limited to 'drivers/regulator/tps80031-regulator.c')
-rw-r--r-- | drivers/regulator/tps80031-regulator.c | 731 |
1 files changed, 731 insertions, 0 deletions
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c new file mode 100644 index 000000000000..481a9d9668a6 --- /dev/null +++ b/drivers/regulator/tps80031-regulator.c @@ -0,0 +1,731 @@ +/* + * driver/regulator/tps80031-regulator.c + * + * Regulator driver for TI TPS80031 + * + * Copyright (C) 2011 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/tps80031-regulator.h> +#include <linux/mfd/tps80031.h> + +#define TPS80031ID_VIO_BASE_ADD 0x47 +#define TPS80031ID_SMPS1_BASE_ADD 0x53 +#define TPS80031ID_SMPS2_BASE_ADD 0x59 +#define TPS80031ID_SMPS3_BASE_ADD 0x65 +#define TPS80031ID_SMPS4_BASE_ADD 0x41 +#define TPS80031ID_VANA_BASE_ADD 0x81 +#define TPS80031ID_VRTC_BASE_ADD 0xC3 +#define TPS80031ID_LDO1_BASE_ADD 0x9D +#define TPS80031ID_LDO2_BASE_ADD 0x85 +#define TPS80031ID_LDO3_BASE_ADD 0x8D +#define TPS80031ID_LDO4_BASE_ADD 0x89 +#define TPS80031ID_LDO5_BASE_ADD 0x99 +#define TPS80031ID_LDO6_BASE_ADD 0x91 +#define TPS80031ID_LDO7_BASE_ADD 0xA5 +#define TPS80031ID_LDOLN_BASE_ADD 0x95 +#define TPS80031ID_LDOUSB_BASE_ADD 0xA1 + +#define VREG_GRP 0 + +/* Register offsets */ +#define VREG_TRANS 0 +#define VREG_STATE 1 +#define VREG_VOLTAGE 2 +#define VREG_VOLTAGE_DCDC 3 + +/* Flags for DCDC Voltage reading */ +#define DCDC_OFFSET_EN BIT(0) +#define DCDC_EXTENDED_EN BIT(1) + +#define SMPS_MULTOFFSET_VIO BIT(1) +#define SMPS_MULTOFFSET_SMPS1 BIT(3) +#define SMPS_MULTOFFSET_SMPS2 BIT(4) +#define SMPS_MULTOFFSET_SMPS3 BIT(6) +#define SMPS_MULTOFFSET_SMPS4 BIT(0) + +#define PMC_SMPS_OFFSET_ADD 0xE0 +#define PMC_SMPS_MULT_ADD 0xE3 + +#define STATE_OFF 0x00 +#define STATE_ON 0x01 +#define STATE_MASK 0x03 + +struct tps80031_regulator { + + /* start of regulator's PM_RECEIVER control register bank */ + u8 base; + + /* twl resource ID, for resource control state machine */ + u8 id; + + /* chip constraints on regulator behavior */ + u16 min_mV; + u16 max_mV; + + /* regulator specific turn-on delay */ + u16 delay; + + u8 flags; + + /* used by regulator core */ + struct regulator_desc desc; + + /* Device */ + struct device *dev; +}; + +static inline struct device *to_tps80031_dev(struct regulator_dev *rdev) +{ + return rdev_get_dev(rdev)->parent->parent; +} + +static int tps80031_regulator_enable_time(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + + return ri->delay; +} + +static u8 tps80031_get_smps_offset(struct device *parent) +{ + u8 value; + int ret; + + ret = tps80031_read(parent, PMC_SMPS_OFFSET_ADD, &value); + if (ret < 0) { + dev_err(parent, "Error in reading smps offset register\n"); + return 0; + } + return value; +} + +static u8 tps80031_get_smps_mult(struct device *parent) +{ + u8 value; + int ret; + + ret = tps80031_read(parent, PMC_SMPS_MULT_ADD, &value); + if (ret < 0) { + dev_err(parent, "Error in reading smps mult register\n"); + return 0; + } + return value; +} + +static int tps80031_reg_is_enabled(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + uint8_t state; + int ret; + + ret = tps80031_read(parent, ri->base + VREG_STATE, &state); + if (ret < 0) { + dev_err(&rdev->dev, "Error in reading the STATE register\n"); + return ret; + } + return ((state & STATE_MASK) == STATE_ON); +} + +static int tps80031_reg_enable(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + + ret = tps80031_update(parent, ri->base + VREG_STATE, STATE_ON, + STATE_MASK); + if (ret < 0) { + dev_err(&rdev->dev, "Error in updating the STATE register\n"); + return ret; + } + udelay(ri->delay); + return ret; +} + +static int tps80031_reg_disable(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + + ret = tps80031_update(parent, ri->base + VREG_STATE, STATE_OFF, + STATE_MASK); + if (ret < 0) + dev_err(&rdev->dev, "Error in updating the STATE register\n"); + + return ret; +} + +/* + * DCDC status and control + */ +static int tps80031dcdc_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + int voltage = 0; + + switch (ri->flags) { + case 0: + if (index == 0) + voltage = 0; + else if (index < 58) + voltage = (600000 + (12500 * (index - 1))); + else if (index == 58) + voltage = 1350 * 1000; + else if (index == 59) + voltage = 1500 * 1000; + else if (index == 60) + voltage = 1800 * 1000; + else if (index == 61) + voltage = 1900 * 1000; + else if (index == 62) + voltage = 2100 * 1000; + break; + + case DCDC_OFFSET_EN: + if (index == 0) + voltage = 0; + else if (index < 58) + voltage = (700000 + (12500 * (index - 1))); + else if (index == 58) + voltage = 1350 * 1000; + else if (index == 59) + voltage = 1500 * 1000; + else if (index == 60) + voltage = 1800 * 1000; + else if (index == 61) + voltage = 1900 * 1000; + else if (index == 62) + voltage = 2100 * 1000; + break; + + case DCDC_EXTENDED_EN: + if (index == 0) + voltage = 0; + else if (index < 58) + voltage = (1852000 + (38600 * (index - 1))); + else if (index == 58) + voltage = 2084 * 1000; + else if (index == 59) + voltage = 2315 * 1000; + else if (index == 60) + voltage = 2778 * 1000; + else if (index == 61) + voltage = 2932 * 1000; + else if (index == 62) + voltage = 3241 * 1000; + break; + + case DCDC_OFFSET_EN|DCDC_EXTENDED_EN: + if (index == 0) + voltage = 0; + else if (index < 58) + voltage = (2161000 + (38600 * (index - 1))); + else if (index == 58) + voltage = 4167 * 1000; + else if (index == 59) + voltage = 2315 * 1000; + else if (index == 60) + voltage = 2778 * 1000; + else if (index == 61) + voltage = 2932 * 1000; + else if (index == 62) + voltage = 3241 * 1000; + break; + } + + return voltage; +} + +static int __tps80031_dcdc_set_voltage(struct device *parent, + struct tps80031_regulator *ri, int min_uV, int max_uV) +{ + int vsel = 0; + int ret; + + switch (ri->flags) { + case 0: + if (min_uV == 0) + vsel = 0; + else if ((min_uV >= 600000) && (max_uV <= 1300000)) { + vsel = (min_uV - 600000) / 125; + if (vsel % 100) + vsel += 100; + vsel /= 100; + vsel++; + } else if ((min_uV > 1900000) && (max_uV >= 2100000)) + vsel = 62; + else if ((min_uV > 1800000) && (max_uV >= 1900000)) + vsel = 61; + else if ((min_uV > 1500000) && (max_uV >= 1800000)) + vsel = 60; + else if ((min_uV > 1350000) && (max_uV >= 1500000)) + vsel = 59; + else if ((min_uV > 1300000) && (max_uV >= 1350000)) + vsel = 58; + else + return -EINVAL; + break; + + case DCDC_OFFSET_EN: + if (min_uV == 0) + vsel = 0; + else if ((min_uV >= 700000) && (max_uV <= 1420000)) { + vsel = (min_uV - 600000) / 125; + if (vsel % 100) + vsel += 100; + vsel /= 100; + vsel++; + } else if ((min_uV > 1900000) && (max_uV >= 2100000)) + vsel = 62; + else if ((min_uV > 1800000) && (max_uV >= 1900000)) + vsel = 61; + else if ((min_uV > 1350000) && (max_uV >= 1800000)) + vsel = 60; + else if ((min_uV > 1350000) && (max_uV >= 1500000)) + vsel = 59; + else if ((min_uV > 1300000) && (max_uV >= 1350000)) + vsel = 58; + else + return -EINVAL; + break; + + case DCDC_EXTENDED_EN: + if (min_uV == 0) + vsel = 0; + else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { + vsel = (min_uV - 1852000) / 386; + if (vsel % 100) + vsel += 100; + vsel /= 100; + vsel++; + } + break; + + case DCDC_OFFSET_EN|DCDC_EXTENDED_EN: + if (min_uV == 0) + vsel = 0; + else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { + vsel = (min_uV - 1852000) / 386; + if (vsel % 100) + vsel += 100; + vsel /= 100; + vsel++; + } + break; + } + + ret = tps80031_write(parent, ri->base + VREG_VOLTAGE_DCDC, vsel); + if (ret < 0) + dev_err(ri->dev, "Error in updating the Voltage register\n"); + return ret; +} + +static int tps80031dcdc_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + return __tps80031_dcdc_set_voltage(parent, ri, min_uV, max_uV); +} + +static int tps80031dcdc_get_voltage(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + uint8_t vsel = 0; + int ret; + int voltage = 0; + + ret = tps80031_read(parent, ri->base + VREG_VOLTAGE_DCDC, &vsel); + if (ret < 0) { + dev_err(&rdev->dev, "Error in reading the Voltage register\n"); + return ret; + } + + switch (ri->flags) { + case 0: + if (vsel == 0) + voltage = 0; + else if (vsel < 58) + voltage = (600000 + (12500 * (vsel - 1))); + else if (vsel == 58) + voltage = 1350 * 1000; + else if (vsel == 59) + voltage = 1500 * 1000; + else if (vsel == 60) + voltage = 1800 * 1000; + else if (vsel == 61) + voltage = 1900 * 1000; + else if (vsel == 62) + voltage = 2100 * 1000; + break; + + case DCDC_OFFSET_EN: + if (vsel == 0) + voltage = 0; + else if (vsel < 58) + voltage = (700000 + (12500 * (vsel - 1))); + else if (vsel == 58) + voltage = 1350 * 1000; + else if (vsel == 59) + voltage = 1500 * 1000; + else if (vsel == 60) + voltage = 1800 * 1000; + else if (vsel == 61) + voltage = 1900 * 1000; + else if (vsel == 62) + voltage = 2100 * 1000; + break; + + case DCDC_EXTENDED_EN: + if (vsel == 0) + voltage = 0; + else if (vsel < 58) + voltage = (1852000 + (38600 * (vsel - 1))); + else if (vsel == 58) + voltage = 2084 * 1000; + else if (vsel == 59) + voltage = 2315 * 1000; + else if (vsel == 60) + voltage = 2778 * 1000; + else if (vsel == 61) + voltage = 2932 * 1000; + else if (vsel == 62) + voltage = 3241 * 1000; + break; + + case DCDC_EXTENDED_EN|DCDC_OFFSET_EN: + if (vsel == 0) + voltage = 0; + else if (vsel < 58) + voltage = (2161000 + (38600 * (vsel - 1))); + else if (vsel == 58) + voltage = 4167 * 1000; + else if (vsel == 59) + voltage = 2315 * 1000; + else if (vsel == 60) + voltage = 2778 * 1000; + else if (vsel == 61) + voltage = 2932 * 1000; + else if (vsel == 62) + voltage = 3241 * 1000; + break; + } + + return voltage; +} + +static int tps80031ldo_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + + if (index == 0) + return 0; + + return (ri->min_mV + (index * 100)) * 1000; +} + +static int __tps80031_ldo_set_voltage(struct device *parent, + struct tps80031_regulator *ri, int min_uV, int max_uV) +{ + int vsel; + int ret; + + if ((min_uV/1000 < ri->min_mV) || (max_uV/1000 > ri->max_mV)) + return -EDOM; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + vsel = (min_uV/1000 - 1000)/100 + 1; + ret = tps80031_write(parent, ri->base + VREG_VOLTAGE, vsel); + if (ret < 0) + dev_err(ri->dev, "Error in writing the Voltage register\n"); + return ret; +} + +static int tps80031ldo_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + + return __tps80031_ldo_set_voltage(parent, ri, min_uV, max_uV); +} + +static int tps80031ldo_get_voltage(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + uint8_t vsel; + int ret; + + ret = tps80031_read(parent, ri->base + VREG_VOLTAGE, &vsel); + if (ret < 0) { + dev_err(&rdev->dev, "Error in reading the Voltage register\n"); + return ret; + } + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + return (1000 + (100 * (vsel - 1))) * 1000; +} + +static struct regulator_ops tps80031dcdc_ops = { + .list_voltage = tps80031dcdc_list_voltage, + .set_voltage = tps80031dcdc_set_voltage, + .get_voltage = tps80031dcdc_get_voltage, + .enable = tps80031_reg_enable, + .disable = tps80031_reg_disable, + .is_enabled = tps80031_reg_is_enabled, + .enable_time = tps80031_regulator_enable_time, +}; + +static struct regulator_ops tps80031ldo_ops = { + .list_voltage = tps80031ldo_list_voltage, + .set_voltage = tps80031ldo_set_voltage, + .get_voltage = tps80031ldo_get_voltage, + .enable = tps80031_reg_enable, + .disable = tps80031_reg_disable, + .is_enabled = tps80031_reg_is_enabled, + .enable_time = tps80031_regulator_enable_time, +}; + +#define TPS80031_REG(_id, min_mVolts, max_mVolts, _ops, _n_volt, _delay) \ +{ \ + .base = TPS80031ID_##_id##_BASE_ADD, \ + .id = TPS80031_ID_##_id, \ + .min_mV = min_mVolts, \ + .max_mV = max_mVolts, \ + .desc = { \ + .name = tps80031_rails(_id), \ + .id = TPS80031_ID_##_id, \ + .n_voltages = _n_volt, \ + .ops = &_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + }, \ + .delay = _delay, \ +} + +static struct tps80031_regulator tps80031_regulator[] = { + TPS80031_REG(VIO, 600, 2100, tps80031dcdc_ops, 63, 500), + TPS80031_REG(SMPS1, 600, 2100, tps80031dcdc_ops, 63, 500), + TPS80031_REG(SMPS2, 600, 2100, tps80031dcdc_ops, 63, 500), + TPS80031_REG(SMPS3, 600, 2100, tps80031dcdc_ops, 63, 500), + TPS80031_REG(SMPS4, 600, 2100, tps80031dcdc_ops, 63, 500), + + TPS80031_REG(LDO1, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDO2, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDO3, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDO4, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDO5, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDO6, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDO7, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDOUSB, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(LDOLN, 1100, 3300, tps80031ldo_ops, 24, 500), + TPS80031_REG(VANA, 1100, 3300, tps80031ldo_ops, 24, 500), +}; + + +static inline int tps80031_regulator_preinit(struct device *parent, + struct tps80031_regulator *ri, + struct tps80031_regulator_platform_data *tps80031_pdata) +{ + int ret; + + if (!tps80031_pdata->init_apply) + return 0; + + if (tps80031_pdata->init_uV >= 0) { + switch (ri->desc.id) { + case TPS80031_ID_VIO: + case TPS80031_ID_SMPS1: + case TPS80031_ID_SMPS2: + case TPS80031_ID_SMPS3: + case TPS80031_ID_SMPS4: + ret = __tps80031_dcdc_set_voltage(parent, ri, + tps80031_pdata->init_uV, + tps80031_pdata->init_uV); + break; + + case TPS80031_ID_LDO1: + case TPS80031_ID_LDO2: + case TPS80031_ID_LDO3: + case TPS80031_ID_LDO4: + case TPS80031_ID_LDO5: + case TPS80031_ID_LDO6: + case TPS80031_ID_LDO7: + case TPS80031_ID_LDOUSB: + case TPS80031_ID_LDOLN: + case TPS80031_ID_VANA: + ret = __tps80031_ldo_set_voltage(parent, ri, + tps80031_pdata->init_uV, + tps80031_pdata->init_uV); + break; + default: + ret = -EINVAL; + break; + } + + if (ret < 0) { + dev_err(ri->dev, "Not able to initialize voltage %d " + "for rail %d err %d\n", tps80031_pdata->init_uV, + ri->desc.id, ret); + return ret; + } + } + + if (tps80031_pdata->init_enable) + ret = tps80031_update(parent, ri->base + VREG_STATE, STATE_ON, + STATE_MASK); + else + ret = tps80031_update(parent, ri->base + VREG_STATE, STATE_OFF, + STATE_MASK); + if (ret < 0) + dev_err(ri->dev, "Not able to %s rail %d err %d\n", + (tps80031_pdata->init_enable) ? "enable" : "disable", + ri->desc.id, ret); + return ret; +} + +static inline struct tps80031_regulator *find_regulator_info(int id) +{ + struct tps80031_regulator *ri; + int i; + + for (i = 0; i < ARRAY_SIZE(tps80031_regulator); i++) { + ri = &tps80031_regulator[i]; + if (ri->desc.id == id) + return ri; + } + return NULL; +} +static void check_smps_mode_mult(struct device *parent, + struct tps80031_regulator *ri) +{ + int mult_offset; + switch (ri->desc.id) { + case TPS80031_ID_VIO: + mult_offset = SMPS_MULTOFFSET_VIO; + break; + case TPS80031_ID_SMPS1: + mult_offset = SMPS_MULTOFFSET_SMPS1; + break; + case TPS80031_ID_SMPS2: + mult_offset = SMPS_MULTOFFSET_SMPS2; + break; + case TPS80031_ID_SMPS3: + mult_offset = SMPS_MULTOFFSET_SMPS3; + break; + case TPS80031_ID_SMPS4: + mult_offset = SMPS_MULTOFFSET_SMPS4; + break; + default: + return; + } + + ri->flags = (tps80031_get_smps_offset(parent) & mult_offset) ? + DCDC_OFFSET_EN : 0; + ri->flags |= (tps80031_get_smps_mult(parent) & mult_offset) ? + DCDC_EXTENDED_EN : 0; + return; +} + +static int __devinit tps80031_regulator_probe(struct platform_device *pdev) +{ + struct tps80031_regulator *ri = NULL; + struct regulator_dev *rdev; + struct tps80031_regulator_platform_data *tps_pdata; + int id = pdev->id; + int err; + + dev_dbg(&pdev->dev, "Probing reulator %d\n", id); + + ri = find_regulator_info(id); + if (ri == NULL) { + dev_err(&pdev->dev, "invalid regulator ID specified\n"); + return -EINVAL; + } + tps_pdata = pdev->dev.platform_data; + ri->dev = &pdev->dev; + + check_smps_mode_mult(pdev->dev.parent, ri); + + err = tps80031_regulator_preinit(pdev->dev.parent, ri, tps_pdata); + if (err) + return err; + + rdev = regulator_register(&ri->desc, &pdev->dev, + &tps_pdata->regulator, ri); + if (IS_ERR_OR_NULL(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + ri->desc.name); + return PTR_ERR(rdev); + } + + platform_set_drvdata(pdev, rdev); + + return 0; +} + +static int __devexit tps80031_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = platform_get_drvdata(pdev); + + regulator_unregister(rdev); + return 0; +} + +static struct platform_driver tps80031_regulator_driver = { + .driver = { + .name = "tps80031-regulator", + .owner = THIS_MODULE, + }, + .probe = tps80031_regulator_probe, + .remove = __devexit_p(tps80031_regulator_remove), +}; + +static int __init tps80031_regulator_init(void) +{ + return platform_driver_register(&tps80031_regulator_driver); +} +subsys_initcall(tps80031_regulator_init); + +static void __exit tps80031_regulator_exit(void) +{ + platform_driver_unregister(&tps80031_regulator_driver); +} +module_exit(tps80031_regulator_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Regulator Driver for TI TPS80031 PMIC"); +MODULE_ALIAS("platform:tps80031-regulator"); |