diff options
author | Dinh Nguyen <Dinh.Nguyen@freescale.com> | 2010-08-17 16:46:40 -0500 |
---|---|---|
committer | Dinh Nguyen <Dinh.Nguyen@freescale.com> | 2010-09-01 10:42:59 -0500 |
commit | 3eb9039c5392abaabd96d08c0006ea4066346a60 (patch) | |
tree | 1b23d62933572db70a4aef7476a07e73f75e43d1 /drivers/regulator | |
parent | 4dcb1e4f577f7331930301798da548447208f35a (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/Kconfig | 25 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 10 | ||||
-rw-r--r-- | drivers/regulator/core.c | 5 | ||||
-rw-r--r-- | drivers/regulator/max17135-regulator.c | 736 | ||||
-rw-r--r-- | drivers/regulator/mxs-regulator.c | 302 | ||||
-rw-r--r-- | drivers/regulator/reg-mc13783.c | 2662 | ||||
-rw-r--r-- | drivers/regulator/reg-mc13892.c | 1850 | ||||
-rw-r--r-- | drivers/regulator/reg-mc34704.c | 289 | ||||
-rw-r--r-- | drivers/regulator/reg-mc9s08dz60.c | 236 |
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, ®ulator_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_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, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW1A); + break; + case MC13783_SW1B: + CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_1, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW1B); + break; + case MC13783_SW2A: + CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_2, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW2A); + break; + case MC13783_SW2B: + CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_3, + ®ister_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, ®_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(®_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, ®ister_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, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW1); + break; + case MC13892_SW2: + CHECK_ERROR(pmic_read_reg(REG_SW_1, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW2); + break; + case MC13892_SW3: + CHECK_ERROR(pmic_read_reg(REG_SW_2, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW3); + break; + case MC13892_SW4: + CHECK_ERROR(pmic_read_reg(REG_SW_3, + ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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(®_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"); |