summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorDinh Nguyen <Dinh.Nguyen@freescale.com>2010-08-17 16:46:40 -0500
committerDinh Nguyen <Dinh.Nguyen@freescale.com>2010-09-01 10:42:59 -0500
commit3eb9039c5392abaabd96d08c0006ea4066346a60 (patch)
tree1b23d62933572db70a4aef7476a07e73f75e43d1 /drivers/regulator
parent4dcb1e4f577f7331930301798da548447208f35a (diff)
ENGR00126692-3: Upgrade kernel to 2.6.35
This patch contains changes to /drivers files Contains all checkpatch and copyright fixes. Acked-by: Rob Herring <r.herring@freescale.com> Signed-off-by: Dinh Nguyen <Dinh.Nguyen@freescale.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig25
-rw-r--r--drivers/regulator/Makefile10
-rw-r--r--drivers/regulator/core.c5
-rw-r--r--drivers/regulator/max17135-regulator.c736
-rw-r--r--drivers/regulator/mxs-regulator.c302
-rw-r--r--drivers/regulator/reg-mc13783.c2662
-rw-r--r--drivers/regulator/reg-mc13892.c1850
-rw-r--r--drivers/regulator/reg-mc34704.c289
-rw-r--r--drivers/regulator/reg-mc9s08dz60.c236
9 files changed, 6114 insertions, 1 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 04f2e085116a..90c47a684de4 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -201,5 +201,30 @@ config REGULATOR_88PM8607
help
This driver supports 88PM8607 voltage regulator chips.
+config REGULATOR_MC13892
+ tristate "MC13892 Regulator Support"
+ depends on MXC_PMIC_MC13892
+ default y
+
+config REGULATOR_MC34704
+ tristate "MC34704 Regulator Support"
+ depends on MXC_PMIC_MC34704
+ default y
+
+config REGULATOR_MXS
+ tristate "MXS Regulator Support"
+ depends on ARCH_MXS
+ default y
+
+config REGULATOR_MC9S08DZ60
+ tristate "mc9s08dz60 Regulator Support"
+ depends on MXC_PMIC_MC9S08DZ60
+ default y
+
+config REGULATOR_MAX17135
+ tristate "Maxim MAX17135 Regulator Support"
+ depends on REGULATOR
+ default n
+
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 4e7feece22d5..724460635476 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -2,7 +2,6 @@
# Makefile for regulator drivers.
#
-
obj-$(CONFIG_REGULATOR) += core.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
@@ -32,4 +31,13 @@ obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
+obj-$(CONFIG_REGULATOR_MAX17135) += max17135-regulator.o
+
+obj-$(CONFIG_REGULATOR_MC13892) += reg-mc13892.o
+obj-$(CONFIG_REGULATOR_MC34704) += reg-mc34704.o
+obj-$(CONFIG_REGULATOR_STMP3XXX) += stmp3xxx.o
+obj-$(CONFIG_REGULATOR_MXS) += mxs-regulator.o
+
+obj-$(CONFIG_REGULATOR_MC9S08DZ60) += reg-mc9s08dz60.o
+
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2248087b9be2..af6ebc027884 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1108,6 +1108,11 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
goto found;
}
}
+ list_for_each_entry(rdev, &regulator_list, list) {
+ if (strcmp(rdev->desc->name, id) == 0) {
+ goto found;
+ }
+ }
#ifdef CONFIG_REGULATOR_DUMMY
if (!devname)
diff --git a/drivers/regulator/max17135-regulator.c b/drivers/regulator/max17135-regulator.c
new file mode 100644
index 000000000000..3fdec795fbeb
--- /dev/null
+++ b/drivers/regulator/max17135-regulator.c
@@ -0,0 +1,736 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/max17135.h>
+#include <linux/gpio.h>
+
+/*
+ * Define this as 1 when using a Rev 1 MAX17135 part. These parts have
+ * some limitations, including an inability to turn on the PMIC via I2C.
+ */
+#define MAX17135_REV 1
+
+/*
+ * PMIC Register Addresses
+ */
+enum {
+ REG_MAX17135_EXT_TEMP = 0x0,
+ REG_MAX17135_CONFIG,
+ REG_MAX17135_INT_TEMP = 0x4,
+ REG_MAX17135_STATUS,
+ REG_MAX17135_PRODUCT_REV,
+ REG_MAX17135_PRODUCT_ID,
+ REG_MAX17135_DVR,
+ REG_MAX17135_ENABLE,
+ REG_MAX17135_FAULT, /*0x0A*/
+ REG_MAX17135_HVINP,
+ REG_MAX17135_PRGM_CTRL,
+ REG_MAX17135_TIMING1 = 0x10, /* Timing regs base address is 0x10 */
+ REG_MAX17135_TIMING2,
+ REG_MAX17135_TIMING3,
+ REG_MAX17135_TIMING4,
+ REG_MAX17135_TIMING5,
+ REG_MAX17135_TIMING6,
+ REG_MAX17135_TIMING7,
+ REG_MAX17135_TIMING8,
+};
+#define MAX17135_REG_NUM 21
+#define MAX17135_MAX_REGISTER 0xFF
+
+/*
+ * Bitfield macros that use rely on bitfield width/shift information.
+ */
+#define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH))
+#define BITFVAL(field, val) ((val) << (field ## _LSH))
+#define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH))
+
+/*
+ * Shift and width values for each register bitfield
+ */
+#define EXT_TEMP_LSH 7
+#define EXT_TEMP_WID 9
+
+#define THERMAL_SHUTDOWN_LSH 0
+#define THERMAL_SHUTDOWN_WID 1
+
+#define INT_TEMP_LSH 7
+#define INT_TEMP_WID 9
+
+#define STAT_BUSY_LSH 0
+#define STAT_BUSY_WID 1
+#define STAT_OPEN_LSH 1
+#define STAT_OPEN_WID 1
+#define STAT_SHRT_LSH 2
+#define STAT_SHRT_WID 1
+
+#define PROD_REV_LSH 0
+#define PROD_REV_WID 8
+
+#define PROD_ID_LSH 0
+#define PROD_ID_WID 8
+
+#define DVR_LSH 0
+#define DVR_WID 8
+
+#define ENABLE_LSH 0
+#define ENABLE_WID 1
+#define VCOM_ENABLE_LSH 1
+#define VCOM_ENABLE_WID 1
+
+#define FAULT_FBPG_LSH 0
+#define FAULT_FBPG_WID 1
+#define FAULT_HVINP_LSH 1
+#define FAULT_HVINP_WID 1
+#define FAULT_HVINN_LSH 2
+#define FAULT_HVINN_WID 1
+#define FAULT_FBNG_LSH 3
+#define FAULT_FBNG_WID 1
+#define FAULT_HVINPSC_LSH 4
+#define FAULT_HVINPSC_WID 1
+#define FAULT_HVINNSC_LSH 5
+#define FAULT_HVINNSC_WID 1
+#define FAULT_OT_LSH 6
+#define FAULT_OT_WID 1
+#define FAULT_POK_LSH 7
+#define FAULT_POK_WID 1
+
+#define HVINP_LSH 0
+#define HVINP_WID 4
+
+#define CTRL_DVR_LSH 0
+#define CTRL_DVR_WID 1
+#define CTRL_TIMING_LSH 1
+#define CTRL_TIMING_WID 1
+
+#define TIMING1_LSH 0
+#define TIMING1_WID 8
+#define TIMING2_LSH 0
+#define TIMING2_WID 8
+#define TIMING3_LSH 0
+#define TIMING3_WID 8
+#define TIMING4_LSH 0
+#define TIMING4_WID 8
+#define TIMING5_LSH 0
+#define TIMING5_WID 8
+#define TIMING6_LSH 0
+#define TIMING6_WID 8
+#define TIMING7_LSH 0
+#define TIMING7_WID 8
+#define TIMING8_LSH 0
+#define TIMING8_WID 8
+
+/*
+ * Regulator definitions
+ * *_MIN_uV - minimum microvolt for regulator
+ * *_MAX_uV - maximum microvolt for regulator
+ * *_STEP_uV - microvolts between regulator output levels
+ * *_MIN_VAL - minimum register field value for regulator
+ * *_MAX_VAL - maximum register field value for regulator
+ */
+#define MAX17135_HVINP_MIN_uV 5000000
+#define MAX17135_HVINP_MAX_uV 20000000
+#define MAX17135_HVINP_STEP_uV 1000000
+#define MAX17135_HVINP_MIN_VAL 0
+#define MAX17135_HVINP_MAX_VAL 1
+
+#define MAX17135_HVINN_MIN_uV 5000000
+#define MAX17135_HVINN_MAX_uV 20000000
+#define MAX17135_HVINN_STEP_uV 1000000
+#define MAX17135_HVINN_MIN_VAL 0
+#define MAX17135_HVINN_MAX_VAL 1
+
+#define MAX17135_GVDD_MIN_uV 5000000
+#define MAX17135_GVDD_MAX_uV 20000000
+#define MAX17135_GVDD_STEP_uV 1000000
+#define MAX17135_GVDD_MIN_VAL 0
+#define MAX17135_GVDD_MAX_VAL 1
+
+#define MAX17135_GVEE_MIN_uV 5000000
+#define MAX17135_GVEE_MAX_uV 20000000
+#define MAX17135_GVEE_STEP_uV 1000000
+#define MAX17135_GVEE_MIN_VAL 0
+#define MAX17135_GVEE_MAX_VAL 1
+
+#if (MAX17135_REV == 1)
+#define MAX17135_VCOM_MIN_uV -4325000
+#define MAX17135_VCOM_MAX_uV -500000
+#define MAX17135_VCOM_STEP_uV 15000
+#define MAX17135_VCOM_MIN_VAL 0
+#define MAX17135_VCOM_MAX_VAL 255
+/* Required due to discrepancy between
+ * observed VCOM programming and
+ * what is suggested in the spec.
+ */
+#define MAX17135_VCOM_FUDGE_FACTOR 330000
+#else
+#define MAX17135_VCOM_MIN_uV -3050000
+#define MAX17135_VCOM_MAX_uV -500000
+#define MAX17135_VCOM_STEP_uV 10000
+#define MAX17135_VCOM_MIN_VAL 0
+#define MAX17135_VCOM_MAX_VAL 255
+#define MAX17135_VCOM_FUDGE_FACTOR 330000
+#endif
+
+#define MAX17135_VCOM_VOLTAGE_DEFAULT -1250000
+
+#define MAX17135_VNEG_MIN_uV 5000000
+#define MAX17135_VNEG_MAX_uV 20000000
+#define MAX17135_VNEG_STEP_uV 1000000
+#define MAX17135_VNEG_MIN_VAL 0
+#define MAX17135_VNEG_MAX_VAL 1
+
+#define MAX17135_VPOS_MIN_uV 5000000
+#define MAX17135_VPOS_MAX_uV 20000000
+#define MAX17135_VPOS_STEP_uV 1000000
+#define MAX17135_VPOS_MIN_VAL 0
+#define MAX17135_VPOS_MAX_VAL 1
+
+struct max17135 {
+ /* chip revision */
+ int rev;
+
+ struct device *dev;
+
+ /* Platform connection */
+ struct i2c_client *i2c_client;
+
+ /* Client devices */
+ struct platform_device *pdev[MAX17135_REG_NUM];
+
+ /* GPIOs */
+ int gpio_pmic_pwrgood;
+ int gpio_pmic_vcom_ctrl;
+ int gpio_pmic_wakeup;
+ int gpio_pmic_intr;
+
+ bool vcom_setup;
+
+ int max_wait;
+};
+
+/*
+ * Regulator operations
+ */
+static int max17135_hvinp_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int reg_val;
+ unsigned int fld_val;
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ struct i2c_client *client = max17135->i2c_client;
+
+ if ((uV >= MAX17135_HVINP_MIN_uV) &&
+ (uV <= MAX17135_HVINP_MAX_uV))
+ fld_val = (uV - MAX17135_HVINP_MIN_uV) /
+ MAX17135_HVINP_STEP_uV;
+ else
+ return -EINVAL;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_HVINP);
+
+ reg_val &= ~BITFMASK(HVINP);
+ reg_val |= BITFVAL(HVINP, fld_val); /* shift to correct bit */
+
+ return i2c_smbus_write_byte_data(client, REG_MAX17135_HVINP, reg_val);
+}
+
+static int max17135_hvinp_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int reg_val;
+ unsigned int fld_val;
+ int volt;
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ struct i2c_client *client = max17135->i2c_client;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_HVINP);
+
+ fld_val = (reg_val & BITFMASK(HVINP)) >> HVINP_LSH;
+
+ if ((fld_val >= MAX17135_HVINP_MIN_VAL) &&
+ (fld_val <= MAX17135_HVINP_MAX_VAL)) {
+ volt = (fld_val * MAX17135_HVINP_STEP_uV) +
+ MAX17135_HVINP_MIN_uV;
+ } else {
+ printk(KERN_ERR "MAX17135: HVINP voltage is out of range\n");
+ volt = 0;
+ }
+ return volt;
+}
+
+static int max17135_hvinp_enable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int max17135_hvinp_disable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+/* Convert uV to the VCOM register bitfield setting */
+static inline int vcom_uV_to_rs(int uV)
+{
+ return (MAX17135_VCOM_MAX_uV - uV) / MAX17135_VCOM_STEP_uV;
+}
+
+/* Convert the VCOM register bitfield setting to uV */
+static inline int vcom_rs_to_uV(int rs)
+{
+ return MAX17135_VCOM_MAX_uV - (MAX17135_VCOM_STEP_uV * rs);
+}
+
+static int max17135_vcom_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ struct i2c_client *client = max17135->i2c_client;
+ unsigned int reg_val;
+ int vcom_read;
+
+ if ((uV < MAX17135_VCOM_MIN_uV) || (uV > MAX17135_VCOM_MAX_uV))
+ return -EINVAL;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_DVR);
+
+ /*
+ * Only program VCOM if it is not set to the desired value.
+ * Programming VCOM excessively degrades ability to keep
+ * DVR register value persistent.
+ */
+ vcom_read = vcom_rs_to_uV(reg_val) - MAX17135_VCOM_FUDGE_FACTOR;
+ if (vcom_read != MAX17135_VCOM_VOLTAGE_DEFAULT) {
+ reg_val &= ~BITFMASK(DVR);
+ reg_val |= BITFVAL(DVR,
+ vcom_uV_to_rs(uV + MAX17135_VCOM_FUDGE_FACTOR));
+ i2c_smbus_write_byte_data(client, REG_MAX17135_DVR, reg_val);
+
+ reg_val = BITFVAL(CTRL_DVR, true); /* shift to correct bit */
+ return i2c_smbus_write_byte_data(client,
+ REG_MAX17135_PRGM_CTRL, reg_val);
+ }
+}
+
+static int max17135_vcom_get_voltage(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ struct i2c_client *client = max17135->i2c_client;
+ unsigned int reg_val;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_DVR);
+ return vcom_rs_to_uV(BITFEXT(reg_val, DVR));
+}
+
+static int max17135_vcom_enable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+
+ /*
+ * Check to see if we need to set the VCOM voltage.
+ * Should only be done one time. And, we can
+ * only change vcom voltage if we have been enabled.
+ */
+ if (!max17135->vcom_setup
+ && gpio_get_value(max17135->gpio_pmic_pwrgood)) {
+ max17135_vcom_set_voltage(reg,
+ MAX17135_VCOM_VOLTAGE_DEFAULT,
+ MAX17135_VCOM_VOLTAGE_DEFAULT);
+ max17135->vcom_setup = true;
+ }
+
+ /* enable VCOM regulator output */
+#if (MAX17135_REV == 1)
+ gpio_set_value(max17135->gpio_pmic_vcom_ctrl, 1);
+#else
+ struct i2c_client *client = max17135->i2c_client;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_ENABLE);
+ reg_val &= ~BITFMASK(VCOM_ENABLE);
+ reg_val |= BITFVAL(VCOM_ENABLE, 1); /* shift to correct bit */
+ i2c_smbus_write_byte_data(client, REG_MAX17135_ENABLE, reg_val);
+#endif
+ return 0;
+}
+
+static int max17135_vcom_disable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+#if (MAX17135_REV == 1)
+ gpio_set_value(max17135->gpio_pmic_vcom_ctrl, 0);
+#else
+ struct i2c_client *client = max17135->i2c_client;
+ unsigned int reg_val;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_ENABLE);
+ reg_val &= ~BITFMASK(VCOM_ENABLE);
+ i2c_smbus_write_byte_data(client, REG_MAX17135_ENABLE, reg_val);
+#endif
+ return 0;
+}
+
+static int max17135_wait_power_good(struct max17135 *max17135)
+{
+ int i;
+
+ for (i = 0; i < max17135->max_wait * 3; i++) {
+ if (gpio_get_value(max17135->gpio_pmic_pwrgood))
+ return 0;
+
+ msleep(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int max17135_display_enable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+#if (MAX17135_REV == 1)
+ gpio_set_value(max17135->gpio_pmic_wakeup, 1);
+#else
+ struct i2c_client *client = max17135->i2c_client;
+ unsigned int reg_val;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_ENABLE);
+ reg_val &= ~BITFMASK(ENABLE);
+ reg_val |= BITFVAL(ENABLE, 1);
+ i2c_smbus_write_byte_data(client, REG_MAX17135_ENABLE, reg_val);
+#endif
+
+ return max17135_wait_power_good(max17135);
+}
+
+static int max17135_display_disable(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+#if (MAX17135_REV == 1)
+ gpio_set_value(max17135->gpio_pmic_wakeup, 0);
+#else
+ struct i2c_client *client = max17135->i2c_client;
+ unsigned int reg_val;
+
+ reg_val = i2c_smbus_read_byte_data(client, REG_MAX17135_ENABLE);
+ reg_val &= ~BITFMASK(ENABLE);
+ i2c_smbus_write_byte_data(client, REG_MAX17135_ENABLE, reg_val);
+ msleep(PMIC_DISABLE__V3P3_DESERT/1000);
+#endif
+ return 0;
+}
+
+static int max17135_display_is_enabled(struct regulator_dev *reg)
+{
+ struct max17135 *max17135 = rdev_get_drvdata(reg);
+ int gpio = gpio_get_value(max17135->gpio_pmic_wakeup);
+
+ if (gpio == 0)
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * Regulator operations
+ */
+
+static struct regulator_ops max17135_display_ops = {
+ .enable = max17135_display_enable,
+ .disable = max17135_display_disable,
+ .is_enabled = max17135_display_is_enabled,
+};
+
+static struct regulator_ops max17135_gvdd_ops = {
+};
+
+static struct regulator_ops max17135_gvee_ops = {
+};
+
+static struct regulator_ops max17135_hvinn_ops = {
+};
+
+static struct regulator_ops max17135_hvinp_ops = {
+ .enable = max17135_hvinp_enable,
+ .disable = max17135_hvinp_disable,
+ .get_voltage = max17135_hvinp_get_voltage,
+ .set_voltage = max17135_hvinp_set_voltage,
+};
+
+static struct regulator_ops max17135_vcom_ops = {
+ .enable = max17135_vcom_enable,
+ .disable = max17135_vcom_disable,
+ .get_voltage = max17135_vcom_get_voltage,
+ .set_voltage = max17135_vcom_set_voltage,
+};
+
+static struct regulator_ops max17135_vneg_ops = {
+};
+
+static struct regulator_ops max17135_vpos_ops = {
+};
+
+/*
+ * Regulator descriptors
+ */
+static struct regulator_desc max17135_reg[MAX17135_NUM_REGULATORS] = {
+{
+ .name = "DISPLAY",
+ .id = MAX17135_DISPLAY,
+ .ops = &max17135_display_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "GVDD",
+ .id = MAX17135_GVDD,
+ .ops = &max17135_gvdd_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "GVEE",
+ .id = MAX17135_GVEE,
+ .ops = &max17135_gvee_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "HVINN",
+ .id = MAX17135_HVINN,
+ .ops = &max17135_hvinn_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "HVINP",
+ .id = MAX17135_HVINP,
+ .ops = &max17135_hvinp_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VCOM",
+ .id = MAX17135_VCOM,
+ .ops = &max17135_vcom_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VNEG",
+ .id = MAX17135_VNEG,
+ .ops = &max17135_vneg_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+{
+ .name = "VPOS",
+ .id = MAX17135_VPOS,
+ .ops = &max17135_vpos_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+},
+};
+
+/*
+ * Regulator init/probing/exit functions
+ */
+static int max17135_regulator_probe(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev;
+
+ rdev = regulator_register(&max17135_reg[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
+ dev_get_drvdata(&pdev->dev));
+
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ max17135_reg[pdev->id].name);
+ return PTR_ERR(rdev);
+ }
+
+ return 0;
+}
+
+static int max17135_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+ regulator_unregister(rdev);
+ return 0;
+}
+
+static struct platform_driver max17135_regulator_driver = {
+ .probe = max17135_regulator_probe,
+ .remove = max17135_regulator_remove,
+ .driver = {
+ .name = "max17135-reg",
+ },
+};
+
+static int max17135_register_regulator(struct max17135 *max17135, int reg,
+ struct regulator_init_data *initdata)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ struct i2c_client *client = max17135->i2c_client;
+ /* If we can't find PMIC via I2C, we should not register regulators */
+ if (i2c_smbus_read_byte_data(client,
+ REG_MAX17135_PRODUCT_REV >= 0)) {
+ dev_err(max17135->dev,
+ "Max17135 PMIC not found!\n");
+ return -ENXIO;
+ }
+
+ if (max17135->pdev[reg])
+ return -EBUSY;
+
+ pdev = platform_device_alloc("max17135-reg", reg);
+ if (!pdev)
+ return -ENOMEM;
+
+ max17135->pdev[reg] = pdev;
+
+ initdata->driver_data = max17135;
+
+ pdev->dev.platform_data = initdata;
+ pdev->dev.parent = max17135->dev;
+ platform_set_drvdata(pdev, max17135);
+
+ ret = platform_device_add(pdev);
+
+ if (ret != 0) {
+ dev_err(max17135->dev,
+ "Failed to register regulator %d: %d\n",
+ reg, ret);
+ platform_device_del(pdev);
+ max17135->pdev[reg] = NULL;
+ }
+
+ return ret;
+}
+
+static int max17135_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int i;
+ struct max17135 *max17135;
+ struct max17135_platform_data *pdata = client->dev.platform_data;
+ int ret = 0;
+
+ if (!pdata || !pdata->regulator_init)
+ return -ENODEV;
+
+ /* Create the PMIC data structure */
+ max17135 = kzalloc(sizeof(struct max17135), GFP_KERNEL);
+ if (max17135 == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+
+ /* Initialize the PMIC data structure */
+ i2c_set_clientdata(client, max17135);
+ max17135->dev = &client->dev;
+ max17135->i2c_client = client;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ max17135->vcom_setup = false;
+
+ ret = platform_driver_register(&max17135_regulator_driver);
+ if (ret < 0)
+ goto err;
+
+ for (i = 0; i <= MAX17135_VPOS; i++) {
+ ret = max17135_register_regulator(max17135, i, &pdata->regulator_init[i]);
+ if (ret != 0) {
+ dev_err(max17135->dev, "Platform init() failed: %d\n",
+ ret);
+ goto err;
+ }
+ }
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ /* Initialize the PMIC device */
+ dev_info(&client->dev, "PMIC MAX17135 for eInk display\n");
+
+ return ret;
+err:
+ kfree(max17135);
+
+ return ret;
+}
+
+
+static int max17135_i2c_remove(struct i2c_client *i2c)
+{
+ struct max17135 *max17135 = i2c_get_clientdata(i2c);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(max17135->pdev); i++)
+ platform_device_unregister(max17135->pdev[i]);
+
+ platform_driver_unregister(&max17135_regulator_driver);
+
+ kfree(max17135);
+
+ return 0;
+}
+
+static const struct i2c_device_id max17135_i2c_id[] = {
+ { "max17135", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max17135_i2c_id);
+
+
+static struct i2c_driver max17135_i2c_driver = {
+ .driver = {
+ .name = "max17135",
+ .owner = THIS_MODULE,
+ },
+ .probe = max17135_i2c_probe,
+ .remove = max17135_i2c_remove,
+ .id_table = max17135_i2c_id,
+};
+
+static int __init max17135_init(void)
+{
+ return i2c_add_driver(&max17135_i2c_driver);
+}
+module_init(max17135_init);
+
+static void __exit max17135_exit(void)
+{
+ i2c_del_driver(&max17135_i2c_driver);
+}
+module_exit(max17135_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MAX17135 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/mxs-regulator.c b/drivers/regulator/mxs-regulator.c
new file mode 100644
index 000000000000..34930776a90c
--- /dev/null
+++ b/drivers/regulator/mxs-regulator.c
@@ -0,0 +1,302 @@
+/*
+ * Freescale STMP378X voltage regulators
+ *
+ * Embedded Alley Solutions, Inc <source@embeddedalley.com>
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <mach/power.h>
+#include <mach/regulator.h>
+
+static int mxs_set_voltage(struct regulator_dev *reg, int MiniV, int uv)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ if (mxs_reg->rdata->set_voltage)
+ return mxs_reg->rdata->set_voltage(mxs_reg, uv);
+ else
+ return -ENOTSUPP;
+}
+
+
+static int mxs_get_voltage(struct regulator_dev *reg)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ if (mxs_reg->rdata->get_voltage)
+ return mxs_reg->rdata->get_voltage(mxs_reg);
+ else
+ return -ENOTSUPP;
+}
+
+static int mxs_set_current(struct regulator_dev *reg, int min_uA, int uA)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ if (mxs_reg->rdata->set_current)
+ return mxs_reg->rdata->set_current(mxs_reg, uA);
+ else
+ return -ENOTSUPP;
+}
+
+static int mxs_get_current(struct regulator_dev *reg)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ if (mxs_reg->rdata->get_current)
+ return mxs_reg->rdata->get_current(mxs_reg);
+ else
+ return -ENOTSUPP;
+}
+
+static int mxs_enable(struct regulator_dev *reg)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ return mxs_reg->rdata->enable(mxs_reg);
+}
+
+static int mxs_disable(struct regulator_dev *reg)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ return mxs_reg->rdata->disable(mxs_reg);
+}
+
+static int mxs_is_enabled(struct regulator_dev *reg)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ return mxs_reg->rdata->is_enabled(mxs_reg);
+}
+
+static int mxs_set_mode(struct regulator_dev *reg, unsigned int mode)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ return mxs_reg->rdata->set_mode(mxs_reg, mode);
+}
+
+static unsigned int mxs_get_mode(struct regulator_dev *reg)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ return mxs_reg->rdata->get_mode(mxs_reg);
+}
+
+static unsigned int mxs_get_optimum_mode(struct regulator_dev *reg,
+ int input_uV, int output_uV, int load_uA)
+{
+ struct mxs_regulator *mxs_reg = rdev_get_drvdata(reg);
+
+ if (mxs_reg->rdata->get_optimum_mode)
+ return mxs_reg->rdata->get_optimum_mode(mxs_reg, input_uV,
+ output_uV, load_uA);
+ else
+ return -ENOTSUPP;
+}
+
+static struct regulator_ops mxs_rops = {
+ .set_voltage = mxs_set_voltage,
+ .get_voltage = mxs_get_voltage,
+ .set_current_limit = mxs_set_current,
+ .get_current_limit = mxs_get_current,
+ .enable = mxs_enable,
+ .disable = mxs_disable,
+ .is_enabled = mxs_is_enabled,
+ .set_mode = mxs_set_mode,
+ .get_mode = mxs_get_mode,
+ .get_optimum_mode = mxs_get_optimum_mode,
+};
+
+static struct regulator_desc mxs_reg_desc[] = {
+ {
+ .name = "vddd",
+ .id = MXS_VDDD,
+ .ops = &mxs_rops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "vdda",
+ .id = MXS_VDDA,
+ .ops = &mxs_rops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "vddio",
+ .id = MXS_VDDIO,
+ .ops = &mxs_rops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "vddd_bo",
+ .id = MXS_VDDDBO,
+ .ops = &mxs_rops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "overall_current",
+ .id = MXS_OVERALL_CUR,
+ .ops = &mxs_rops,
+ .irq = 0,
+ .type = REGULATOR_CURRENT,
+ .owner = THIS_MODULE
+ },
+};
+
+static int reg_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ unsigned long flags;
+ struct mxs_regulator *sreg =
+ container_of(self, struct mxs_regulator , nb);
+
+ switch (event) {
+ case MXS_REG5V_IS_USB:
+ spin_lock_irqsave(&sreg->lock, flags);
+ sreg->rdata->max_current = 500000;
+ spin_unlock_irqrestore(&sreg->lock, flags);
+ break;
+ case MXS_REG5V_NOT_USB:
+ spin_lock_irqsave(&sreg->lock, flags);
+ sreg->rdata->max_current = 0x7fffffff;
+ spin_unlock_irqrestore(&sreg->lock, flags);
+ break;
+ }
+
+ return 0;
+}
+
+int mxs_regulator_probe(struct platform_device *pdev)
+{
+ struct regulator_desc *rdesc;
+ struct regulator_dev *rdev;
+ struct mxs_regulator *sreg;
+ struct regulator_init_data *initdata;
+
+ sreg = platform_get_drvdata(pdev);
+ initdata = pdev->dev.platform_data;
+ sreg->cur_current = 0;
+ sreg->next_current = 0;
+ sreg->cur_voltage = 0;
+
+ init_waitqueue_head(&sreg->wait_q);
+ spin_lock_init(&sreg->lock);
+
+ if (pdev->id > MXS_OVERALL_CUR) {
+ rdesc = kzalloc(sizeof(struct regulator_desc), GFP_KERNEL);
+ memcpy(rdesc, &mxs_reg_desc[MXS_OVERALL_CUR],
+ sizeof(struct regulator_desc));
+ rdesc->name = kstrdup(sreg->rdata->name, GFP_KERNEL);
+ } else
+ rdesc = &mxs_reg_desc[pdev->id];
+
+ pr_debug("probing regulator %s %s %d\n",
+ sreg->rdata->name,
+ rdesc->name,
+ pdev->id);
+
+ /* register regulator */
+ rdev = regulator_register(rdesc, &pdev->dev,
+ initdata, sreg);
+
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ rdesc->name);
+ return PTR_ERR(rdev);
+ }
+
+ if (sreg->rdata->max_current) {
+ struct regulator *regu;
+ regu = regulator_get(NULL, sreg->rdata->name);
+ sreg->nb.notifier_call = reg_callback;
+ regulator_register_notifier(regu, &sreg->nb);
+ }
+
+ return 0;
+}
+
+
+int mxs_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+
+ return 0;
+
+}
+
+int mxs_register_regulator(
+ struct mxs_regulator *reg_data, int reg,
+ struct regulator_init_data *initdata)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = platform_device_alloc("mxs_reg", reg);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->dev.platform_data = initdata;
+
+ platform_set_drvdata(pdev, reg_data);
+ ret = platform_device_add(pdev);
+
+ if (ret != 0) {
+ pr_debug("Failed to register regulator %d: %d\n",
+ reg, ret);
+ platform_device_del(pdev);
+ }
+ pr_debug("register regulator %s, %d: %d\n",
+ reg_data->rdata->name, reg, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mxs_register_regulator);
+
+struct platform_driver mxs_reg = {
+ .driver = {
+ .name = "mxs_reg",
+ },
+ .probe = mxs_regulator_probe,
+ .remove = mxs_regulator_remove,
+};
+
+int mxs_regulator_init(void)
+{
+ return platform_driver_register(&mxs_reg);
+}
+
+void mxs_regulator_exit(void)
+{
+ platform_driver_unregister(&mxs_reg);
+}
+
+postcore_initcall(mxs_regulator_init);
+module_exit(mxs_regulator_exit);
diff --git a/drivers/regulator/reg-mc13783.c b/drivers/regulator/reg-mc13783.c
new file mode 100644
index 000000000000..da20907ba087
--- /dev/null
+++ b/drivers/regulator/reg-mc13783.c
@@ -0,0 +1,2662 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/mc13783/core.h>
+#include <linux/platform_device.h>
+#include <linux/pmic_status.h>
+#include <linux/pmic_external.h>
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+/*!
+ * @enum regulator_voltage_sw
+ * @brief PMIC regulator SW output voltage.
+ */
+enum {
+ SW_0_9V = 0, /*!< 0.900 V */
+ SW_0_925V, /*!< 0.925 V */
+ SW_0_95V, /*!< 0.950 V */
+ SW_0_975V, /*!< 0.975 V */
+ SW_1V, /*!< 1.000 V */
+ SW_1_025V, /*!< 1.025 V */
+ SW_1_05V, /*!< 1.050 V */
+ SW_1_075V, /*!< 1.075 V */
+ SW_1_1V, /*!< 1.100 V */
+ SW_1_125V, /*!< 1.125 V */
+ SW_1_15V, /*!< 1.150 V */
+ SW_1_175V, /*!< 1.175 V */
+ SW_1_2V, /*!< 1.200 V */
+ SW_1_225V, /*!< 1.225 V */
+ SW_1_25V, /*!< 1.250 V */
+ SW_1_275V, /*!< 1.275 V */
+ SW_1_3V, /*!< 1.300 V */
+ SW_1_325V, /*!< 1.325 V */
+ SW_1_35V, /*!< 1.350 V */
+ SW_1_375V, /*!< 1.375 V */
+ SW_1_4V, /*!< 1.400 V */
+ SW_1_425V, /*!< 1.425 V */
+ SW_1_45V, /*!< 1.450 V */
+ SW_1_475V, /*!< 1.475 V */
+ SW_1_5V, /*!< 1.500 V */
+ SW_1_525V, /*!< 1.525 V */
+ SW_1_55V, /*!< 1.550 V */
+ SW_1_575V, /*!< 1.575 V */
+ SW_1_6V, /*!< 1.600 V */
+ SW_1_625V, /*!< 1.625 V */
+ SW_1_65V, /*!< 1.650 V */
+ SW_1_675V, /*!< 1.675 V */
+ SW_1_7V, /*!< 1.700 V */
+ SW_1_8V = 36, /*!< 1.800 V */
+ SW_1_85V = 40, /*!< 1.850 V */
+ SW_2V = 44, /*!< 2_000 V */
+ SW_2_1V = 48, /*!< 2_100 V */
+ SW_2_2V = 52, /*!< 2_200 V */
+} regulator_voltage_sw;
+
+/*!
+ * @enum regulator_voltage_violo
+ * @brief PMIC regulator VIOLO output voltage.
+ */
+enum {
+ VIOLO_1_2V = 0, /*!< 1.2 V */
+ VIOLO_1_3V, /*!< 1.3 V */
+ VIOLO_1_5V, /*!< 1.5 V */
+ VIOLO_1_8V, /*!< 1.8 V */
+} regulator_voltage_violo;
+
+/*!
+ * @enum regulator_voltage_vdig
+ * @brief PMIC regulator VDIG output voltage.
+ */
+enum {
+ VDIG_1_2V = 0, /*!< 1.2 V */
+ VDIG_1_3V, /*!< 1.3 V */
+ VDIG_1_5V, /*!< 1.5 V */
+ VDIG_1_8V, /*!< 1.8 V */
+} regulator_voltage_vdig;
+
+/*!
+ * @enum regulator_voltage_vgen
+ * @brief PMIC regulator VGEN output voltage.
+ */
+enum {
+ VGEN_1_2V = 0, /*!< 1.2 V */
+ VGEN_1_3V, /*!< 1.3 V */
+ VGEN_1_5V, /*!< 1.5 V */
+ VGEN_1_8V, /*!< 1.8 V */
+ VGEN_1_1V, /*!< 1.1 V */
+ VGEN_2V, /*!< 2 V */
+ VGEN_2_775V, /*!< 2.775 V */
+ VGEN_2_4V, /*!< 2.4 V */
+} regulator_voltage_vgen;
+
+/*!
+ * @enum regulator_voltage_vrfdig
+ * @brief PMIC regulator VRFDIG output voltage.
+ */
+enum {
+ VRFDIG_1_2V = 0, /*!< 1.2 V */
+ VRFDIG_1_5V, /*!< 1.5 V */
+ VRFDIG_1_8V, /*!< 1.8 V */
+ VRFDIG_1_875V, /*!< 1.875 V */
+} regulator_voltage_vrfdig;
+
+/*!
+ * @enum regulator_voltage_vrfref
+ * @brief PMIC regulator VRFREF output voltage.
+ */
+enum {
+ VRFREF_2_475V = 0, /*!< 2.475 V */
+ VRFREF_2_6V, /*!< 2.600 V */
+ VRFREF_2_7V, /*!< 2.700 V */
+ VRFREF_2_775V, /*!< 2.775 V */
+} regulator_voltage_vrfref;
+
+/*!
+ * @enum regulator_voltage_vrfcp
+ * @brief PMIC regulator VRFCP output voltage.
+ */
+enum {
+ VRFCP_2_7V = 0, /*!< 2.700 V */
+ VRFCP_2_775V, /*!< 2.775 V */
+} regulator_voltage_vrfcp;
+
+/*!
+ * @enum regulator_voltage_vsim
+ * @brief PMIC linear regulator VSIM output voltage.
+ */
+enum {
+ VSIM_1_8V = 0, /*!< 1.8 V */
+ VSIM_2_9V, /*!< 2.90 V */
+ VSIM_3V = 1, /*!< 3 V */
+} regulator_voltage_vsim;
+
+/*!
+ * @enum regulator_voltage_vesim
+ * @brief PMIC regulator VESIM output voltage.
+ */
+enum {
+ VESIM_1_8V = 0, /*!< 1.80 V */
+ VESIM_2_9V, /*!< 2.90 V */
+} regulator_voltage_vesim;
+
+/*!
+ * @enum regulator_voltage_vcam
+ * @brief PMIC regulator VCAM output voltage.
+ */
+enum {
+ VCAM_1_5V = 0, /*!< 1.50 V */
+ VCAM_1_8V, /*!< 1.80 V */
+ VCAM_2_5V, /*!< 2.50 V */
+ VCAM_2_55V, /*!< 2.55 V */
+ VCAM_2_6V, /*!< 2.60 V */
+ VCAM_2_75V, /*!< 2.75 V */
+ VCAM_2_8V, /*!< 2.80 V */
+ VCAM_3V, /*!< 3.00 V */
+} regulator_voltage_vcam;
+
+/*!
+ * @enum regulator_voltage_vvib
+ * @brief PMIC linear regulator V_VIB output voltage.
+ */
+enum {
+ VVIB_1_3V = 0, /*!< 1.30 V */
+ VVIB_1_8V, /*!< 1.80 V */
+ VVIB_2V, /*!< 2 V */
+ VVIB_3V, /*!< 3 V */
+} regulator_voltage_vvib;
+
+/*!
+ * @enum regulator_voltage_vmmc
+ * @brief MC13783 PMIC regulator VMMC output voltage.
+ */
+enum {
+ VMMC_1_6V = 0, /*!< 1.60 V */
+ VMMC_1_8V, /*!< 1.80 V */
+ VMMC_2V, /*!< 2.00 V */
+ VMMC_2_6V, /*!< 2.60 V */
+ VMMC_2_7V, /*!< 2.70 V */
+ VMMC_2_8V, /*!< 2.80 V */
+ VMMC_2_9V, /*!< 2.90 V */
+ VMMC_3V, /*!< 3.00 V */
+} regulator_voltage_vmmc;
+
+/*!
+ * @enum regulator_voltage_vrf
+ * @brief PMIC regulator VRF output voltage.
+ */
+enum {
+ VRF_1_5V = 0, /*!< 1.500 V */
+ VRF_1_875V, /*!< 1.875 V */
+ VRF_2_7V, /*!< 2.700 V */
+ VRF_2_775V, /*!< 2.775 V */
+} regulator_voltage_vrf;
+
+/*!
+ * @enum regulator_voltage_sw3
+ * @brief PMIC Switch mode regulator SW3 output voltages.
+ */
+enum {
+ SW3_5V = 0, /*!< 5.0 V */
+ SW3_5_5V = 3, /*!< 5.5 V */
+} regulator_voltage_sw3;
+
+/*!
+ * The \b TPmicDVSTransitionSpeed enum defines the rate with which the
+ * voltage transition occurs.
+ */
+enum {
+ ESysDependent,
+ E25mVEach4us,
+ E25mVEach8us,
+ E25mvEach16us
+} DVS_transition_speed;
+
+/*
+ * Reg Regulator Mode 0
+ */
+#define VAUDIO_EN_LSH 0
+#define VAUDIO_EN_WID 1
+#define VAUDIO_EN_ENABLE 1
+#define VAUDIO_EN_DISABLE 0
+#define VIOHI_EN_LSH 3
+#define VIOHI_EN_WID 1
+#define VIOHI_EN_ENABLE 1
+#define VIOHI_EN_DISABLE 0
+#define VIOLO_EN_LSH 6
+#define VIOLO_EN_WID 1
+#define VIOLO_EN_ENABLE 1
+#define VIOLO_EN_DISABLE 0
+#define VDIG_EN_LSH 9
+#define VDIG_EN_WID 1
+#define VDIG_EN_ENABLE 1
+#define VDIG_EN_DISABLE 0
+#define VGEN_EN_LSH 12
+#define VGEN_EN_WID 1
+#define VGEN_EN_ENABLE 1
+#define VGEN_EN_DISABLE 0
+#define VRFDIG_EN_LSH 15
+#define VRFDIG_EN_WID 1
+#define VRFDIG_EN_ENABLE 1
+#define VRFDIG_EN_DISABLE 0
+#define VRFREF_EN_LSH 18
+#define VRFREF_EN_WID 1
+#define VRFREF_EN_ENABLE 1
+#define VRFREF_EN_DISABLE 0
+#define VRFCP_EN_LSH 21
+#define VRFCP_EN_WID 1
+#define VRFCP_EN_ENABLE 1
+#define VRFCP_EN_DISABLE 0
+
+/*
+ * Reg Regulator Mode 1
+ */
+#define VSIM_EN_LSH 0
+#define VSIM_EN_WID 1
+#define VSIM_EN_ENABLE 1
+#define VSIM_EN_DISABLE 0
+#define VESIM_EN_LSH 3
+#define VESIM_EN_WID 1
+#define VESIM_EN_ENABLE 1
+#define VESIM_EN_DISABLE 0
+#define VCAM_EN_LSH 6
+#define VCAM_EN_WID 1
+#define VCAM_EN_ENABLE 1
+#define VCAM_EN_DISABLE 0
+#define VRFBG_EN_LSH 9
+#define VRFBG_EN_WID 1
+#define VRFBG_EN_ENABLE 1
+#define VRFBG_EN_DISABLE 0
+#define VVIB_EN_LSH 11
+#define VVIB_EN_WID 1
+#define VVIB_EN_ENABLE 1
+#define VVIB_EN_DISABLE 0
+#define VRF1_EN_LSH 12
+#define VRF1_EN_WID 1
+#define VRF1_EN_ENABLE 1
+#define VRF1_EN_DISABLE 0
+#define VRF2_EN_LSH 15
+#define VRF2_EN_WID 1
+#define VRF2_EN_ENABLE 1
+#define VRF2_EN_DISABLE 0
+#define VMMC1_EN_LSH 18
+#define VMMC1_EN_WID 1
+#define VMMC1_EN_ENABLE 1
+#define VMMC1_EN_DISABLE 0
+#define VMMC2_EN_LSH 21
+#define VMMC2_EN_WID 1
+#define VMMC2_EN_ENABLE 1
+#define VMMC2_EN_DISABLE 0
+
+/*
+ * Reg Regulator Setting 0
+ */
+#define VIOLO_LSH 2
+#define VIOLO_WID 2
+#define VDIG_LSH 4
+#define VDIG_WID 2
+#define VGEN_LSH 6
+#define VGEN_WID 3
+#define VRFDIG_LSH 9
+#define VRFDIG_WID 2
+#define VRFREF_LSH 11
+#define VRFREF_WID 2
+#define VRFCP_LSH 13
+#define VRFCP_WID 1
+#define VSIM_LSH 14
+#define VSIM_WID 1
+#define VESIM_LSH 15
+#define VESIM_WID 1
+#define VCAM_LSH 16
+#define VCAM_WID 3
+
+/*
+ * Reg Regulator Setting 1
+ */
+#define VVIB_LSH 0
+#define VVIB_WID 2
+#define VRF1_LSH 2
+#define VRF1_WID 2
+#define VRF2_LSH 4
+#define VRF2_WID 2
+#define VMMC1_LSH 6
+#define VMMC1_WID 3
+#define VMMC2_LSH 9
+#define VMMC2_WID 3
+
+/*
+ * Reg Switcher 0
+ */
+#define SW1A_LSH 0
+#define SW1A_WID 6
+#define SW1A_DVS_LSH 6
+#define SW1A_DVS_WID 6
+#define SW1A_STDBY_LSH 12
+#define SW1A_STDBY_WID 6
+
+/*
+ * Reg Switcher 1
+ */
+#define SW1B_LSH 0
+#define SW1B_WID 6
+#define SW1B_DVS_LSH 6
+#define SW1B_DVS_WID 6
+#define SW1B_STDBY_LSH 12
+#define SW1B_STDBY_WID 6
+
+/*
+ * Reg Switcher 2
+ */
+#define SW2A_LSH 0
+#define SW2A_WID 6
+#define SW2A_DVS_LSH 6
+#define SW2A_DVS_WID 6
+#define SW2A_STDBY_LSH 12
+#define SW2A_STDBY_WID 6
+
+/*
+ * Reg Switcher 3
+ */
+#define SW2B_LSH 0
+#define SW2B_WID 6
+#define SW2B_DVS_LSH 6
+#define SW2B_DVS_WID 6
+#define SW2B_STDBY_LSH 12
+#define SW2B_STDBY_WID 6
+
+/*
+ * Reg Switcher 4
+ */
+#define SW1A_MODE_LSH 0
+#define SW1A_MODE_WID 2
+#define SW1A_STBY_MODE_LSH 2
+#define SW1A_STBY_MODE_WID 2
+#define SW1A_DVS_SPEED_LSH 6
+#define SW1A_DVS_SPEED_WID 2
+#define SW1B_MODE_LSH 10
+#define SW1B_MODE_WID 2
+#define SW1B_STBY_MODE_LSH 12
+#define SW1B_STBY_MODE_WID 2
+#define SW1B_DVS_SPEED_LSH 14
+#define SW1B_DVS_SPEED_WID 2
+
+/*
+ * Reg Switcher 5
+ */
+#define SW2A_MODE_LSH 0
+#define SW2A_MODE_WID 2
+#define SW2A_STBY_MODE_LSH 2
+#define SW2A_STBY_MODE_WID 2
+#define SW2A_DVS_SPEED_LSH 6
+#define SW2A_DVS_SPEED_WID 2
+#define SW2B_MODE_LSH 10
+#define SW2B_MODE_WID 2
+#define SW2B_STBY_MODE_LSH 12
+#define SW2B_STBY_MODE_WID 2
+#define SW2B_DVS_SPEED_LSH 14
+#define SW2B_DVS_SPEED_WID 2
+#define SW3_LSH 18
+#define SW3_WID 2
+#define SW3_EN_LSH 20
+#define SW3_EN_WID 2
+#define SW3_EN_ENABLE 1
+#define SW3_EN_DISABLE 0
+
+/*
+ * Reg Regulator Misc.
+ */
+#define GPO1_EN_LSH 6
+#define GPO1_EN_WID 1
+#define GPO1_EN_ENABLE 1
+#define GPO1_EN_DISABLE 0
+#define GPO2_EN_LSH 8
+#define GPO2_EN_WID 1
+#define GPO2_EN_ENABLE 1
+#define GPO2_EN_DISABLE 0
+#define GPO3_EN_LSH 10
+#define GPO3_EN_WID 1
+#define GPO3_EN_ENABLE 1
+#define GPO3_EN_DISABLE 0
+#define GPO4_EN_LSH 12
+#define GPO4_EN_WID 1
+#define GPO4_EN_ENABLE 1
+#define GPO4_EN_DISABLE 0
+
+/*
+ * Switcher mode configuration
+ */
+#define SW_MODE_SYNC_RECT_EN 0
+#define SW_MODE_PULSE_NO_SKIP_EN 1
+#define SW_MODE_PULSE_SKIP_EN 2
+#define SW_MODE_LOW_POWER_EN 3
+
+#define dvs_speed E25mvEach16us
+
+static int mc13783_vaudio_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VAUDIO_EN, VAUDIO_EN_ENABLE);
+ register_mask = BITFMASK(VAUDIO_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vaudio_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VAUDIO_EN, VAUDIO_EN_DISABLE);
+ register_mask = BITFMASK(VAUDIO_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_viohi_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VIOHI_EN, VIOHI_EN_ENABLE);
+ register_mask = BITFMASK(VIOHI_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_viohi_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VIOHI_EN, VIOHI_EN_DISABLE);
+ register_mask = BITFMASK(VIOHI_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_violo_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0, register1 = 0;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1200) && (mV < 1300))
+ voltage = VIOLO_1_2V;
+ else if ((mV >= 1300) && (mV < 1500))
+ voltage = VIOLO_1_3V;
+ else if ((mV >= 1500) && (mV < 1800))
+ voltage = VIOLO_1_5V;
+ else
+ voltage = VIOLO_1_8V;
+
+ register_val = BITFVAL(VIOLO, voltage);
+ register_mask = BITFMASK(VIOLO);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_violo_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VIOLO);
+
+ switch (voltage) {
+ case VIOLO_1_2V:
+ mV = 1200;
+ break;
+ case VIOLO_1_3V:
+ mV = 1300;
+ break;
+ case VIOLO_1_5V:
+ mV = 1500;
+ break;
+ case VIOLO_1_8V:
+ mV = 1800;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_violo_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VIOLO_EN, VIOLO_EN_ENABLE);
+ register_mask = BITFMASK(VIOLO_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_violo_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VIOLO_EN, VIOLO_EN_DISABLE);
+ register_mask = BITFMASK(VIOLO_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vdig_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1200) && (mV < 1300))
+ voltage = VDIG_1_2V;
+ else if ((mV >= 1300) && (mV < 1500))
+ voltage = VDIG_1_3V;
+ else if ((mV >= 1500) && (mV < 1800))
+ voltage = VDIG_1_5V;
+ else
+ voltage = VDIG_1_8V;
+
+ register_val = BITFVAL(VDIG, voltage);
+ register_mask = BITFMASK(VDIG);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vdig_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VDIG);
+
+ switch (voltage) {
+ case VDIG_1_2V:
+ mV = 1200;
+ break;
+ case VDIG_1_3V:
+ mV = 1300;
+ break;
+ case VDIG_1_5V:
+ mV = 1500;
+ break;
+ case VDIG_1_8V:
+ mV = 1800;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vdig_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VDIG_EN, VDIG_EN_ENABLE);
+ register_mask = BITFMASK(VDIG_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vdig_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VDIG_EN, VDIG_EN_DISABLE);
+ register_mask = BITFMASK(VDIG_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vgen_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+ int vgenid = rdev_get_id(reg);
+
+ printk(KERN_INFO "VGEN ID is %d\n", vgenid);
+
+ if ((mV >= 1100) && (mV < 1200))
+ voltage = VGEN_1_1V;
+ else if ((mV >= 1200) && (mV < 1300))
+ voltage = VGEN_1_2V;
+ else if ((mV >= 1300) && (mV < 1500))
+ voltage = VGEN_1_3V;
+ else if ((mV >= 1500) && (mV < 1800))
+ voltage = VGEN_1_5V;
+ else if ((mV >= 1800) && (mV < 2000))
+ voltage = VGEN_1_8V;
+ else if ((mV >= 2000) && (mV < 2400))
+ voltage = VGEN_2V;
+ else if ((mV >= 2400) && (mV < 2775))
+ voltage = VGEN_2_4V;
+ else
+ voltage = VGEN_2_775V;
+
+ register_val = BITFVAL(VGEN, voltage);
+ register_mask = BITFMASK(VGEN);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vgen_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VGEN);
+
+ switch (voltage) {
+ case VGEN_1_2V:
+ mV = 1200;
+ break;
+ case VGEN_1_3V:
+ mV = 1300;
+ break;
+ case VGEN_1_5V:
+ mV = 1500;
+ break;
+ case VGEN_1_8V:
+ mV = 1800;
+ break;
+ case VGEN_1_1V:
+ mV = 1100;
+ break;
+ case VGEN_2V:
+ mV = 2000;
+ break;
+ case VGEN_2_775V:
+ mV = 2775;
+ break;
+ case VGEN_2_4V:
+ mV = 2400;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vgen_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN_EN, VGEN_EN_ENABLE);
+ register_mask = BITFMASK(VGEN_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vgen_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN_EN, VGEN_EN_DISABLE);
+ register_mask = BITFMASK(VGEN_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfdig_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1200) && (mV < 1500))
+ voltage = VRFDIG_1_2V;
+ else if ((mV >= 1500) && (mV < 1300))
+ voltage = VRFDIG_1_5V;
+ else if ((mV >= 1800) && (mV < 1875))
+ voltage = VRFDIG_1_8V;
+ else
+ voltage = VRFDIG_1_875V;
+
+ register_val = BITFVAL(VRFDIG, voltage);
+ register_mask = BITFMASK(VRFDIG);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfdig_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VRFDIG);
+
+ switch (voltage) {
+ case VRFDIG_1_2V:
+ mV = 1200;
+ break;
+ case VRFDIG_1_5V:
+ mV = 1500;
+ break;
+ case VRFDIG_1_8V:
+ mV = 1800;
+ break;
+ case VRFDIG_1_875V:
+ mV = 1875;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vrfdig_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VRFDIG_EN, VRFDIG_EN_ENABLE);
+ register_mask = BITFMASK(VRFDIG_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfdig_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VRFDIG_EN, VRFDIG_EN_DISABLE);
+ register_mask = BITFMASK(VRFDIG_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfref_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 2475) && (mV < 2600))
+ voltage = VRFREF_2_475V;
+ else if ((mV >= 2600) && (mV < 2700))
+ voltage = VRFREF_2_6V;
+ else if ((mV >= 2700) && (mV < 2775))
+ voltage = VRFREF_2_7V;
+ else
+ voltage = VRFREF_2_775V;
+
+ register_val = BITFVAL(VRFREF, voltage);
+ register_mask = BITFMASK(VRFREF);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfref_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VRFREF);
+
+ switch (voltage) {
+ case VRFREF_2_475V:
+ mV = 2475;
+ break;
+ case VRFREF_2_6V:
+ mV = 2600;
+ break;
+ case VRFREF_2_7V:
+ mV = 2700;
+ break;
+ case VRFREF_2_775V:
+ mV = 2775;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vrfref_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VRFREF_EN, VRFREF_EN_ENABLE);
+ register_mask = BITFMASK(VRFREF_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfref_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VRFREF_EN, VRFREF_EN_DISABLE);
+ register_mask = BITFMASK(VRFREF_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfcp_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 2700) && (mV < 2775))
+ voltage = VRFCP_2_7V;
+ else
+ voltage = VRFCP_2_775V;
+
+ register_val = BITFVAL(VRFCP, voltage);
+ register_mask = BITFMASK(VRFCP);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfcp_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VRFCP);
+
+ switch (voltage) {
+ case VRFCP_2_7V:
+ mV = 2700;
+ break;
+ case VRFCP_2_775V:
+ mV = 2775;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vrfcp_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VRFCP_EN, VRFCP_EN_ENABLE);
+ register_mask = BITFMASK(VRFCP_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrfcp_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VRFCP_EN, VRFCP_EN_DISABLE);
+ register_mask = BITFMASK(VRFCP_EN);
+ register1 = REG_REGULATOR_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vsim_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1800) && (mV < 2900))
+ voltage = VSIM_1_8V;
+ else
+ voltage = VSIM_2_9V;
+
+ register_val = BITFVAL(VSIM, voltage);
+ register_mask = BITFMASK(VSIM);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vsim_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VSIM);
+
+ switch (voltage) {
+ case VSIM_1_8V:
+ mV = 1800;
+ break;
+ case VSIM_2_9V:
+ mV = 1900;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vsim_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VSIM_EN, VSIM_EN_ENABLE);
+ register_mask = BITFMASK(VSIM_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vsim_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VSIM_EN, VSIM_EN_DISABLE);
+ register_mask = BITFMASK(VSIM_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vesim_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1800) && (mV < 2900))
+ voltage = VESIM_1_8V;
+ else
+ voltage = VESIM_2_9V;
+
+ register_val = BITFVAL(VESIM, voltage);
+ register_mask = BITFMASK(VESIM);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vesim_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VESIM);
+
+ switch (voltage) {
+ case VESIM_1_8V:
+ mV = 1800;
+ break;
+ case VESIM_2_9V:
+ mV = 1900;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vesim_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VESIM_EN, VESIM_EN_ENABLE);
+ register_mask = BITFMASK(VESIM_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vesim_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VESIM_EN, VESIM_EN_DISABLE);
+ register_mask = BITFMASK(VESIM_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vcam_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1500) && (mV < 1800))
+ voltage = VCAM_1_5V;
+ else if ((mV >= 1800) && (mV < 2500))
+ voltage = VCAM_1_8V;
+ else if ((mV >= 2500) && (mV < 2550))
+ voltage = VCAM_2_5V;
+ else if ((mV >= 2550) && (mV < 2600))
+ voltage = VCAM_2_55V;
+ if ((mV >= 2600) && (mV < 2750))
+ voltage = VCAM_2_6V;
+ else if ((mV >= 2750) && (mV < 2800))
+ voltage = VCAM_2_75V;
+ else if ((mV >= 2800) && (mV < 3000))
+ voltage = VCAM_2_8V;
+ else
+ voltage = VCAM_3V;
+
+ register_val = BITFVAL(VCAM, voltage);
+ register_mask = BITFMASK(VCAM);
+ register1 = REG_REGULATOR_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vcam_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VCAM);
+
+ switch (voltage) {
+ case VCAM_1_5V:
+ mV = 1500;
+ break;
+ case VCAM_1_8V:
+ mV = 1800;
+ break;
+ case VCAM_2_5V:
+ mV = 2500;
+ break;
+ case VCAM_2_55V:
+ mV = 2550;
+ break;
+ case VCAM_2_6V:
+ mV = 2600;
+ break;
+ case VCAM_2_75V:
+ mV = 2750;
+ break;
+ case VCAM_2_8V:
+ mV = 2800;
+ break;
+ case VCAM_3V:
+ mV = 3000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vcam_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VCAM_EN, VCAM_EN_ENABLE);
+ register_mask = BITFMASK(VCAM_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vcam_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VCAM_EN, VCAM_EN_DISABLE);
+ register_mask = BITFMASK(VCAM_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vvib_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1300) && (mV < 1800))
+ voltage = VVIB_1_3V;
+ else if ((mV >= 1800) && (mV < 2000))
+ voltage = VVIB_1_8V;
+ else if ((mV >= 2000) && (mV < 3000))
+ voltage = VVIB_2V;
+ else
+ voltage = VVIB_3V;
+
+ register_val = BITFVAL(VVIB, voltage);
+ register_mask = BITFMASK(VVIB);
+ register1 = REG_REGULATOR_SETTING_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vvib_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_1,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VVIB);
+
+ switch (voltage) {
+ case VVIB_1_3V:
+ mV = 1300;
+ break;
+ case VVIB_1_8V:
+ mV = 1800;
+ break;
+ case VVIB_2V:
+ mV = 2000;
+ break;
+ case VVIB_3V:
+ mV = 3000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vvib_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VVIB_EN, VVIB_EN_ENABLE);
+ register_mask = BITFMASK(VVIB_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vvib_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VVIB_EN, VVIB_EN_DISABLE);
+ register_mask = BITFMASK(VVIB_EN);
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrf_set_voltage(struct regulator_dev *reg, int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, rf = rdev_get_id(reg), mV = uV / 1000;
+
+ if ((mV >= 1500) && (mV < 1875))
+ voltage = VRF_1_5V;
+ else if ((mV >= 1875) && (mV < 2700))
+ voltage = VRF_1_875V;
+ else if ((mV >= 2700) && (mV < 2775))
+ voltage = VRF_2_7V;
+ else
+ voltage = VRF_2_775V;
+
+ switch (rf) {
+ case MC13783_VRF1:
+ register_val = BITFVAL(VRF1, voltage);
+ register_mask = BITFMASK(VRF1);
+ break;
+ case MC13783_VRF2:
+ register_val = BITFVAL(VRF2, voltage);
+ register_mask = BITFMASK(VRF2);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ register1 = REG_REGULATOR_SETTING_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrf_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, rf = rdev_get_id(reg), mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_1,
+ &register_val, PMIC_ALL_BITS));
+
+ switch (rf) {
+ case MC13783_VRF1:
+ voltage = BITFEXT(register_val, VRF1);
+ break;
+ case MC13783_VRF2:
+ voltage = BITFEXT(register_val, VRF2);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ switch (voltage) {
+ case VRF_1_5V:
+ mV = 1500;
+ break;
+ case VRF_1_875V:
+ mV = 1875;
+ break;
+ case VRF_2_7V:
+ mV = 2700;
+ break;
+ case VRF_2_775V:
+ mV = 2775;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vrf_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int vrf = rdev_get_id(reg);
+
+ switch (vrf) {
+ case MC13783_VRF1:
+ register_val = BITFVAL(VRF1_EN, VRF1_EN_ENABLE);
+ register_mask = BITFMASK(VRF1_EN);
+ break;
+ case MC13783_VRF2:
+ register_val = BITFVAL(VRF2_EN, VRF2_EN_ENABLE);
+ register_mask = BITFMASK(VRF2_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vrf_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int vrf = rdev_get_id(reg);
+
+ switch (vrf) {
+ case MC13783_VRF1:
+ register_val = BITFVAL(VRF1_EN, VRF1_EN_DISABLE);
+ register_mask = BITFMASK(VRF1_EN);
+ break;
+ case MC13783_VRF2:
+ register_val = BITFVAL(VRF2_EN, VRF2_EN_DISABLE);
+ register_mask = BITFMASK(VRF2_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vmmc_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mmc = rdev_get_id(reg), mV = uV / 1000;
+
+ printk(KERN_INFO "VMMC ID is %d\n", mmc);
+
+ if ((mV >= 1600) && (mV < 1800))
+ voltage = VMMC_1_6V;
+ else if ((mV >= 1800) && (mV < 2000))
+ voltage = VMMC_1_8V;
+ else if ((mV >= 2000) && (mV < 2600))
+ voltage = VMMC_2V;
+ else if ((mV >= 2600) && (mV < 2700))
+ voltage = VMMC_2_6V;
+ else if ((mV >= 2700) && (mV < 2800))
+ voltage = VMMC_2_7V;
+ else if ((mV >= 2800) && (mV < 2900))
+ voltage = VMMC_2_8V;
+ else if ((mV >= 2900) && (mV < 3000))
+ voltage = VMMC_2_9V;
+ else
+ voltage = VMMC_3V;
+
+ switch (mmc) {
+ case MC13783_VMMC1:
+ register_val = BITFVAL(VMMC1, voltage);
+ register_mask = BITFMASK(VMMC1);
+ break;
+ case MC13783_VMMC2:
+ register_val = BITFVAL(VMMC2, voltage);
+ register_mask = BITFMASK(VMMC2);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ register1 = REG_REGULATOR_SETTING_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vmmc_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mmc = rdev_get_id(reg), mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_1,
+ &register_val, PMIC_ALL_BITS));
+
+ switch (mmc) {
+ case MC13783_VMMC1:
+ voltage = BITFEXT(register_val, VMMC1);
+ break;
+ case MC13783_VMMC2:
+ voltage = BITFEXT(register_val, VMMC2);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (voltage) {
+ case VMMC_1_6V:
+ mV = 1600;
+ break;
+ case VMMC_1_8V:
+ mV = 1800;
+ break;
+ case VMMC_2V:
+ mV = 2000;
+ break;
+ case VMMC_2_6V:
+ mV = 2600;
+ break;
+ case VMMC_2_7V:
+ mV = 2700;
+ break;
+ case VMMC_2_8V:
+ mV = 2800;
+ break;
+ case VMMC_2_9V:
+ mV = 2900;
+ break;
+ case VMMC_3V:
+ mV = 3000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_vmmc_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int vmmc = rdev_get_id(reg);
+
+ switch (vmmc) {
+ case MC13783_VMMC1:
+ register_val = BITFVAL(VMMC1_EN, VMMC1_EN_ENABLE);
+ register_mask = BITFMASK(VMMC1_EN);
+ break;
+ case MC13783_VMMC2:
+ register_val = BITFVAL(VMMC2_EN, VMMC2_EN_ENABLE);
+ register_mask = BITFMASK(VMMC2_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_vmmc_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int vmmc = rdev_get_id(reg);
+
+ switch (vmmc) {
+ case MC13783_VMMC1:
+ register_val = BITFVAL(VMMC1_EN, VMMC1_EN_DISABLE);
+ register_mask = BITFMASK(VMMC1_EN);
+ break;
+ case MC13783_VMMC2:
+ register_val = BITFVAL(VMMC2_EN, VMMC2_EN_DISABLE);
+ register_mask = BITFMASK(VMMC2_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_REGULATOR_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_gpo_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int gpo = rdev_get_id(reg);
+
+ switch (gpo) {
+ case MC13783_GPO1:
+ register_val = BITFVAL(GPO1_EN, GPO1_EN_ENABLE);
+ register_mask = BITFMASK(GPO1_EN);
+ break;
+ case MC13783_GPO2:
+ register_val = BITFVAL(GPO2_EN, GPO2_EN_ENABLE);
+ register_mask = BITFMASK(GPO2_EN);
+ break;
+ case MC13783_GPO3:
+ register_val = BITFVAL(GPO3_EN, GPO3_EN_ENABLE);
+ register_mask = BITFMASK(GPO3_EN);
+ break;
+ case MC13783_GPO4:
+ register_val = BITFVAL(GPO4_EN, GPO4_EN_ENABLE);
+ register_mask = BITFMASK(GPO4_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_POWER_MISCELLANEOUS;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_gpo_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int gpo = rdev_get_id(reg);
+
+ switch (gpo) {
+ case MC13783_GPO1:
+ register_val = BITFVAL(GPO1_EN, GPO1_EN_DISABLE);
+ register_mask = BITFMASK(GPO1_EN);
+ break;
+ case MC13783_GPO2:
+ register_val = BITFVAL(GPO2_EN, GPO2_EN_DISABLE);
+ register_mask = BITFMASK(GPO2_EN);
+ break;
+ case MC13783_GPO3:
+ register_val = BITFVAL(GPO3_EN, GPO3_EN_DISABLE);
+ register_mask = BITFMASK(GPO3_EN);
+ break;
+ case MC13783_GPO4:
+ register_val = BITFVAL(GPO4_EN, GPO4_EN_DISABLE);
+ register_mask = BITFMASK(GPO4_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_POWER_MISCELLANEOUS;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_sw3_set_voltage(struct regulator_dev *reg, int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0, register1 = 0;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 5000) && (mV < 5500))
+ voltage = SW3_5V;
+ else
+ voltage = SW3_5_5V;
+
+ register_val = BITFVAL(SW3, voltage);
+ register_mask = BITFMASK(SW3);
+ register1 = REG_SWITCHERS_5;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_sw3_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_5,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW3);
+
+ if (voltage == SW3_5_5V)
+ mV = 5500;
+ else
+ mV = 5000;
+
+ return mV * 1000;
+}
+
+static int mc13783_sw3_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(SW3_EN, SW3_EN_ENABLE);
+ register_mask = BITFMASK(SW3_EN);
+ register1 = REG_SWITCHERS_5;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_sw3_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(SW3_EN, SW3_EN_DISABLE);
+ register_mask = BITFMASK(SW3_EN);
+ register1 = REG_SWITCHERS_5;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_sw_set_normal_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1 = 0;
+ int voltage, sw = rdev_get_id(reg), mV = uV / 1000;
+
+ if ((mV >= 900) && (mV < 925))
+ voltage = SW_0_9V;
+ else if ((mV >= 925) && (mV < 950))
+ voltage = SW_0_925V;
+ else if ((mV >= 950) && (mV < 975))
+ voltage = SW_0_95V;
+ else if ((mV >= 975) && (mV < 1000))
+ voltage = SW_0_975V;
+ else if ((mV >= 1000) && (mV < 1025))
+ voltage = SW_1V;
+ else if ((mV >= 1025) && (mV < 1050))
+ voltage = SW_1_025V;
+ else if ((mV >= 1050) && (mV < 1075))
+ voltage = SW_1_05V;
+ else if ((mV >= 1075) && (mV < 1100))
+ voltage = SW_1_075V;
+ else if ((mV >= 1100) && (mV < 1125))
+ voltage = SW_1_1V;
+ else if ((mV >= 1125) && (mV < 1150))
+ voltage = SW_1_125V;
+ else if ((mV >= 1150) && (mV < 1175))
+ voltage = SW_1_15V;
+ else if ((mV >= 1175) && (mV < 1200))
+ voltage = SW_1_175V;
+ else if ((mV >= 1200) && (mV < 1225))
+ voltage = SW_1_2V;
+ else if ((mV >= 1225) && (mV < 1250))
+ voltage = SW_1_225V;
+ else if ((mV >= 1250) && (mV < 1275))
+ voltage = SW_1_25V;
+ else if ((mV >= 1275) && (mV < 1300))
+ voltage = SW_1_275V;
+ else if ((mV >= 1300) && (mV < 1325))
+ voltage = SW_1_3V;
+ else if ((mV >= 1325) && (mV < 1350))
+ voltage = SW_1_325V;
+ else if ((mV >= 1350) && (mV < 1375))
+ voltage = SW_1_35V;
+ else if ((mV >= 1375) && (mV < 1400))
+ voltage = SW_1_375V;
+ else if ((mV >= 1400) && (mV < 1425))
+ voltage = SW_1_4V;
+ else if ((mV >= 1425) && (mV < 1450))
+ voltage = SW_1_425V;
+ else if ((mV >= 1450) && (mV < 1475))
+ voltage = SW_1_45V;
+ else if ((mV >= 1475) && (mV < 1500))
+ voltage = SW_1_475V;
+ else if ((mV >= 1500) && (mV < 1525))
+ voltage = SW_1_5V;
+ else if ((mV >= 1525) && (mV < 1550))
+ voltage = SW_1_525V;
+ else if ((mV >= 1550) && (mV < 1575))
+ voltage = SW_1_55V;
+ else if ((mV >= 1575) && (mV < 1600))
+ voltage = SW_1_575V;
+ else if ((mV >= 1600) && (mV < 1625))
+ voltage = SW_1_6V;
+ else if ((mV >= 1625) && (mV < 1650))
+ voltage = SW_1_625V;
+ else if ((mV >= 1650) && (mV < 1675))
+ voltage = SW_1_65V;
+ else if ((mV >= 1675) && (mV < 1700))
+ voltage = SW_1_675V;
+ else if ((mV >= 1700) && (mV < 1800))
+ voltage = SW_1_7V;
+ else if ((mV >= 1800) && (mV < 1850))
+ voltage = SW_1_8V;
+ else if ((mV >= 1850) && (mV < 2000))
+ voltage = SW_1_85V;
+ else if ((mV >= 2000) && (mV < 2100))
+ voltage = SW_2V;
+ else if ((mV >= 2100) && (mV < 2200))
+ voltage = SW_2_1V;
+ else
+ voltage = SW_2_2V;
+
+ switch (sw) {
+ case MC13783_SW1A:
+ register1 = REG_SWITCHERS_0;
+ register_val = BITFVAL(SW1A, voltage);
+ register_mask = BITFMASK(SW1A);
+ break;
+ case MC13783_SW1B:
+ register1 = REG_SWITCHERS_1;
+ register_val = BITFVAL(SW1B, voltage);
+ register_mask = BITFMASK(SW1B);
+ break;
+ case MC13783_SW2A:
+ register1 = REG_SWITCHERS_2;
+ register_val = BITFVAL(SW2A, voltage);
+ register_mask = BITFMASK(SW2A);
+ break;
+ case MC13783_SW2B:
+ register1 = REG_SWITCHERS_3;
+ register_val = BITFVAL(SW2B, voltage);
+ register_mask = BITFMASK(SW2B);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_sw_get_normal_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0, sw = rdev_get_id(reg);
+
+ switch (sw) {
+ case MC13783_SW1A:
+ CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW1A);
+ break;
+ case MC13783_SW1B:
+ CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_1,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW1B);
+ break;
+ case MC13783_SW2A:
+ CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_2,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW2A);
+ break;
+ case MC13783_SW2B:
+ CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_3,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW2B);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (voltage) {
+ case SW_0_9V:
+ mV = 900;
+ break;
+ case SW_0_925V:
+ mV = 925;
+ break;
+ case SW_0_95V:
+ mV = 950;
+ break;
+ case SW_0_975V:
+ mV = 975;
+ break;
+ case SW_1V:
+ mV = 1000;
+ break;
+ case SW_1_025V:
+ mV = 1025;
+ break;
+ case SW_1_05V:
+ mV = 1050;
+ break;
+ case SW_1_075V:
+ mV = 1075;
+ break;
+ case SW_1_1V:
+ mV = 1100;
+ break;
+ case SW_1_125V:
+ mV = 1125;
+ break;
+ case SW_1_15V:
+ mV = 1150;
+ break;
+ case SW_1_175V:
+ mV = 1175;
+ break;
+ case SW_1_2V:
+ mV = 1200;
+ break;
+ case SW_1_225V:
+ mV = 1225;
+ break;
+ case SW_1_25V:
+ mV = 1250;
+ break;
+ case SW_1_275V:
+ mV = 1275;
+ break;
+ case SW_1_3V:
+ mV = 1300;
+ break;
+ case SW_1_325V:
+ mV = 1325;
+ break;
+ case SW_1_35V:
+ mV = 1350;
+ break;
+ case SW_1_375V:
+ mV = 1375;
+ break;
+ case SW_1_4V:
+ mV = 1400;
+ break;
+ case SW_1_425V:
+ mV = 1425;
+ break;
+ case SW_1_45V:
+ mV = 1450;
+ break;
+ case SW_1_475V:
+ mV = 1475;
+ break;
+ case SW_1_5V:
+ mV = 1500;
+ break;
+ case SW_1_525V:
+ mV = 1525;
+ break;
+ case SW_1_55V:
+ mV = 1550;
+ break;
+ case SW_1_575V:
+ mV = 1575;
+ break;
+ case SW_1_6V:
+ mV = 1600;
+ break;
+ case SW_1_625V:
+ mV = 1625;
+ break;
+ case SW_1_65V:
+ mV = 1650;
+ break;
+ case SW_1_675V:
+ mV = 1675;
+ break;
+ case SW_1_7V:
+ mV = 1700;
+ break;
+ case SW_1_8V:
+ mV = 1800;
+ break;
+ case SW_1_85V:
+ mV = 1850;
+ break;
+ case SW_2V:
+ mV = 2000;
+ break;
+ case SW_2_1V:
+ mV = 2100;
+ break;
+ case SW_2_2V:
+ mV = 2200;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13783_sw_normal_enable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int mc13783_sw_normal_disable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int mc13783_sw_stby_enable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int mc13783_sw_stby_disable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int mc13783_sw_set_stby_voltage(struct regulator_dev *reg, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1 = 0;
+ int voltage, sw = rdev_get_id(reg), mV = uV / 1000;
+
+ if ((mV >= 900) && (mV < 925))
+ voltage = SW_0_9V;
+ else if ((mV >= 925) && (mV < 950))
+ voltage = SW_0_925V;
+ else if ((mV >= 950) && (mV < 975))
+ voltage = SW_0_95V;
+ else if ((mV >= 975) && (mV < 1000))
+ voltage = SW_0_975V;
+ else if ((mV >= 1000) && (mV < 1025))
+ voltage = SW_1V;
+ else if ((mV >= 1025) && (mV < 1050))
+ voltage = SW_1_025V;
+ else if ((mV >= 1050) && (mV < 1075))
+ voltage = SW_1_05V;
+ else if ((mV >= 1075) && (mV < 1100))
+ voltage = SW_1_075V;
+ else if ((mV >= 1100) && (mV < 1125))
+ voltage = SW_1_1V;
+ else if ((mV >= 1125) && (mV < 1150))
+ voltage = SW_1_125V;
+ else if ((mV >= 1150) && (mV < 1175))
+ voltage = SW_1_15V;
+ else if ((mV >= 1175) && (mV < 1200))
+ voltage = SW_1_175V;
+ else if ((mV >= 1200) && (mV < 1225))
+ voltage = SW_1_2V;
+ else if ((mV >= 1225) && (mV < 1250))
+ voltage = SW_1_225V;
+ else if ((mV >= 1250) && (mV < 1275))
+ voltage = SW_1_25V;
+ else if ((mV >= 1275) && (mV < 1300))
+ voltage = SW_1_275V;
+ else if ((mV >= 1300) && (mV < 1325))
+ voltage = SW_1_3V;
+ else if ((mV >= 1325) && (mV < 1350))
+ voltage = SW_1_325V;
+ else if ((mV >= 1350) && (mV < 1375))
+ voltage = SW_1_35V;
+ else if ((mV >= 1375) && (mV < 1400))
+ voltage = SW_1_375V;
+ else if ((mV >= 1400) && (mV < 1425))
+ voltage = SW_1_4V;
+ else if ((mV >= 1425) && (mV < 1450))
+ voltage = SW_1_425V;
+ else if ((mV >= 1450) && (mV < 1475))
+ voltage = SW_1_45V;
+ else if ((mV >= 1475) && (mV < 1500))
+ voltage = SW_1_475V;
+ else if ((mV >= 1500) && (mV < 1525))
+ voltage = SW_1_5V;
+ else if ((mV >= 1525) && (mV < 1550))
+ voltage = SW_1_525V;
+ else if ((mV >= 1550) && (mV < 1575))
+ voltage = SW_1_55V;
+ else if ((mV >= 1575) && (mV < 1600))
+ voltage = SW_1_575V;
+ else if ((mV >= 1600) && (mV < 1625))
+ voltage = SW_1_6V;
+ else if ((mV >= 1625) && (mV < 1650))
+ voltage = SW_1_625V;
+ else if ((mV >= 1650) && (mV < 1675))
+ voltage = SW_1_65V;
+ else if ((mV >= 1675) && (mV < 1700))
+ voltage = SW_1_675V;
+ else if ((mV >= 1700) && (mV < 1800))
+ voltage = SW_1_7V;
+ else if ((mV >= 1800) && (mV < 1850))
+ voltage = SW_1_8V;
+ else if ((mV >= 1850) && (mV < 2000))
+ voltage = SW_1_85V;
+ else if ((mV >= 2000) && (mV < 2100))
+ voltage = SW_2V;
+ else if ((mV >= 2100) && (mV < 2200))
+ voltage = SW_2_1V;
+ else
+ voltage = SW_2_2V;
+
+ switch (sw) {
+ case MC13783_SW1A:
+ register1 = REG_SWITCHERS_0;
+ register_val = BITFVAL(SW1A_STDBY, voltage);
+ register_mask = BITFMASK(SW1A_STDBY);
+ break;
+ case MC13783_SW1B:
+ register1 = REG_SWITCHERS_1;
+ register_val = BITFVAL(SW1B_STDBY, voltage);
+ register_mask = BITFMASK(SW1B_STDBY);
+ break;
+ case MC13783_SW2A:
+ register1 = REG_SWITCHERS_2;
+ register_val = BITFVAL(SW2A_STDBY, voltage);
+ register_mask = BITFMASK(SW2A_STDBY);
+ break;
+ case MC13783_SW2B:
+ register1 = REG_SWITCHERS_3;
+ register_val = BITFVAL(SW2B_STDBY, voltage);
+ register_mask = BITFMASK(SW2B_STDBY);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13783_sw_set_normal_mode(struct regulator_dev *reg,
+ unsigned int mode)
+{
+ unsigned int reg_val = 0, reg_mask = 0;
+ unsigned int register1 = 0;
+ unsigned int l_mode;
+ int sw = rdev_get_id(reg);
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ /* SYNC RECT mode */
+ l_mode = SW_MODE_SYNC_RECT_EN;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ /* PULSE SKIP mode */
+ l_mode = SW_MODE_PULSE_SKIP_EN;
+ break;
+ case REGULATOR_MODE_IDLE:
+ /* LOW POWER mode */
+ l_mode = SW_MODE_LOW_POWER_EN;
+ break;
+ case REGULATOR_MODE_STANDBY:
+ /* NO PULSE SKIP mode */
+ l_mode = SW_MODE_PULSE_NO_SKIP_EN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (sw) {
+ case MC13783_SW1A:
+ reg_val = BITFVAL(SW1A_MODE, l_mode);
+ reg_mask = BITFMASK(SW1A_MODE);
+ register1 = REG_SWITCHERS_4;
+ break;
+ case MC13783_SW1B:
+ reg_val = BITFVAL(SW1B_MODE, l_mode);
+ reg_mask = BITFMASK(SW1B_MODE);
+ register1 = REG_SWITCHERS_4;
+ break;
+ case MC13783_SW2A:
+ reg_val = BITFVAL(SW2A_MODE, l_mode);
+ reg_mask = BITFMASK(SW2A_MODE);
+ register1 = REG_SWITCHERS_5;
+ break;
+ case MC13783_SW2B:
+ reg_val = BITFVAL(SW2B_MODE, l_mode);
+ reg_mask = BITFMASK(SW2B_MODE);
+ register1 = REG_SWITCHERS_5;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return pmic_write_reg(register1, reg_val, reg_mask);
+}
+
+static unsigned int mc13783_sw_get_normal_mode(struct regulator_dev *reg)
+{
+ unsigned int reg_val = 0, reg_mask = 0;
+ unsigned int register1 = 0;
+ unsigned int l_mode = 0;
+ int sw = rdev_get_id(reg);
+ int ret = 0;
+
+ switch (sw) {
+ case MC13783_SW1A:
+ reg_mask = BITFMASK(SW1A_MODE);
+ register1 = REG_SWITCHERS_4;
+ break;
+ case MC13783_SW1B:
+ reg_mask = BITFMASK(SW1B_MODE);
+ register1 = REG_SWITCHERS_4;
+ break;
+ case MC13783_SW2A:
+ reg_mask = BITFMASK(SW2A_MODE);
+ register1 = REG_SWITCHERS_5;
+ break;
+ case MC13783_SW2B:
+ reg_mask = BITFMASK(SW2B_MODE);
+ register1 = REG_SWITCHERS_5;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = pmic_read_reg(register1, &reg_val, reg_mask);
+ if (ret != 0)
+ return ret;
+
+ switch (sw) {
+ case MC13783_SW1A:
+ l_mode = BITFEXT(reg_val, SW1A_MODE);
+ break;
+ case MC13783_SW1B:
+ l_mode = BITFEXT(reg_val, SW1B_MODE);
+ break;
+ case MC13783_SW2A:
+ l_mode = BITFEXT(reg_val, SW2A_MODE);
+ break;
+ case MC13783_SW2B:
+ l_mode = BITFEXT(reg_val, SW2B_MODE);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (l_mode == SW_MODE_SYNC_RECT_EN) {
+ return REGULATOR_MODE_FAST;
+ } else if (l_mode == SW_MODE_PULSE_NO_SKIP_EN) {
+ return REGULATOR_MODE_STANDBY;
+ } else if (l_mode == SW_MODE_PULSE_SKIP_EN) {
+ return REGULATOR_MODE_NORMAL;
+ } else if (l_mode == SW_MODE_LOW_POWER_EN) {
+ return REGULATOR_MODE_IDLE;
+ } else {
+ return -EINVAL;
+ }
+}
+
+static int mc13783_sw_set_stby_mode(struct regulator_dev *reg,
+ unsigned int mode)
+{
+ unsigned int reg_val = 0, reg_mask = 0;
+ unsigned int register1 = 0;
+ unsigned int l_mode;
+ int sw = rdev_get_id(reg);
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ /* SYNC RECT mode */
+ l_mode = SW_MODE_SYNC_RECT_EN;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ /* PULSE SKIP mode */
+ l_mode = SW_MODE_PULSE_SKIP_EN;
+ break;
+ case REGULATOR_MODE_IDLE:
+ /* LOW POWER mode */
+ l_mode = SW_MODE_LOW_POWER_EN;
+ break;
+ case REGULATOR_MODE_STANDBY:
+ /* NO PULSE SKIP mode */
+ l_mode = SW_MODE_PULSE_NO_SKIP_EN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (sw) {
+ case MC13783_SW1A:
+ reg_val = BITFVAL(SW1A_STBY_MODE, l_mode);
+ reg_mask = BITFMASK(SW1A_STBY_MODE);
+ register1 = REG_SWITCHERS_4;
+ break;
+ case MC13783_SW1B:
+ reg_val = BITFVAL(SW1B_STBY_MODE, l_mode);
+ reg_mask = BITFMASK(SW1B_STBY_MODE);
+ register1 = REG_SWITCHERS_4;
+ break;
+ case MC13783_SW2A:
+ reg_val = BITFVAL(SW2A_STBY_MODE, l_mode);
+ reg_mask = BITFMASK(SW2A_STBY_MODE);
+ register1 = REG_SWITCHERS_5;
+ break;
+ case MC13783_SW2B:
+ reg_val = BITFVAL(SW2B_STBY_MODE, l_mode);
+ reg_mask = BITFMASK(SW2B_STBY_MODE);
+ register1 = REG_SWITCHERS_5;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return pmic_write_reg(register1, reg_val, reg_mask);
+}
+
+static struct regulator_ops mc13783_vaudio_ops = {
+ .enable = mc13783_vaudio_enable,
+ .disable = mc13783_vaudio_disable,
+};
+
+static struct regulator_ops mc13783_viohi_ops = {
+ .enable = mc13783_viohi_enable,
+ .disable = mc13783_viohi_disable,
+};
+
+static struct regulator_ops mc13783_violo_ops = {
+ .set_voltage = mc13783_violo_set_voltage,
+ .get_voltage = mc13783_violo_get_voltage,
+ .enable = mc13783_violo_enable,
+ .disable = mc13783_violo_disable,
+};
+
+static struct regulator_ops mc13783_vdig_ops = {
+ .set_voltage = mc13783_vdig_set_voltage,
+ .get_voltage = mc13783_vdig_get_voltage,
+ .enable = mc13783_vdig_enable,
+ .disable = mc13783_vdig_disable,
+};
+
+static struct regulator_ops mc13783_vgen_ops = {
+ .set_voltage = mc13783_vgen_set_voltage,
+ .get_voltage = mc13783_vgen_get_voltage,
+ .enable = mc13783_vgen_enable,
+ .disable = mc13783_vgen_disable,
+};
+
+static struct regulator_ops mc13783_vrfdig_ops = {
+ .set_voltage = mc13783_vrfdig_set_voltage,
+ .get_voltage = mc13783_vrfdig_get_voltage,
+ .enable = mc13783_vrfdig_enable,
+ .disable = mc13783_vrfdig_disable,
+};
+
+static struct regulator_ops mc13783_vrfref_ops = {
+ .set_voltage = mc13783_vrfref_set_voltage,
+ .get_voltage = mc13783_vrfref_get_voltage,
+ .enable = mc13783_vrfref_enable,
+ .disable = mc13783_vrfref_disable,
+};
+
+static struct regulator_ops mc13783_vrfcp_ops = {
+ .set_voltage = mc13783_vrfcp_set_voltage,
+ .get_voltage = mc13783_vrfcp_get_voltage,
+ .enable = mc13783_vrfcp_enable,
+ .disable = mc13783_vrfcp_disable,
+};
+
+static struct regulator_ops mc13783_vsim_ops = {
+ .set_voltage = mc13783_vsim_set_voltage,
+ .get_voltage = mc13783_vsim_get_voltage,
+ .enable = mc13783_vsim_enable,
+ .disable = mc13783_vsim_disable,
+};
+
+static struct regulator_ops mc13783_vesim_ops = {
+ .set_voltage = mc13783_vesim_set_voltage,
+ .get_voltage = mc13783_vesim_get_voltage,
+ .enable = mc13783_vesim_enable,
+ .disable = mc13783_vesim_disable,
+};
+
+static struct regulator_ops mc13783_vcam_ops = {
+ .set_voltage = mc13783_vcam_set_voltage,
+ .get_voltage = mc13783_vcam_get_voltage,
+ .enable = mc13783_vcam_enable,
+ .disable = mc13783_vcam_disable,
+};
+
+static struct regulator_ops mc13783_vvib_ops = {
+ .set_voltage = mc13783_vvib_set_voltage,
+ .get_voltage = mc13783_vvib_get_voltage,
+ .enable = mc13783_vvib_enable,
+ .disable = mc13783_vvib_disable,
+};
+
+static struct regulator_ops mc13783_vrf_ops = {
+ .set_voltage = mc13783_vrf_set_voltage,
+ .get_voltage = mc13783_vrf_get_voltage,
+ .enable = mc13783_vrf_enable,
+ .disable = mc13783_vrf_disable,
+};
+
+static struct regulator_ops mc13783_vmmc_ops = {
+ .set_voltage = mc13783_vmmc_set_voltage,
+ .get_voltage = mc13783_vmmc_get_voltage,
+ .enable = mc13783_vmmc_enable,
+ .disable = mc13783_vmmc_disable,
+};
+
+static struct regulator_ops mc13783_gpo_ops = {
+ .enable = mc13783_gpo_enable,
+ .disable = mc13783_gpo_disable,
+};
+
+static struct regulator_ops mc13783_sw3_ops = {
+ .set_voltage = mc13783_sw3_set_voltage,
+ .get_voltage = mc13783_sw3_get_voltage,
+ .enable = mc13783_sw3_enable,
+ .disable = mc13783_sw3_disable,
+};
+
+static struct regulator_ops mc13783_sw1_ops = {
+ .set_voltage = mc13783_sw_set_normal_voltage,
+ .get_voltage = mc13783_sw_get_normal_voltage,
+ .get_mode = mc13783_sw_get_normal_mode,
+ .set_mode = mc13783_sw_set_normal_mode,
+ .set_suspend_voltage = mc13783_sw_set_stby_voltage,
+ .set_suspend_enable = mc13783_sw_stby_enable,
+ .set_suspend_disable = mc13783_sw_stby_disable,
+ .set_suspend_mode = mc13783_sw_set_stby_mode,
+};
+
+static struct regulator_ops mc13783_sw_normal_ops = {
+ .set_voltage = mc13783_sw_set_normal_voltage,
+ .get_voltage = mc13783_sw_get_normal_voltage,
+ .get_mode = mc13783_sw_get_normal_mode,
+ .set_mode = mc13783_sw_set_normal_mode,
+ .enable = mc13783_sw_normal_enable,
+ .disable = mc13783_sw_normal_disable,
+};
+
+static struct regulator_desc reg_mc13783[] = {
+ {
+ .name = "SW1A",
+ .id = MC13783_SW1A,
+ .ops = &mc13783_sw1_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW1B",
+ .id = MC13783_SW1B,
+ .ops = &mc13783_sw_normal_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW2A",
+ .id = MC13783_SW2A,
+ .ops = &mc13783_sw_normal_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW2B",
+ .id = MC13783_SW2B,
+ .ops = &mc13783_sw_normal_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW3",
+ .id = MC13783_SW3,
+ .ops = &mc13783_sw3_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VAUDIO",
+ .id = MC13783_VAUDIO,
+ .ops = &mc13783_vaudio_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VIOHI",
+ .id = MC13783_VIOHI,
+ .ops = &mc13783_viohi_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VIOLO",
+ .id = MC13783_VIOLO,
+ .ops = &mc13783_violo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VDIG",
+ .id = MC13783_VDIG,
+ .ops = &mc13783_vdig_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VGEN",
+ .id = MC13783_VGEN,
+ .ops = &mc13783_vgen_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VRFDIG",
+ .id = MC13783_VRFDIG,
+ .ops = &mc13783_vrfdig_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VRFREF",
+ .id = MC13783_VRFREF,
+ .ops = &mc13783_vrfref_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VRFCP",
+ .id = MC13783_VRFCP,
+ .ops = &mc13783_vrfcp_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VSIM",
+ .id = MC13783_VSIM,
+ .ops = &mc13783_vsim_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VESIM",
+ .id = MC13783_VESIM,
+ .ops = &mc13783_vesim_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VCAM",
+ .id = MC13783_VCAM,
+ .ops = &mc13783_vcam_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VRFBG",
+ .id = MC13783_VRFBG,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VVIB",
+ .id = MC13783_VVIB,
+ .ops = &mc13783_vvib_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VRF1",
+ .id = MC13783_VRF1,
+ .ops = &mc13783_vrf_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VRF2",
+ .id = MC13783_VRF2,
+ .ops = &mc13783_vrf_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VMMC1",
+ .id = MC13783_VMMC1,
+ .ops = &mc13783_vmmc_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VMMC2",
+ .id = MC13783_VMMC2,
+ .ops = &mc13783_vmmc_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO1",
+ .id = MC13783_GPO1,
+ .ops = &mc13783_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO2",
+ .id = MC13783_GPO2,
+ .ops = &mc13783_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO3",
+ .id = MC13783_GPO3,
+ .ops = &mc13783_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO4",
+ .id = MC13783_GPO4,
+ .ops = &mc13783_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+};
+
+/*
+ * Init and Exit
+ */
+
+static int reg_mc13783_probe(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev;
+
+ /* register regulator */
+ rdev = regulator_register(&reg_mc13783[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
+ dev_get_drvdata(&pdev->dev));
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ reg_mc13783[pdev->id].name);
+ return PTR_ERR(rdev);
+ }
+ platform_set_drvdata(pdev, rdev);
+
+ return 0;
+}
+
+static int mc13783_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+
+ return 0;
+}
+
+int mc13783_register_regulator(struct mc13783 *mc13783, int reg,
+ struct regulator_init_data *initdata)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ if (mc13783->pmic.pdev[reg])
+ return -EBUSY;
+
+ pdev = platform_device_alloc("mc13783-regulatr", reg);
+ if (!pdev)
+ return -ENOMEM;
+
+ mc13783->pmic.pdev[reg] = pdev;
+
+ initdata->driver_data = mc13783;
+
+ pdev->dev.platform_data = initdata;
+ pdev->dev.parent = mc13783->dev;
+ ret = platform_device_add(pdev);
+
+ if (ret != 0) {
+ dev_err(mc13783->dev, "Failed to register regulator %d: %d\n",
+ reg, ret);
+ platform_device_del(pdev);
+ mc13783->pmic.pdev[reg] = NULL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mc13783_register_regulator);
+
+static struct platform_driver mc13783_regulator_driver = {
+ .probe = reg_mc13783_probe,
+ .remove = mc13783_regulator_remove,
+ .driver = {
+ .name = "mc13783-regulatr",
+ /* o left out due to string length */
+ },
+};
+
+static int __init mc13783_regulator_subsys_init(void)
+{
+ return platform_driver_register(&mc13783_regulator_driver);
+}
+subsys_initcall(mc13783_regulator_subsys_init);
+
+static void __exit mc13783_regulator_exit(void)
+{
+ platform_driver_unregister(&mc13783_regulator_driver);
+}
+module_exit(mc13783_regulator_exit);
+
+
+/* Module information */
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MC13783 Regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/reg-mc13892.c b/drivers/regulator/reg-mc13892.c
new file mode 100644
index 000000000000..f6803f8ba837
--- /dev/null
+++ b/drivers/regulator/reg-mc13892.c
@@ -0,0 +1,1850 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/mc13892/core.h>
+#include <linux/platform_device.h>
+#include <linux/pmic_status.h>
+#include <linux/pmic_external.h>
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+enum {
+ VDIG_1_05V = 0,
+ VDIG_1_25V,
+ VDIG_1_65V,
+ VDIG_1_80V,
+} regulator_voltage_vdig;
+
+enum {
+ VPLL_1_05V = 0,
+ VPLL_1_25V,
+ VPLL_1_65V,
+ VPLL_1_80V,
+} regulator_voltage_vpll;
+
+enum {
+ VGEN1_1_2V = 0,
+ VGEN1_1_5V,
+ VGEN1_2_775V,
+ VGEN1_3_15V,
+} regulator_voltage_vgen1;
+
+enum {
+ VGEN2_1_2V = 0,
+ VGEN2_1_5V,
+ VGEN2_1_6V,
+ VGEN2_1_8V,
+ VGEN2_2_7V,
+ VGEN2_2_8V,
+ VGEN2_3_0V,
+ VGEN2_3_15V,
+} regulator_voltage_vgen2;
+
+enum {
+ VGEN3_1_8V = 0,
+ VGEN3_2_9V,
+} regulator_voltage_vgen3;
+
+enum {
+ VSD_1_8V = 0,
+ VSD_2_0V,
+ VSD_2_6V,
+ VSD_2_7V,
+ VSD_2_8V,
+ VSD_2_9V,
+ VSD_3_0V,
+ VSD_3_15V,
+} regulator_voltage_vsd;
+
+enum {
+ VCAM_2_5V,
+ VCAM_2_6V,
+ VCAM_2_75V,
+ VCAM_3_0V,
+} regulator_voltage_vcam;
+
+enum {
+ VAUDIO_2_3V,
+ VAUDIO_2_5V,
+ VAUDIO_2_775V,
+ VAUDIO_3V,
+} regulator_voltage_vaudio;
+
+enum {
+ VUSB2_2_4V,
+ VUSB2_2_6V,
+ VUSB2_2_7V,
+ VUSB2_2_775V,
+} regulator_voltage_vusb2;
+
+enum {
+ VVIDEO_2_7V,
+ VVIDEO_2_775V,
+ VVIDEO_2_5V,
+ VVIDEO_2_6V,
+} regulator_voltage_vvideo;
+
+#define VAUDIO_LSH 4
+#define VAUDIO_WID 2
+#define VAUDIO_EN_LSH 15
+#define VAUDIO_EN_WID 1
+#define VAUDIO_EN_ENABLE 1
+#define VAUDIO_EN_DISABLE 0
+
+#define VUSB2_LSH 11
+#define VUSB2_WID 2
+#define VUSB2_EN_LSH 18
+#define VUSB2_EN_WID 1
+#define VUSB2_EN_ENABLE 1
+#define VUSB2_EN_DISABLE 0
+
+#define VVIDEO_LSH 2
+#define VVIDEO_WID 2
+#define VVIDEO_EN_LSH 12
+#define VVIDEO_EN_WID 1
+#define VVIDEO_EN_ENABLE 1
+#define VVIDEO_EN_DISABLE 0
+
+#define SWBST_EN_LSH 20
+#define SWBST_EN_WID 1
+#define SWBST_EN_ENABLE 1
+#define SWBST_EN_DISABLE 0
+
+#define VIOHI_EN_LSH 3
+#define VIOHI_EN_WID 1
+#define VIOHI_EN_ENABLE 1
+#define VIOHI_EN_DISABLE 0
+
+#define VDIG_LSH 4
+#define VDIG_WID 2
+#define VDIG_EN_LSH 9
+#define VDIG_EN_WID 1
+#define VDIG_EN_ENABLE 1
+#define VDIG_EN_DISABLE 0
+
+#define VPLL_LSH 9
+#define VPLL_WID 2
+#define VPLL_EN_LSH 15
+#define VPLL_EN_WID 1
+#define VPLL_EN_ENABLE 1
+#define VPLL_EN_DISABLE 0
+
+#define VGEN1_LSH 0
+#define VGEN1_WID 2
+#define VGEN1_EN_LSH 0
+#define VGEN1_EN_WID 1
+#define VGEN1_EN_ENABLE 1
+#define VGEN1_EN_DISABLE 0
+
+#define VGEN2_LSH 6
+#define VGEN2_WID 3
+#define VGEN2_EN_LSH 12
+#define VGEN2_EN_WID 1
+#define VGEN2_EN_ENABLE 1
+#define VGEN2_EN_DISABLE 0
+
+#define VGEN3_LSH 14
+#define VGEN3_WID 1
+#define VGEN3_EN_LSH 0
+#define VGEN3_EN_WID 1
+#define VGEN3_EN_ENABLE 1
+#define VGEN3_EN_DISABLE 0
+
+#define VSD_LSH 6
+#define VSD_WID 3
+#define VSD_EN_LSH 18
+#define VSD_EN_WID 1
+#define VSD_EN_ENABLE 1
+#define VSD_EN_DISABLE 0
+
+#define VCAM_LSH 16
+#define VCAM_WID 2
+#define VCAM_EN_LSH 6
+#define VCAM_EN_WID 1
+#define VCAM_EN_ENABLE 1
+#define VCAM_EN_DISABLE 0
+#define VCAM_CONFIG_LSH 9
+#define VCAM_CONFIG_WID 1
+#define VCAM_CONFIG_EXT 1
+#define VCAM_CONFIG_INT 0
+
+#define SW1_LSH 0
+#define SW1_WID 5
+#define SW1_DVS_LSH 5
+#define SW1_DVS_WID 5
+#define SW1_STDBY_LSH 10
+#define SW1_STDBY_WID 5
+
+#define SW2_LSH 0
+#define SW2_WID 5
+#define SW2_DVS_LSH 5
+#define SW2_DVS_WID 5
+#define SW2_STDBY_LSH 10
+#define SW2_STDBY_WID 5
+
+#define SW3_LSH 0
+#define SW3_WID 5
+#define SW3_STDBY_LSH 10
+#define SW3_STDBY_WID 5
+
+#define SW4_LSH 0
+#define SW4_WID 5
+#define SW4_STDBY_LSH 10
+#define SW4_STDBY_WID 5
+
+#define VUSB_EN_LSH 3
+#define VUSB_EN_WID 1
+#define VUSB_EN_ENABLE 1
+#define VUSB_EN_DISABLE 0
+
+#define GPO1_EN_LSH 6
+#define GPO1_EN_WID 1
+#define GPO1_EN_ENABLE 1
+#define GPO1_EN_DISABLE 0
+
+#define GPO2_EN_LSH 8
+#define GPO2_EN_WID 1
+#define GPO2_EN_ENABLE 1
+#define GPO2_EN_DISABLE 0
+
+#define GPO3_EN_LSH 10
+#define GPO3_EN_WID 1
+#define GPO3_EN_ENABLE 1
+#define GPO3_EN_DISABLE 0
+
+#define GPO4_EN_LSH 12
+#define GPO4_EN_WID 1
+#define GPO4_EN_ENABLE 1
+#define GPO4_EN_DISABLE 0
+
+#define GPO4_ADIN_LSH 21
+#define GPO4_ADIN_WID 1
+#define GPO4_ADIN_ENABLE 1
+#define GPO4_ADIN_DISABLE 0
+
+#define PWGT1SPI_EN_LSH 15
+#define PWGT1SPI_EN_WID 1
+#define PWGT1SPI_EN_ENABLE 0
+#define PWGT1SPI_EN_DISABLE 1
+
+#define PWGT2SPI_EN_LSH 16
+#define PWGT2SPI_EN_WID 1
+#define PWGT2SPI_EN_ENABLE 0
+#define PWGT2SPI_EN_DISABLE 1
+
+#define SWXHI_LSH 23
+#define SWXHI_WID 1
+#define SWXHI_ON 1
+#define SWXHI_OFF 0
+
+static int mc13892_get_sw_hi_bit(int sw)
+{
+ unsigned int register_val = 0;
+ unsigned int reg = 0;
+
+ switch (sw) {
+ case MC13892_SW1:
+ reg = REG_SW_0;
+ break;
+ case MC13892_SW2:
+ reg = REG_SW_1;
+ break;
+ case MC13892_SW3:
+ reg = REG_SW_2;
+ break;
+ case MC13892_SW4:
+ reg = REG_SW_3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ CHECK_ERROR(pmic_read_reg(reg, &register_val, PMIC_ALL_BITS));
+ return (register_val & 0x800000) >> SWXHI_LSH;
+}
+
+static int mc13892_get_voltage_value(int *hi, int mV)
+{
+ int voltage;
+
+ if (mV < 600)
+ mV = 600;
+ if (mV > 1850)
+ mV = 1850;
+
+ if (mV > 1375)
+ *hi = 1;
+ if (mV < 1100)
+ *hi = 0;
+
+ if (*hi == 0)
+ voltage = (mV - 600) / 25;
+ else
+ voltage = (mV - 1100) / 25;
+
+ return voltage;
+}
+
+static int mc13892_get_voltage_mV(int hi, int voltage)
+{
+ int mV;
+
+ if (hi == 0)
+ mV = voltage * 25 + 600;
+ else
+ mV = voltage * 25 + 1100;
+
+ return mV;
+}
+
+static int mc13892_sw_set_voltage(struct regulator_dev *reg, int MiniV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1 = 0;
+ int voltage;
+ int sw = rdev_get_id(reg);
+ int mV = uV / 1000;
+ int hi;
+
+ hi = mc13892_get_sw_hi_bit(sw);
+ voltage = mc13892_get_voltage_value(&hi, mV);
+
+ switch (sw) {
+ case MC13892_SW1:
+ register1 = REG_SW_0;
+ register_val = BITFVAL(SW1, voltage);
+ register_mask = BITFMASK(SW1);
+ break;
+ case MC13892_SW2:
+ register1 = REG_SW_1;
+ register_val = BITFVAL(SW2, voltage);
+ register_mask = BITFMASK(SW2);
+ break;
+ case MC13892_SW3:
+ register1 = REG_SW_2;
+ register_val = BITFVAL(SW3, voltage);
+ register_mask = BITFMASK(SW3);
+ break;
+ case MC13892_SW4:
+ register1 = REG_SW_3;
+ register_val = BITFVAL(SW4, voltage);
+ register_mask = BITFMASK(SW4);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ register_val |= (hi << SWXHI_LSH);
+ register_mask |= (1 << SWXHI_LSH);
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_sw_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0;
+ int mV = 0;
+ int sw = rdev_get_id(reg);
+ int hi;
+
+ switch (sw) {
+ case MC13892_SW1:
+ CHECK_ERROR(pmic_read_reg(REG_SW_0,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW1);
+ break;
+ case MC13892_SW2:
+ CHECK_ERROR(pmic_read_reg(REG_SW_1,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW2);
+ break;
+ case MC13892_SW3:
+ CHECK_ERROR(pmic_read_reg(REG_SW_2,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW3);
+ break;
+ case MC13892_SW4:
+ CHECK_ERROR(pmic_read_reg(REG_SW_3,
+ &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, SW4);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ hi = mc13892_get_sw_hi_bit(sw);
+ mV = mc13892_get_voltage_mV(hi, voltage);
+
+ return mV * 1000;
+}
+
+static int mc13892_sw_stby_enable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int mc13892_sw_stby_disable(struct regulator_dev *reg)
+{
+ return 0;
+}
+
+static int mc13892_sw_stby_set_mode(struct regulator_dev *reg, unsigned int mode)
+{
+ return 0;
+}
+
+static int mc13892_sw_stby_set_voltage(struct regulator_dev *reg, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1 = 0;
+ int voltage, mV = uV / 1000, hi;
+ int sw = rdev_get_id(reg);
+
+ hi = mc13892_get_sw_hi_bit(sw);
+ voltage = mc13892_get_voltage_value(&hi, mV);
+
+ switch (sw) {
+ case MC13892_SW1:
+ register1 = REG_SW_0;
+ register_val = BITFVAL(SW1_STDBY, voltage);
+ register_mask = BITFMASK(SW1_STDBY);
+ break;
+ case MC13892_SW2:
+ register1 = REG_SW_1;
+ register_val = BITFVAL(SW2_STDBY, voltage);
+ register_mask = BITFMASK(SW2_STDBY);
+ break;
+ case MC13892_SW3:
+ register1 = REG_SW_2;
+ register_val = BITFVAL(SW3_STDBY, voltage);
+ register_mask = BITFMASK(SW3_STDBY);
+ break;
+ case MC13892_SW4:
+ register1 = REG_SW_3;
+ register_val = BITFVAL(SW4_STDBY, voltage);
+ register_mask = BITFMASK(SW4_STDBY);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ register_val |= (hi << SWXHI_LSH);
+ register_mask |= (1 << SWXHI_LSH);
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_swbst_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(SWBST_EN, SWBST_EN_ENABLE);
+ register_mask = BITFMASK(SWBST_EN);
+ register1 = REG_SW_5;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_swbst_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(SWBST_EN, SWBST_EN_DISABLE);
+ register_mask = BITFMASK(SWBST_EN);
+ register1 = REG_SW_5;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_viohi_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VIOHI_EN, VIOHI_EN_ENABLE);
+ register_mask = BITFMASK(VIOHI_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_viohi_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VIOHI_EN, VIOHI_EN_DISABLE);
+ register_mask = BITFMASK(VIOHI_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vusb_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VUSB_EN, VUSB_EN_ENABLE);
+ register_mask = BITFMASK(VUSB_EN);
+ register1 = REG_USB1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vusb_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VUSB_EN, VUSB_EN_DISABLE);
+ register_mask = BITFMASK(VUSB_EN);
+ register1 = REG_USB1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vdig_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1050) && (mV < 1250))
+ voltage = VDIG_1_05V;
+ else if ((mV >= 1250) && (mV < 1650))
+ voltage = VDIG_1_25V;
+ else if ((mV >= 1650) && (mV < 1800))
+ voltage = VDIG_1_65V;
+ else
+ voltage = VDIG_1_80V;
+
+ register_val = BITFVAL(VDIG, voltage);
+ register_mask = BITFMASK(VDIG);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vdig_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VDIG);
+
+ switch (voltage) {
+ case VDIG_1_05V:
+ mV = 1050;
+ break;
+ case VDIG_1_25V:
+ mV = 1250;
+ break;
+ case VDIG_1_65V:
+ mV = 1650;
+ break;
+ case VDIG_1_80V:
+ mV = 1800;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vdig_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VDIG_EN, VDIG_EN_ENABLE);
+ register_mask = BITFMASK(VDIG_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vdig_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VDIG_EN, VDIG_EN_DISABLE);
+ register_mask = BITFMASK(VDIG_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vpll_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1050) && (mV < 1250))
+ voltage = VPLL_1_05V;
+ else if ((mV >= 1250) && (mV < 1650))
+ voltage = VPLL_1_25V;
+ else if ((mV >= 1650) && (mV < 1800))
+ voltage = VPLL_1_65V;
+ else
+ voltage = VPLL_1_80V;
+
+ register_val = BITFVAL(VPLL, voltage);
+ register_mask = BITFMASK(VPLL);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vpll_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VPLL);
+
+ switch (voltage) {
+ case VPLL_1_05V:
+ mV = 1050;
+ break;
+ case VPLL_1_25V:
+ mV = 1250;
+ break;
+ case VPLL_1_65V:
+ mV = 1650;
+ break;
+ case VPLL_1_80V:
+ mV = 1800;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vpll_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VPLL_EN, VPLL_EN_ENABLE);
+ register_mask = BITFMASK(VPLL_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vpll_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VPLL_EN, VPLL_EN_DISABLE);
+ register_mask = BITFMASK(VPLL_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vaudio_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 2300) && (mV < 2500))
+ voltage = VAUDIO_2_3V;
+ else if ((mV >= 2500) && (mV < 2775))
+ voltage = VAUDIO_2_5V;
+ else if ((mV >= 2775) && (mV < 3000))
+ voltage = VAUDIO_2_775V;
+ else
+ voltage = VAUDIO_3V;
+
+ register_val = BITFVAL(VAUDIO, voltage);
+ register_mask = BITFMASK(VAUDIO);
+ register1 = REG_SETTING_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vaudio_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_1, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VAUDIO);
+
+ switch (voltage) {
+ case VAUDIO_2_3V:
+ mV = 2300;
+ break;
+ case VAUDIO_2_5V:
+ mV = 2500;
+ break;
+ case VAUDIO_2_775V:
+ mV = 2775;
+ break;
+ case VAUDIO_3V:
+ mV = 3000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vaudio_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VAUDIO_EN, VAUDIO_EN_ENABLE);
+ register_mask = BITFMASK(VAUDIO_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vaudio_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VAUDIO_EN, VAUDIO_EN_DISABLE);
+ register_mask = BITFMASK(VAUDIO_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vusb2_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 2400) && (mV < 2600))
+ voltage = VUSB2_2_4V;
+ else if ((mV >= 2600) && (mV < 2700))
+ voltage = VUSB2_2_6V;
+ else if ((mV >= 2700) && (mV < 2775))
+ voltage = VUSB2_2_7V;
+ else
+ voltage = VUSB2_2_775V;
+
+ register_val = BITFVAL(VUSB2, voltage);
+ register_mask = BITFMASK(VUSB2);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vusb2_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VUSB2);
+
+ switch (voltage) {
+ case VUSB2_2_4V:
+ mV = 2400;
+ break;
+ case VUSB2_2_6V:
+ mV = 2600;
+ break;
+ case VUSB2_2_7V:
+ mV = 2700;
+ break;
+ case VUSB2_2_775V:
+ mV = 2775;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vusb2_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VUSB2_EN, VUSB2_EN_ENABLE);
+ register_mask = BITFMASK(VUSB2_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vusb2_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VUSB2_EN, VUSB2_EN_DISABLE);
+ register_mask = BITFMASK(VUSB2_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vvideo_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 2500) && (mV < 2600))
+ voltage = VVIDEO_2_5V;
+ else if ((mV >= 2600) && (mV < 2700))
+ voltage = VVIDEO_2_6V;
+ else if ((mV >= 2700) && (mV < 2775))
+ voltage = VVIDEO_2_7V;
+ else
+ voltage = VVIDEO_2_775V;
+
+ register_val = BITFVAL(VVIDEO, voltage);
+ register_mask = BITFMASK(VVIDEO);
+ register1 = REG_SETTING_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vvideo_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_1, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VVIDEO);
+
+ switch (voltage) {
+ case VVIDEO_2_5V:
+ mV = 2500;
+ break;
+ case VVIDEO_2_6V:
+ mV = 2600;
+ break;
+ case VVIDEO_2_7V:
+ mV = 2700;
+ break;
+ case VVIDEO_2_775V:
+ mV = 2775;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vvideo_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VVIDEO_EN, VVIDEO_EN_ENABLE);
+ register_mask = BITFMASK(VVIDEO_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vvideo_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VVIDEO_EN, VVIDEO_EN_DISABLE);
+ register_mask = BITFMASK(VVIDEO_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vsd_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1800) && (mV < 2000))
+ voltage = VSD_1_8V;
+ else if ((mV >= 2000) && (mV < 2600))
+ voltage = VSD_2_0V;
+ else if ((mV >= 2600) && (mV < 2700))
+ voltage = VSD_2_6V;
+ else if ((mV >= 2700) && (mV < 2800))
+ voltage = VSD_2_7V;
+ else if ((mV >= 2800) && (mV < 2900))
+ voltage = VSD_2_8V;
+ else if ((mV >= 2900) && (mV < 3000))
+ voltage = VSD_2_9V;
+ else if ((mV >= 3000) && (mV < 3150))
+ voltage = VSD_3_0V;
+ else
+ voltage = VSD_3_15V;
+
+ register_val = BITFVAL(VSD, voltage);
+ register_mask = BITFMASK(VSD);
+ register1 = REG_SETTING_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vsd_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_1, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VSD);
+
+ switch (voltage) {
+ case VSD_1_8V:
+ mV = 1800;
+ break;
+ case VSD_2_0V:
+ mV = 2000;
+ break;
+ case VSD_2_6V:
+ mV = 2600;
+ break;
+ case VSD_2_7V:
+ mV = 2700;
+ break;
+ case VSD_2_8V:
+ mV = 2800;
+ break;
+ case VSD_2_9V:
+ mV = 2900;
+ break;
+ case VSD_3_0V:
+ mV = 3000;
+ break;
+ case VSD_3_15V:
+ mV = 3150;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vsd_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VSD_EN, VSD_EN_ENABLE);
+ register_mask = BITFMASK(VSD_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vsd_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VSD_EN, VSD_EN_DISABLE);
+ register_mask = BITFMASK(VSD_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vcam_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 2500) && (mV < 2600))
+ voltage = VCAM_2_5V;
+ else if ((mV >= 2600) && (mV < 2750))
+ voltage = VCAM_2_6V;
+ else if ((mV >= 2750) && (mV < 3000))
+ voltage = VCAM_2_75V;
+ else
+ voltage = VCAM_3_0V;
+
+ register_val = BITFVAL(VCAM, voltage);
+ register_mask = BITFMASK(VCAM);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vcam_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VCAM);
+
+ switch (voltage) {
+ case VCAM_2_5V:
+ mV = 2500;
+ break;
+ case VCAM_2_6V:
+ mV = 2600;
+ break;
+ case VCAM_2_75V:
+ mV = 2750;
+ break;
+ case VCAM_3_0V:
+ mV = 3000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vcam_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VCAM_EN, VCAM_EN_ENABLE);
+ register_mask = BITFMASK(VCAM_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vcam_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VCAM_EN, VCAM_EN_DISABLE);
+ register_mask = BITFMASK(VCAM_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vcam_set_mode(struct regulator_dev *reg, unsigned int mode)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ register_val = BITFVAL(VCAM_CONFIG, VCAM_CONFIG_EXT);
+ break;
+ case REGULATOR_MODE_NORMAL:
+ register_val = BITFVAL(VCAM_CONFIG, VCAM_CONFIG_INT);
+ break;
+ default:
+ return -EINVAL;
+ }
+ register_mask = BITFMASK(VCAM_CONFIG);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+unsigned int mc13892_vcam_get_mode(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int config = 0, mode = VCAM_CONFIG_INT;
+
+ CHECK_ERROR(pmic_read_reg(REG_MODE_1, &register_val, PMIC_ALL_BITS));
+ config = BITFEXT(register_val, VCAM_CONFIG);
+
+ switch (config) {
+ case VCAM_CONFIG_EXT:
+ mode = REGULATOR_MODE_FAST;
+ break;
+ case VCAM_CONFIG_INT:
+ mode = REGULATOR_MODE_NORMAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return mode;
+}
+
+static int mc13892_vgen1_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1200) && (mV < 1500))
+ voltage = VGEN1_1_2V;
+ else if ((mV >= 1500) && (mV < 2775))
+ voltage = VGEN1_1_5V;
+ else if ((mV >= 2775) && (mV < 3150))
+ voltage = VGEN1_2_775V;
+ else
+ voltage = VGEN1_3_15V;
+
+ register_val = BITFVAL(VGEN1, voltage);
+ register_mask = BITFMASK(VGEN1);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen1_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VGEN1);
+
+ switch (voltage) {
+ case VGEN1_1_2V:
+ mV = 1200;
+ break;
+ case VGEN1_1_5V:
+ mV = 1500;
+ break;
+ case VGEN1_2_775V:
+ mV = 2775;
+ break;
+ case VGEN1_3_15V:
+ mV = 3150;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vgen1_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN1_EN, VGEN1_EN_ENABLE);
+ register_mask = BITFMASK(VGEN1_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen1_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN1_EN, VGEN1_EN_DISABLE);
+ register_mask = BITFMASK(VGEN1_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen2_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1200) && (mV < 1500))
+ voltage = VGEN2_1_2V;
+ else if ((mV >= 1500) && (mV < 1600))
+ voltage = VGEN2_1_5V;
+ else if ((mV >= 1600) && (mV < 1800))
+ voltage = VGEN2_1_6V;
+ else if ((mV >= 1800) && (mV < 2700))
+ voltage = VGEN2_1_8V;
+ else if ((mV >= 2700) && (mV < 2800))
+ voltage = VGEN2_2_7V;
+ else if ((mV >= 2800) && (mV < 3000))
+ voltage = VGEN2_2_8V;
+ else if ((mV >= 3000) && (mV < 3150))
+ voltage = VGEN2_3_0V;
+ else
+ voltage = VGEN2_3_15V;
+
+ register_val = BITFVAL(VGEN2, voltage);
+ register_mask = BITFMASK(VGEN2);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen2_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VGEN2);
+
+ switch (voltage) {
+ case VGEN2_1_2V:
+ mV = 1200;
+ break;
+ case VGEN2_1_5V:
+ mV = 1500;
+ break;
+ case VGEN2_1_6V:
+ mV = 1600;
+ break;
+ case VGEN2_1_8V:
+ mV = 1800;
+ break;
+ case VGEN2_2_7V:
+ mV = 2700;
+ break;
+ case VGEN2_2_8V:
+ mV = 2800;
+ break;
+ case VGEN2_3_0V:
+ mV = 3000;
+ break;
+ case VGEN2_3_15V:
+ mV = 3150;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vgen2_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN2_EN, VGEN2_EN_ENABLE);
+ register_mask = BITFMASK(VGEN2_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen2_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN2_EN, VGEN2_EN_DISABLE);
+ register_mask = BITFMASK(VGEN2_EN);
+ register1 = REG_MODE_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen3_set_voltage(struct regulator_dev *reg,
+ int minuV, int uV)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int voltage, mV = uV / 1000;
+
+ if ((mV >= 1800) && (mV < 2900))
+ voltage = VGEN3_1_8V;
+ else
+ voltage = VGEN3_2_9V;
+
+ register_val = BITFVAL(VGEN3, voltage);
+ register_mask = BITFMASK(VGEN3);
+ register1 = REG_SETTING_0;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen3_get_voltage(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0;
+ int voltage = 0, mV = 0;
+
+ CHECK_ERROR(pmic_read_reg(REG_SETTING_0, &register_val, PMIC_ALL_BITS));
+ voltage = BITFEXT(register_val, VGEN3);
+
+ switch (voltage) {
+ case VGEN3_1_8V:
+ mV = 1800;
+ break;
+ case VGEN3_2_9V:
+ mV = 2900;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mV * 1000;
+}
+
+static int mc13892_vgen3_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN3_EN, VGEN3_EN_ENABLE);
+ register_mask = BITFMASK(VGEN3_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_vgen3_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+
+ register_val = BITFVAL(VGEN3_EN, VGEN3_EN_DISABLE);
+ register_mask = BITFMASK(VGEN3_EN);
+ register1 = REG_MODE_1;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_gpo_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int gpo = rdev_get_id(reg);
+
+ switch (gpo) {
+ case MC13892_GPO1:
+ register_val = BITFVAL(GPO1_EN, GPO1_EN_ENABLE);
+ register_mask = BITFMASK(GPO1_EN);
+ break;
+ case MC13892_GPO2:
+ register_val = BITFVAL(GPO2_EN, GPO2_EN_ENABLE);
+ register_mask = BITFMASK(GPO2_EN);
+ break;
+ case MC13892_GPO3:
+ register_val = BITFVAL(GPO3_EN, GPO3_EN_ENABLE);
+ register_mask = BITFMASK(GPO3_EN);
+ break;
+ case MC13892_GPO4:
+ register_val = BITFVAL(GPO4_EN, GPO4_EN_ENABLE) +
+ BITFVAL(GPO4_ADIN, GPO4_ADIN_DISABLE);
+ register_mask = BITFMASK(GPO4_EN) + BITFMASK(GPO4_ADIN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_POWER_MISC;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_gpo_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int gpo = rdev_get_id(reg);
+
+ switch (gpo) {
+ case MC13892_GPO1:
+ register_val = BITFVAL(GPO1_EN, GPO1_EN_DISABLE);
+ register_mask = BITFMASK(GPO1_EN);
+ break;
+ case MC13892_GPO2:
+ register_val = BITFVAL(GPO2_EN, GPO2_EN_DISABLE);
+ register_mask = BITFMASK(GPO2_EN);
+ break;
+ case MC13892_GPO3:
+ register_val = BITFVAL(GPO3_EN, GPO3_EN_DISABLE);
+ register_mask = BITFMASK(GPO3_EN);
+ break;
+ case MC13892_GPO4:
+ register_val = BITFVAL(GPO4_EN, GPO4_EN_DISABLE);
+ register_mask = BITFMASK(GPO4_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_POWER_MISC;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_power_gating_enable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int gpo = rdev_get_id(reg);
+
+ switch (gpo) {
+ case MC13892_PWGT1:
+ register_val = BITFVAL(PWGT1SPI_EN, PWGT1SPI_EN_ENABLE);
+ register_mask = BITFMASK(PWGT1SPI_EN);
+ break;
+ case MC13892_PWGT2:
+ register_val = BITFVAL(PWGT2SPI_EN, PWGT2SPI_EN_ENABLE);
+ register_mask = BITFMASK(PWGT2SPI_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_POWER_MISC;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static int mc13892_power_gating_disable(struct regulator_dev *reg)
+{
+ unsigned int register_val = 0, register_mask = 0;
+ unsigned int register1;
+ int gpo = rdev_get_id(reg);
+
+ switch (gpo) {
+ case MC13892_PWGT1:
+ register_val = BITFVAL(PWGT1SPI_EN, PWGT1SPI_EN_DISABLE);
+ register_mask = BITFMASK(PWGT1SPI_EN);
+ break;
+ case MC13892_PWGT2:
+ register_val = BITFVAL(PWGT2SPI_EN, PWGT2SPI_EN_DISABLE);
+ register_mask = BITFMASK(PWGT2SPI_EN);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ register1 = REG_POWER_MISC;
+
+ return pmic_write_reg(register1, register_val, register_mask);
+}
+
+static struct regulator_ops mc13892_sw_ops = {
+ .enable = mc13892_sw_stby_enable,
+ .disable = mc13892_sw_stby_disable,
+ .set_voltage = mc13892_sw_set_voltage,
+ .get_voltage = mc13892_sw_get_voltage,
+ .set_suspend_voltage = mc13892_sw_stby_set_voltage,
+ .set_suspend_enable = mc13892_sw_stby_enable,
+ .set_suspend_disable = mc13892_sw_stby_disable,
+ .set_suspend_mode = mc13892_sw_stby_set_mode,
+};
+
+static struct regulator_ops mc13892_swbst_ops = {
+ .enable = mc13892_swbst_enable,
+ .disable = mc13892_swbst_disable,
+};
+
+static struct regulator_ops mc13892_viohi_ops = {
+ .enable = mc13892_viohi_enable,
+ .disable = mc13892_viohi_disable,
+};
+
+static struct regulator_ops mc13892_vusb_ops = {
+ .enable = mc13892_vusb_enable,
+ .disable = mc13892_vusb_disable,
+};
+
+static struct regulator_ops mc13892_vdig_ops = {
+ .set_voltage = mc13892_vdig_set_voltage,
+ .get_voltage = mc13892_vdig_get_voltage,
+ .enable = mc13892_vdig_enable,
+ .disable = mc13892_vdig_disable,
+};
+
+static struct regulator_ops mc13892_vpll_ops = {
+ .set_voltage = mc13892_vpll_set_voltage,
+ .get_voltage = mc13892_vpll_get_voltage,
+ .enable = mc13892_vpll_enable,
+ .disable = mc13892_vpll_disable,
+};
+
+static struct regulator_ops mc13892_vusb2_ops = {
+ .set_voltage = mc13892_vusb2_set_voltage,
+ .get_voltage = mc13892_vusb2_get_voltage,
+ .enable = mc13892_vusb2_enable,
+ .disable = mc13892_vusb2_disable,
+};
+
+static struct regulator_ops mc13892_vvideo_ops = {
+ .set_voltage = mc13892_vvideo_set_voltage,
+ .get_voltage = mc13892_vvideo_get_voltage,
+ .enable = mc13892_vvideo_enable,
+ .disable = mc13892_vvideo_disable,
+};
+
+static struct regulator_ops mc13892_vaudio_ops = {
+ .set_voltage = mc13892_vaudio_set_voltage,
+ .get_voltage = mc13892_vaudio_get_voltage,
+ .enable = mc13892_vaudio_enable,
+ .disable = mc13892_vaudio_disable,
+};
+
+static struct regulator_ops mc13892_vsd_ops = {
+ .set_voltage = mc13892_vsd_set_voltage,
+ .get_voltage = mc13892_vsd_get_voltage,
+ .enable = mc13892_vsd_enable,
+ .disable = mc13892_vsd_disable,
+};
+
+static struct regulator_ops mc13892_vcam_ops = {
+ .set_voltage = mc13892_vcam_set_voltage,
+ .get_voltage = mc13892_vcam_get_voltage,
+ .enable = mc13892_vcam_enable,
+ .disable = mc13892_vcam_disable,
+ .set_mode = mc13892_vcam_set_mode,
+ .get_mode = mc13892_vcam_get_mode,
+};
+
+static struct regulator_ops mc13892_vgen1_ops = {
+ .set_voltage = mc13892_vgen1_set_voltage,
+ .get_voltage = mc13892_vgen1_get_voltage,
+ .enable = mc13892_vgen1_enable,
+ .disable = mc13892_vgen1_disable,
+};
+
+static struct regulator_ops mc13892_vgen2_ops = {
+ .set_voltage = mc13892_vgen2_set_voltage,
+ .get_voltage = mc13892_vgen2_get_voltage,
+ .enable = mc13892_vgen2_enable,
+ .disable = mc13892_vgen2_disable,
+};
+
+static struct regulator_ops mc13892_vgen3_ops = {
+ .set_voltage = mc13892_vgen3_set_voltage,
+ .get_voltage = mc13892_vgen3_get_voltage,
+ .enable = mc13892_vgen3_enable,
+ .disable = mc13892_vgen3_disable,
+};
+
+static struct regulator_ops mc13892_gpo_ops = {
+ .enable = mc13892_gpo_enable,
+ .disable = mc13892_gpo_disable,
+};
+
+static struct regulator_ops mc13892_power_gating_ops = {
+ .enable = mc13892_power_gating_enable,
+ .disable = mc13892_power_gating_disable,
+
+};
+
+static struct regulator_desc mc13892_reg[] = {
+ {
+ .name = "SW1",
+ .id = MC13892_SW1,
+ .ops = &mc13892_sw_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW2",
+ .id = MC13892_SW2,
+ .ops = &mc13892_sw_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW3",
+ .id = MC13892_SW3,
+ .ops = &mc13892_sw_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SW4",
+ .id = MC13892_SW4,
+ .ops = &mc13892_sw_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SWBST",
+ .id = MC13892_SWBST,
+ .ops = &mc13892_swbst_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VIOHI",
+ .id = MC13892_VIOHI,
+ .ops = &mc13892_viohi_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VPLL",
+ .id = MC13892_VPLL,
+ .ops = &mc13892_vpll_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VDIG",
+ .id = MC13892_VDIG,
+ .ops = &mc13892_vdig_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VSD",
+ .id = MC13892_VSD,
+ .ops = &mc13892_vsd_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VUSB2",
+ .id = MC13892_VUSB2,
+ .ops = &mc13892_vusb2_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VVIDEO",
+ .id = MC13892_VVIDEO,
+ .ops = &mc13892_vvideo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VAUDIO",
+ .id = MC13892_VAUDIO,
+ .ops = &mc13892_vaudio_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VCAM",
+ .id = MC13892_VCAM,
+ .ops = &mc13892_vcam_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VGEN1",
+ .id = MC13892_VGEN1,
+ .ops = &mc13892_vgen1_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VGEN2",
+ .id = MC13892_VGEN2,
+ .ops = &mc13892_vgen2_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VGEN3",
+ .id = MC13892_VGEN3,
+ .ops = &mc13892_vgen3_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "VUSB",
+ .id = MC13892_VUSB,
+ .ops = &mc13892_vusb_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO1",
+ .id = MC13892_GPO1,
+ .ops = &mc13892_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO2",
+ .id = MC13892_GPO2,
+ .ops = &mc13892_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO3",
+ .id = MC13892_GPO3,
+ .ops = &mc13892_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPO4",
+ .id = MC13892_GPO4,
+ .ops = &mc13892_gpo_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "PWGT1",
+ .id = MC13892_PWGT1,
+ .ops = &mc13892_power_gating_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "PWGT2",
+ .id = MC13892_PWGT2,
+ .ops = &mc13892_power_gating_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+};
+
+static int mc13892_regulator_probe(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev;
+
+ /* register regulator */
+ rdev = regulator_register(&mc13892_reg[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
+ dev_get_drvdata(&pdev->dev));
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ mc13892_reg[pdev->id].name);
+ return PTR_ERR(rdev);
+ }
+
+ return 0;
+}
+
+
+static int mc13892_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+
+ return 0;
+}
+
+int mc13892_register_regulator(struct mc13892 *mc13892, int reg,
+ struct regulator_init_data *initdata)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ if (mc13892->pmic.pdev[reg])
+ return -EBUSY;
+
+ pdev = platform_device_alloc("mc13892-regulatr", reg);
+ if (!pdev)
+ return -ENOMEM;
+
+ mc13892->pmic.pdev[reg] = pdev;
+
+ initdata->driver_data = mc13892;
+
+ pdev->dev.platform_data = initdata;
+ pdev->dev.parent = mc13892->dev;
+ platform_set_drvdata(pdev, mc13892);
+ ret = platform_device_add(pdev);
+
+ if (ret != 0) {
+ dev_err(mc13892->dev, "Failed to register regulator %d: %d\n",
+ reg, ret);
+ platform_device_del(pdev);
+ mc13892->pmic.pdev[reg] = NULL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mc13892_register_regulator);
+
+static struct platform_driver mc13892_regulator_driver = {
+ .probe = mc13892_regulator_probe,
+ .remove = mc13892_regulator_remove,
+ .driver = {
+ .name = "mc13892-regulatr",
+ },
+};
+
+static int __init mc13892_regulator_init(void)
+{
+ return platform_driver_register(&mc13892_regulator_driver);
+}
+subsys_initcall(mc13892_regulator_init);
+
+static void __exit mc13892_regulator_exit(void)
+{
+ platform_driver_unregister(&mc13892_regulator_driver);
+}
+module_exit(mc13892_regulator_exit);
+
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MC13892 Regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/reg-mc34704.c b/drivers/regulator/reg-mc34704.c
new file mode 100644
index 000000000000..ed134074fba3
--- /dev/null
+++ b/drivers/regulator/reg-mc34704.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/ioctl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/mc34704/core.h>
+#include <linux/platform_device.h>
+#include <linux/pmic_status.h>
+#include <linux/pmic_external.h>
+
+#define MC34704_ONOFFA 0x8
+#define MC34704_ONOFFC 0x4
+#define MC34704_ONOFFD 0x2
+#define MC34704_ONOFFE 0x1
+
+/* Private data for MC34704 regulators */
+
+struct reg_mc34704_priv {
+ short enable; /* enable bit, if available */
+ short v_default; /* default regulator voltage in mV */
+ int dvs_min; /* minimum voltage change in units of 2.5% */
+ int dvs_max; /* maximum voltage change in units of 2.5% */
+ char i2c_dvs; /* i2c DVS register number */
+ char i2c_stat; /* i2c status register number */
+};
+struct reg_mc34704_priv mc34704_reg_priv[] = {
+ {
+ .v_default = REG1_V_MV,
+ .dvs_min = REG1_DVS_MIN_PCT / 2.5,
+ .dvs_max = REG1_DVS_MAX_PCT / 2.5,
+ .i2c_dvs = 0x4,
+ .i2c_stat = 0x5,
+ .enable = MC34704_ONOFFA,
+ },
+ {
+ .v_default = REG2_V_MV,
+ .dvs_min = REG2_DVS_MIN_PCT / 2.5,
+ .dvs_max = REG2_DVS_MAX_PCT / 2.5,
+ .i2c_dvs = 0x6,
+ .i2c_stat = 0x7,
+ },
+ {
+ .v_default = REG3_V_MV,
+ .dvs_min = REG3_DVS_MIN_PCT / 2.5,
+ .dvs_max = REG3_DVS_MAX_PCT / 2.5,
+ .i2c_dvs = 0x8,
+ .i2c_stat = 0x9,
+ },
+ {
+ .v_default = REG4_V_MV,
+ .dvs_min = REG4_DVS_MIN_PCT / 2.5,
+ .dvs_max = REG4_DVS_MAX_PCT / 2.5,
+ .i2c_dvs = 0xA,
+ .i2c_stat = 0xB,
+ },
+ {
+ .v_default = REG5_V_MV,
+ .dvs_min = REG5_DVS_MIN_PCT / 2.5,
+ .dvs_max = REG5_DVS_MAX_PCT / 2.5,
+ .i2c_dvs = 0xC,
+ .i2c_stat = 0xE,
+ .enable = MC34704_ONOFFE,
+ },
+};
+
+static int mc34704_set_voltage(struct regulator_dev *reg, int MiniV, int uV)
+{
+ struct reg_mc34704_priv *priv = rdev_get_drvdata(reg);
+ int mV = uV / 1000;
+ int dV = mV - priv->v_default;
+
+ /* compute dynamic voltage scaling value */
+ int dvs = 1000 * dV / priv->v_default / 25;
+
+ /* clip to regulator limits */
+ if (dvs > priv->dvs_max)
+ dvs = priv->dvs_max;
+ if (dvs < priv->dvs_min)
+ dvs = priv->dvs_min;
+
+ return pmic_write_reg(priv->i2c_dvs, dvs << 1, 0x1E);
+}
+
+static int mc34704_get_voltage(struct regulator_dev *reg)
+{
+ int mV;
+ struct reg_mc34704_priv *priv = rdev_get_drvdata(reg);
+ int val, dvs;
+
+ CHECK_ERROR(pmic_read_reg(priv->i2c_dvs, &val, 0xF));
+
+ dvs = (val >> 1) & 0xF;
+
+ /* dvs is 4-bit 2's complement; sign-extend it */
+ if (dvs & 8)
+ dvs |= -1 & ~0xF;
+
+ /* Regulator voltage is adjusted by (dvs * 2.5%) */
+ mV = priv->v_default * (1000 + 25 * dvs) / 1000;
+
+ return 1000 * mV;
+}
+
+static int mc34704_enable_reg(struct regulator_dev *reg)
+{
+ struct reg_mc34704_priv *priv = rdev_get_drvdata(reg);
+
+ if (priv->enable)
+ return pmic_write_reg(REG_MC34704_GENERAL2, -1, priv->enable);
+
+ return PMIC_ERROR;
+}
+
+static int mc34704_disable_reg(struct regulator_dev *reg)
+{
+ struct reg_mc34704_priv *priv = rdev_get_drvdata(reg);
+
+ if (priv->enable)
+ return pmic_write_reg(REG_MC34704_GENERAL2, 0, priv->enable);
+
+ return PMIC_ERROR;
+}
+
+static int mc34704_is_reg_enabled(struct regulator_dev *reg)
+{
+ struct reg_mc34704_priv *priv = rdev_get_drvdata(reg);
+ int val;
+
+ if (priv->enable) {
+ CHECK_ERROR(pmic_read_reg(REG_MC34704_GENERAL2, &val,
+ priv->enable));
+ return val ? 1 : 0;
+ } else {
+ return PMIC_ERROR;
+ }
+}
+
+static struct regulator_ops mc34704_full_ops = {
+ .set_voltage = mc34704_set_voltage,
+ .get_voltage = mc34704_get_voltage,
+ .enable = mc34704_enable_reg,
+ .disable = mc34704_disable_reg,
+ .is_enabled = mc34704_is_reg_enabled,
+};
+
+static struct regulator_ops mc34704_partial_ops = {
+ .set_voltage = mc34704_set_voltage,
+ .get_voltage = mc34704_get_voltage,
+};
+
+static struct regulator_desc reg_mc34704[] = {
+ {
+ .name = "REG1_BKLT",
+ .id = MC34704_BKLT,
+ .ops = &mc34704_full_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE},
+ {
+ .name = "REG2_CPU",
+ .id = MC34704_CPU,
+ .ops = &mc34704_partial_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE},
+ {
+ .name = "REG3_CORE",
+ .id = MC34704_CORE,
+ .ops = &mc34704_partial_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE},
+ {
+ .name = "REG4_DDR",
+ .id = MC34704_DDR,
+ .ops = &mc34704_partial_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE},
+ {
+ .name = "REG5_PERS",
+ .id = MC34704_PERS,
+ .ops = &mc34704_full_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE},
+};
+
+static int mc34704_regulator_probe(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev;
+
+ /* register regulator */
+ rdev = regulator_register(&reg_mc34704[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
+ (void *)&mc34704_reg_priv[pdev->id]);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ reg_mc34704[pdev->id].name);
+ return PTR_ERR(rdev);
+ }
+
+ return 0;
+}
+
+static int mc34704_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+
+ return 0;
+}
+
+int mc34704_register_regulator(struct mc34704 *mc34704, int reg,
+ struct regulator_init_data *initdata)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ if (mc34704->pmic.pdev[reg])
+ return -EBUSY;
+
+ pdev = platform_device_alloc("mc34704-regulatr", reg);
+ if (!pdev)
+ return -ENOMEM;
+
+ mc34704->pmic.pdev[reg] = pdev;
+
+ initdata->driver_data = mc34704;
+
+ pdev->dev.platform_data = initdata;
+ pdev->dev.driver_data = &mc34704_reg_priv[reg];
+ pdev->dev.parent = mc34704->dev;
+ platform_set_drvdata(pdev, mc34704);
+ ret = platform_device_add(pdev);
+
+ if (ret != 0) {
+ dev_err(mc34704->dev, "Failed to register regulator %d: %d\n",
+ reg, ret);
+ platform_device_del(pdev);
+ mc34704->pmic.pdev[reg] = NULL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mc34704_register_regulator);
+
+static struct platform_driver mc34704_regulator_driver = {
+ .probe = mc34704_regulator_probe,
+ .remove = mc34704_regulator_remove,
+ .driver = {
+ .name = "mc34704-regulatr",
+ },
+};
+
+static int __init mc34704_regulator_init(void)
+{
+ return platform_driver_register(&mc34704_regulator_driver);
+}
+subsys_initcall(mc34704_regulator_init);
+
+static void __exit mc34704_regulator_exit(void)
+{
+ platform_driver_unregister(&mc34704_regulator_driver);
+}
+module_exit(mc34704_regulator_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MC34704 Regulator Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/reg-mc9s08dz60.c b/drivers/regulator/reg-mc9s08dz60.c
new file mode 100644
index 000000000000..f2748e99fd80
--- /dev/null
+++ b/drivers/regulator/reg-mc9s08dz60.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/mc9s08dz60/core.h>
+#include <linux/mfd/mc9s08dz60/pmic.h>
+#include <linux/platform_device.h>
+#include <linux/pmic_status.h>
+
+/* lcd */
+static int mc9s08dz60_lcd_enable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 6, 1);
+}
+
+static int mc9s08dz60_lcd_disable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 6, 0);
+}
+
+static struct regulator_ops mc9s08dz60_lcd_ops = {
+ .enable = mc9s08dz60_lcd_enable,
+ .disable = mc9s08dz60_lcd_disable,
+};
+
+/* wifi */
+static int mc9s08dz60_wifi_enable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 5, 1);
+}
+
+static int mc9s08dz60_wifi_disable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 5, 0);
+}
+
+static struct regulator_ops mc9s08dz60_wifi_ops = {
+ .enable = mc9s08dz60_wifi_enable,
+ .disable = mc9s08dz60_wifi_disable,
+};
+
+/* hdd */
+static int mc9s08dz60_hdd_enable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 4, 1);
+}
+
+static int mc9s08dz60_hdd_disable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 4, 0);
+}
+
+static struct regulator_ops mc9s08dz60_hdd_ops = {
+ .enable = mc9s08dz60_hdd_enable,
+ .disable = mc9s08dz60_hdd_disable,
+};
+
+/* gps */
+static int mc9s08dz60_gps_enable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 0, 1);
+}
+
+static int mc9s08dz60_gps_disable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 0, 0);
+}
+
+static struct regulator_ops mc9s08dz60_gps_ops = {
+ .enable = mc9s08dz60_gps_enable,
+ .disable = mc9s08dz60_gps_disable,
+};
+
+/* speaker */
+static int mc9s08dz60_speaker_enable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 0, 1);
+}
+
+static int mc9s08dz60_speaker_disable(struct regulator_dev *reg)
+{
+ return pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 0, 0);
+}
+
+static struct regulator_ops mc9s08dz60_speaker_ops = {
+ .enable = mc9s08dz60_speaker_enable,
+ .disable = mc9s08dz60_speaker_disable,
+};
+
+static struct regulator_desc mc9s08dz60_reg[] = {
+ {
+ .name = "LCD",
+ .id = MC9S08DZ60_LCD,
+ .ops = &mc9s08dz60_lcd_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "WIFI",
+ .id = MC9S08DZ60_WIFI,
+ .ops = &mc9s08dz60_wifi_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "HDD",
+ .id = MC9S08DZ60_HDD,
+ .ops = &mc9s08dz60_hdd_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "GPS",
+ .id = MC9S08DZ60_GPS,
+ .ops = &mc9s08dz60_gps_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+ {
+ .name = "SPKR",
+ .id = MC9S08DZ60_SPKR,
+ .ops = &mc9s08dz60_speaker_ops,
+ .irq = 0,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE
+ },
+
+};
+
+static int mc9s08dz60_regulator_probe(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev;
+
+ /* register regulator */
+ rdev = regulator_register(&mc9s08dz60_reg[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
+ dev_get_drvdata(&pdev->dev));
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ mc9s08dz60_reg[pdev->id].name);
+ return PTR_ERR(rdev);
+ }
+
+ return 0;
+}
+
+
+static int mc9s08dz60_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+
+ return 0;
+}
+
+int mc9s08dz60_register_regulator(struct mc9s08dz60 *mc9s08dz60, int reg,
+ struct regulator_init_data *initdata)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ if (mc9s08dz60->pmic.pdev[reg])
+ return -EBUSY;
+
+ pdev = platform_device_alloc("mc9s08dz60-regu", reg);
+ if (!pdev)
+ return -ENOMEM;
+
+ mc9s08dz60->pmic.pdev[reg] = pdev;
+
+ initdata->driver_data = mc9s08dz60;
+
+ pdev->dev.platform_data = initdata;
+ pdev->dev.parent = mc9s08dz60->dev;
+ platform_set_drvdata(pdev, mc9s08dz60);
+ ret = platform_device_add(pdev);
+
+ if (ret != 0) {
+ dev_err(mc9s08dz60->dev,
+ "Failed to register regulator %d: %d\n",
+ reg, ret);
+ platform_device_del(pdev);
+ mc9s08dz60->pmic.pdev[reg] = NULL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mc9s08dz60_register_regulator);
+
+static struct platform_driver mc9s08dz60_regulator_driver = {
+ .probe = mc9s08dz60_regulator_probe,
+ .remove = mc9s08dz60_regulator_remove,
+ .driver = {
+ .name = "mc9s08dz60-regu",
+ },
+};
+
+static int __init mc9s08dz60_regulator_init(void)
+{
+ return platform_driver_register(&mc9s08dz60_regulator_driver);
+}
+subsys_initcall(mc9s08dz60_regulator_init);
+
+static void __exit mc9s08dz60_regulator_exit(void)
+{
+ platform_driver_unregister(&mc9s08dz60_regulator_driver);
+}
+module_exit(mc9s08dz60_regulator_exit);
+
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MC9S08DZ60 Regulator driver");
+MODULE_LICENSE("GPL");