]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00170255-3 MX6Q PFUZE100: add regulator driver of pfuze100
authorRobin Gong <B38343@freescale.com>
Mon, 19 Dec 2011 10:09:25 +0000 (18:09 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:41 +0000 (08:33 +0200)
add new regulator driver for pfuze100 based on mfd structure

Signed-off-by: Robin Gong <B38343@freescale.com>
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/pfuze-regulator.h [new file with mode: 0644]
drivers/regulator/pfuze100-regulator.c [new file with mode: 0644]

index f996525305edc693bc079b9cef1eba17dbae666d..8ba178f0d8ee941d501aa743adb7e14882de8e78 100755 (executable)
@@ -220,7 +220,12 @@ config REGULATOR_MC34708
        help
          Say y here to support the regulators found on the Freescale MC34708
          PMIC.
-
+config REGULATOR_PFUZE100
+       tristate "Support regulators on Freescale PFUZE100 PMIC"
+       depends on MFD_PFUZE
+       help
+       Say y here to support the regulators found on the Freescale PFUZE100
+         PMIC.
 config REGULATOR_AB3100
        tristate "ST-Ericsson AB3100 Regulator functions"
        depends on AB3100_CORE
index ed0c60604da0a8db12597779d57998c20d126c2e..dc7496cbe78a3559f95db7ae969ea2fbf4e698af 100755 (executable)
@@ -35,6 +35,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_MC34708) += mc34708-regulator.o
+obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
 obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
diff --git a/drivers/regulator/pfuze-regulator.h b/drivers/regulator/pfuze-regulator.h
new file mode 100644 (file)
index 0000000..0ce1c8b
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+#ifndef __LINUX_REGULATOR_PFUZE_H
+#define __LINUX_REGULATOR_PFUZE_H
+
+#include <linux/regulator/driver.h>
+
+struct pfuze_regulator {
+       struct regulator_desc desc;
+       unsigned int reg;
+       unsigned char enable_bit;
+       unsigned char vsel_shift;
+       unsigned char vsel_mask;
+       int const *voltages;
+};
+
+struct pfuze_regulator_priv {
+       struct mc_pfuze *pfuze;
+       struct pfuze_regulator *pfuze_regulators;
+       struct regulator_dev *regulators[];
+};
+
+#define PFUZE_DEFINE(prefix, _name, _reg, _voltages, _ops)     \
+       [prefix ## _name] = {                           \
+               .desc = {                                               \
+                       .name = #prefix "_" #_name,                     \
+                       .n_voltages = ARRAY_SIZE(_voltages),            \
+                       .ops = &_ops,                   \
+                       .type = REGULATOR_VOLTAGE,                      \
+                       .id = prefix ## _name,          \
+                       .owner = THIS_MODULE,                           \
+               },                                                      \
+               .reg = prefix ## _reg,                          \
+               .enable_bit = prefix ## _reg ## _ ## EN,        \
+               .vsel_shift = prefix ## _reg ## _ ## VSEL,\
+               .vsel_mask = prefix ## _reg ## _ ## VSEL_M,\
+               .voltages =  _voltages,                                 \
+       }
+#define PFUZE_SW_DEFINE(prefix, _name, _reg, _voltages, _ops)  \
+       [prefix ## _name] = {                           \
+               .desc = {                                               \
+                       .name = #prefix "_" #_name,                     \
+                       .n_voltages = ARRAY_SIZE(_voltages),            \
+                       .ops = &_ops,                   \
+                       .type = REGULATOR_VOLTAGE,                      \
+                       .id = prefix ## _name,          \
+                       .owner = THIS_MODULE,                           \
+               },                                                      \
+               .reg = prefix ## _reg,                          \
+               .vsel_shift = prefix ## _reg ## _ ## VSEL,\
+               .vsel_mask = prefix ## _reg ## _ ## VSEL_M,\
+               .voltages =  _voltages,                                 \
+       }
+
+#define PFUZE_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops)       \
+       [prefix ## _name] = {                           \
+               .desc = {                                               \
+                       .name = #prefix "_" #_name,                     \
+                       .n_voltages = ARRAY_SIZE(_voltages),            \
+                       .ops = &_ops,           \
+                       .type = REGULATOR_VOLTAGE,                      \
+                       .id = prefix ## _name,          \
+                       .owner = THIS_MODULE,                           \
+               },                                                      \
+               .reg = prefix ## _reg,                          \
+               .enable_bit = prefix ## _reg ## _ ## EN,        \
+               .voltages =  _voltages,                                 \
+       }
+
+#endif
+
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
new file mode 100644 (file)
index 0000000..afa24ab
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * Copyright (C) 2011 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+#include <linux/mfd/pfuze.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include "pfuze-regulator.h"
+
+static const int pfuze100_sw1[] = {
+#ifdef PFUZE100_FIRST_VERSION
+       650000, 662500, 675000, 687500, 700000, 712500, 725000, 737500,
+       750000, 762500, 775000, 787500, 800000, 812500, 825000, 837500,
+       850000, 862500, 875000, 887500, 900000, 912500, 925000, 937500,
+       950000, 962500, 975000, 987500, 1000000, 1012500, 1025000, 1037500,
+       1050000, 1062500, 1075000, 1087500, 1100000, 1112500, 1125000, 1137500,
+       1150000, 1162500, 1175000, 1187500, 1200000, 1212500, 1225000, 1237500,
+       1250000, 1262500, 1275000, 1287500, 1300000, 1312500, 1325000, 1337500,
+       1350000, 1362500, 1375000, 1387500, 1400000, 1412500, 1425000, 1437500,
+#else
+       300000, 325000, 350000, 375000, 400000, 425000, 450000, 475000,
+       500000, 525000, 550000, 575000, 600000, 625000, 650000, 675000,
+       700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000,
+       900000, 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000,
+       1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000,
+       1300000, 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000,
+       1500000, 1525000, 1550000, 1575000, 1600000, 1625000, 1650000, 1675000,
+       1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000,
+#endif
+};
+
+#if  PFUZE100_SW2_VOL6
+static const int pfuze100_sw2[] = {
+       800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
+       1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
+       1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
+       2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
+       2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
+       2800000, 2850000, 2900000, 2950000, 3000000, 3050000, 3100000, 3150000,
+       3200000, 3250000, 3300000, 3300000, 3300000, 3300000, 3300000, 3300000,
+       3300000, 3300000, 3300000, 3300000, 3300000, 3300000, 3300000, 3950000,
+};
+#else
+static const int pfuze100_sw2[] = {
+       400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
+       600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
+       800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
+       1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
+       1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
+       1400000, 1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000,
+       1600000, 1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000,
+       1800000, 1825000, 1850000, 1875000, 1900000, 1925000, 1950000, 1975000,
+};
+#endif
+
+#if PFUZE100_SW3_VOL6
+static const int pfuze100_sw3[] = {
+       800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
+       1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
+       1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
+       2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
+       2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
+       2800000, 2850000, 2900000, 2950000, 3000000, 3050000, 3100000, 3150000,
+       3200000, 3250000, 3300000, 3300000, 3300000, 3300000, 3300000, 3300000,
+       3300000, 3300000, 3300000, 3750000, 3800000, 3850000, 3900000, 3950000,
+};
+#else
+static const int pfuze100_sw3[] = {
+       400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
+       600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
+       800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
+       1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
+       1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
+       1400000, 1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000,
+       1600000, 1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000,
+       1800000, 1825000, 1850000, 1875000, 1900000, 1925000, 1950000, 1975000,
+};
+#endif
+
+#if PFUZE100_SW4_VOL6
+static const int pfuze100_sw4[] = {
+       800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
+       1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
+       1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
+       2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
+       2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
+       2800000, 2850000, 2900000, 2950000, 3000000, 3050000, 3100000, 3150000,
+       3200000, 3250000, 3300000, 3300000, 3300000, 3300000, 3300000, 3300000,
+       3300000, 3300000, 3300000, 3300000, 3300000, 3300000, 3300000, 3950000,
+};
+
+#else
+static const int pfuze100_sw4[] = {
+       400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000,
+       600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000,
+       800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000,
+       1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
+       1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
+       1400000, 1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000,
+       1600000, 1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000,
+       1800000, 1825000, 1850000, 1875000, 1900000, 1925000, 1950000, 1975000,
+};
+#endif
+
+static const int pfuze100_swbst[] = {
+       5000000, 5050000, 5100000, 5150000,
+};
+
+static const int pfuze100_vsnvs[] = {
+       1200000, 1500000, 1800000, 3000000,
+};
+
+static const int pfuze100_vrefddr[] = {
+       750000,
+};
+
+static const int pfuze100_vgen12[] = {
+
+#ifdef PFUZE100_FIRST_VERSION
+       1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
+#else
+       800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000,
+       1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
+#endif
+};
+
+static const int pfuze100_vgen36[] = {
+       1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
+       2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
+};
+
+static struct regulator_ops pfuze100_ldo_regulator_ops;
+static struct regulator_ops pfuze100_fixed_regulator_ops;
+static struct regulator_ops pfuze100_sw_regulator_ops;
+
+#define PFUZE100_FIXED_VOL_DEFINE(name,        reg, voltages)          \
+       PFUZE_FIXED_DEFINE(PFUZE100_, name, reg, voltages,      \
+                       pfuze100_fixed_regulator_ops)
+
+#define PFUZE100_SW_DEFINE(name, reg, voltages)        \
+       PFUZE_SW_DEFINE(PFUZE100_, name, reg, voltages, \
+                       pfuze100_sw_regulator_ops)
+
+#define PFUZE100_VGEN_DEFINE(name, reg, voltages)      \
+       PFUZE_DEFINE(PFUZE100_, name, reg, voltages,    \
+                       pfuze100_ldo_regulator_ops)
+/* SW1A */
+#define PFUZE100_SW1AVOL       32
+#define PFUZE100_SW1AVOL_VSEL  0
+#define PFUZE100_SW1AVOL_VSEL_M        (0x3f<<0)
+
+#define PFUZE100_SW1ASTANDBY   33
+#define PFUZE100_SW1ASTANDBY_STBY_VAL  (0x0)
+#define PFUZE100_SW1ASTANDBY_STBY_M    (0x3f<<0)
+
+#define PFUZE100_SW1AOFF       34
+#define PFUZE100_SW1AOFF_OFF_VAL       (0x0<<0)
+#define PFUZE100_SW1AOFF_OFF_M (0x3f<<0)
+
+#define PFUZE100_SW1AMODE      35
+#define PFUZE100_SW1AMODE_OMODE_VAL    (0x0<<5)
+#define PFUZE100_SW1AMODE_OMODE_M      (0x1<<5)
+#define PFUZE100_SW1AMODE_MODE_VAL     0x7     /*Auto */
+#define PFUZE100_SW1AMODE_MODE_M       (0xf<<0)
+
+#define PFUZE100_SW1ACON               36
+#define PFUZE100_SW1ACON_SPEED_VAL     (0x1<<6)        /*default */
+#define PFUZE100_SW1ACON_SPEED_M       (0x3<<6)
+#define PFUZE100_SW1ACON_PHASE_VAL     (0x1<<4)        /*default */
+#define PFUZE100_SW1ACON_PHASE_M       (0x3<<4)
+#define PFUZE100_SW1ACON_FREQ_VAL      (0x1<<2)        /*1Mhz */
+#define PFUZE100_SW1ACON_FREQ_M        (0x3<<2)
+#define PFUZE100_SW1ACON_LIM_VAL       (0x0<<0)        /*2Imax */
+#define PFUZE100_SW1ACON_LIM_M (0x3<<0)
+
+/*SW1B*/
+#define PFUZE100_SW1BVOL       39
+#define PFUZE100_SW1BVOL_VSEL  0
+#define PFUZE100_SW1BVOL_VSEL_M        (0x3f<<0)
+
+#define PFUZE100_SW1BSTANDBY   40
+#define PFUZE100_SW1BSTANDBY_STBY_VAL  0x0
+#define PFUZE100_SW1BSTANDBY_STBY_M    (0x3f<<0)
+
+#define PFUZE100_SW1BOFF       41
+#define PFUZE100_SW1BOFF_OFF_VAL       0x0
+#define PFUZE100_SW1BOFF_OFF_M (0x3f<<0)
+
+#define PFUZE100_SW1BMODE      42
+#define PFUZE100_SW1BMODE_OMODE_VAL    (0x0<<5)
+#define PFUZE100_SW1BMODE_OMODE_M      (0x1<<5)
+#define PFUZE100_SW1BMODE_MODE_VAL     (0x7<<0)
+#define PFUZE100_SW1BMODE_MODE_M       (0xf<<0)
+
+#define PFUZE100_SW1BCON               43
+#define PFUZE100_SW1BCON_SPEED_VAL     (0x1<<6)
+#define PFUZE100_SW1BCON_SPEED_M       (0x3<<6)
+#define PFUZE100_SW1BCON_PHASE_VAL     (0x1<<4)
+#define PFUZE100_SW1BCON_PHASE_M       (0x3<<4)
+#define PFUZE100_SW1BCON_FREQ_VAL      (0x1<<2)
+#define PFUZE100_SW1BCON_FREQ_M        (0x3<<2)
+#define PFUZE100_SW1BCON_LIM_VAL       (0x0<<0)
+#define PFUZE100_SW1BCON_LIM_M (0x3<<0)
+
+/*SW1C*/
+#define PFUZE100_SW1CVOL       46
+#define PFUZE100_SW1CVOL_VSEL  0
+#define PFUZE100_SW1CVOL_VSEL_M        (0x3f<<0)
+
+#define PFUZE100_SW1CSTANDBY   47
+#define PFUZE100_SW1CSTANDBY_STBY_VAL  0x0
+#define PFUZE100_SW1CSTANDBY_STBY_M    (0x3f<<0)
+
+#define PFUZE100_SW1COFF       48
+#define PFUZE100_SW1COFF_OFF_VAL       0x0
+#define PFUZE100_SW1COFF_OFF_M (0x3f<<0)
+
+#define PFUZE100_SW1CMODE      49
+#define PFUZE100_SW1CMODE_OMODE_VAL    (0x0<<5)
+#define PFUZE100_SW1CMODE_OMODE_M      (0x1<<5)
+#define PFUZE100_SW1CMODE_MODE_VAL     (0x7<<0)
+#define PFUZE100_SW1CMODE_MODE_M       (0xf<<0)
+
+#define PFUZE100_SW1CCON               50
+#define PFUZE100_SW1CCON_SPEED_VAL     (0x1<<6)
+#define PFUZE100_SW1CCON_SPEED_M       (0x3<<6)
+#define PFUZE100_SW1CCON_PHASE_VAL     (0x1<<4)
+#define PFUZE100_SW1CCON_PHASE_M       (0x3<<4)
+#define PFUZE100_SW1CCON_FREQ_VAL      (0x1<<2)
+#define PFUZE100_SW1CCON_FREQ_M                (0x3<<2)
+#define PFUZE100_SW1CCON_LIM_VAL       (0x0<<0)
+#define PFUZE100_SW1CCON_LIM_M         (0x3<<0)
+
+/*SW2*/
+#define PFUZE100_SW2VOL                53
+#define PFUZE100_SW2VOL_VSEL   0
+#define PFUZE100_SW2VOL_VSEL_M (0x3f<<0)
+
+#define PFUZE100_SW2STANDBY    54
+#define PFUZE100_SW2STANDBY_STBY_VAL   0x0
+#define PFUZE100_SW2STANDBY_STBY_M     (0x3f<<0)
+
+#define PFUZE100_SW2OFF        55
+#define PFUZE100_SW2OFF_OFF_VAL        0x0
+#define PFUZE100_SW2OFF_OFF_M  (0x7f<<0)
+
+#define PFUZE100_SW2MODE       56
+#define PFUZE100_SW2MODE_OMODE_VAL     (0x0<<5)
+#define PFUZE100_SW2MODE_OMODE_M       (0x1<<5)
+#define PFUZE100_SW2MODE_MODE_VAL      (0x7<<0)
+#define PFUZE100_SW2MODE_MODE_M                (0xf<<0)
+
+#define PFUZE100_SW2CON                57
+#define PFUZE100_SW2CON_SPEED_VAL      (0x1<<6)
+#define PFUZE100_SW2CON_SPEED_M                (0x3<<6)
+#define PFUZE100_SW2CON_PHASE_VAL      (0x1<<4)
+#define PFUZE100_SW2CON_PHASE_M                (0x3<<4)
+#define PFUZE100_SW2CON_FREQ_VAL       (0x1<<2)
+#define PFUZE100_SW2CON_FREQ_M         (0x3<<2)
+#define PFUZE100_SW2CON_LIM_VAL                (0x0<<0)
+#define PFUZE100_SW2CON_LIM_M          (0x3<<0)
+
+/*SW3A*/
+#define PFUZE100_SW3AVOL       60
+#define PFUZE100_SW3AVOL_VSEL  0
+#define PFUZE100_SW3AVOL_VSEL_M        (0x3f<<0)
+
+#define PFUZE100_SW3ASTANDBY   61
+#define PFUZE100_SW3ASTANDBY_STBY_VAL  0x0
+#define PFUZE100_SW3ASTANDBY_STBY_M    (0x3f<<0)
+
+#define PFUZE100_SW3AOFF       62
+#define PFUZE100_SW3AOFF_OFF_VAL       0x0
+#define PFUZE100_SW3AOFF_OFF_M (0x3f<<0)
+
+#define PFUZE100_SW3AMODE      63
+#define PFUZE100_SW3AMODE_OMODE_VAL    (0x0<<5)
+#define PFUZE100_SW3AMODE_OMODE_M      (0x1<<5)
+#define PFUZE100_SW3AMODE_MODE_VAL     (0x7<<0)
+#define PFUZE100_SW3AMODE_MODE_M       (0xf<<0)
+
+#define PFUZE100_SW3ACON               64
+#define PFUZE100_SW3ACON_SPEED_VAL     (0x1<<6)
+#define PFUZE100_SW3ACON_SPEED_M       (0x3<<6)
+#define PFUZE100_SW3ACON_PHASE_VAL     (0x1<<4)
+#define PFUZE100_SW3ACON_PHASE_M       (0x3<<4)
+#define PFUZE100_SW3ACON_FREQ_VAL      (0x1<<2)
+#define PFUZE100_SW3ACON_FREQ_M                (0x3<<2)
+#define PFUZE100_SW3ACON_LIM_VAL       (0x0<<0)
+#define PFUZE100_SW3ACON_LIM_M         (0x3<<0)
+
+/*SW3B*/
+#define PFUZE100_SW3BVOL       67
+#define PFUZE100_SW3BVOL_VSEL  0
+#define PFUZE100_SW3BVOL_VSEL_M        (0x3f<<0)
+
+#define PFUZE100_SW3BSTANDBY   68
+#define PFUZE100_SW3BSTANDBY_STBY_VAL  0x0
+#define PFUZE100_SW3BSTANDBY_STBY_M    (0x3f<<0)
+
+#define PFUZE100_SW3BOFF       69
+#define PFUZE100_SW3BOFF_OFF_VAL       0x0
+#define PFUZE100_SW3BOFF_OFF_M (0x3f<<0)
+
+#define PFUZE100_SW3BMODE      70
+#define PFUZE100_SW3BMODE_OMODE_VAL    (0x0<<5)
+#define PFUZE100_SW3BMODE_OMODE_M      (0x1<<5)
+#define PFUZE100_SW3BMODE_MODE_VAL     (0x7<<0)
+#define PFUZE100_SW3BMODE_MODE_M       (0xf<<0)
+
+#define PFUZE100_SW3BCON               71
+#define PFUZE100_SW3BCON_SPEED_VAL     (0x1<<6)
+#define PFUZE100_SW3BCON_SPEED_M       (0x3<<6)
+#define PFUZE100_SW3BCON_PHASE_VAL     (0x1<<4)
+#define PFUZE100_SW3BCON_PHASE_M       (0x3<<4)
+#define PFUZE100_SW3BCON_FREQ_VAL      (0x1<<2)
+#define PFUZE100_SW3BCON_FREQ_M                (0x3<<2)
+#define PFUZE100_SW3BCON_LIM_VAL       (0x0<<0)
+#define PFUZE100_SW3BCON_LIM_M         (0x3<<0)
+
+/*SW4*/
+#define PFUZE100_SW4VOL                74
+#define PFUZE100_SW4VOL_VSEL   0
+#define PFUZE100_SW4VOL_VSEL_M (0x3f<<0)
+
+#define PFUZE100_SW4STANDBY    75
+#define PFUZE100_SW4STANDBY_STBY_VAL   0
+#define PFUZE100_SW4STANDBY_STBY_M     (0x3f<<0)
+
+#define PFUZE100_SW4OFF                76
+#define PFUZE100_SW4OFF_OFF_VAL        0x0
+#define PFUZE100_SW4OFF_OFF_M  (0x3f<<0)
+
+#define PFUZE100_SW4MODE       77
+#define PFUZE100_SW4MODE_OMODE_VAL     (0x0<<5)
+#define PFUZE100_SW4MODE_OMODE_M       (0x1<<5)
+#define PFUZE100_SW4MODE_MODE_VAL      (0x7<<0)
+#define PFUZE100_SW4MODE_MODE_M                (0xf<<0)
+
+#define PFUZE100_SW4CON                78
+#define PFUZE100_SW4CON_SPEED_VAL      (0x1<<6)
+#define PFUZE100_SW4CON_SPEED_M                (0x3<<6)
+#define PFUZE100_SW4CON_PHASE_VAL      (0x1<<4)
+#define PFUZE100_SW4CON_PHASE_M                (0x3<<4)
+#define PFUZE100_SW4CON_FREQ_VAL       (0x1<<2)
+#define PFUZE100_SW4CON_FREQ_M         (0x3<<2)
+#define PFUZE100_SW4CON_LIM_VAL                (0x0<<0)
+#define PFUZE100_SW4CON_LIM_M          (0x3<<0)
+
+ /*SWBST*/
+#define PFUZE100_SWBSTCON1     102
+#define PFUZE100_SWBSTCON1_STBY_VAL    0x0
+#define PFUZE100_SWBSTCON1_STBY_M      (0x3<<5)
+#define PFUZE100_SWBSTCON1_SWBSTMOD_VAL        (0x1<<2)
+#define PFUZE100_SWBSTCON1_SWBSTMOD_M  (0x3<<2)
+#define PFUZE100_SWBSTCON1_VSEL        0
+#define PFUZE100_SWBSTCON1_VSEL_M      (0x3<<0)
+     /*VREFDDR*/
+#define PFUZE100_VREFDDRCON    106
+#define PFUZE100_VREFDDRCON_EN (0x1<<4)
+     /*VSNVS*/
+#define PFUZE100_VSNVSVOL              107
+#define PFUZE100_VSNVSVOL_VSEL 0
+#define PFUZE100_VSNVSVOL_VSEL_M       (0x3<<0)
+/*VGEN1*/
+#define PFUZE100_VGEN1VOL              108
+#define PFUZE100_VGEN1VOL_STBY_VAL     0x0
+#define PFUZE100_VGEN1VOL_STBY_M       (0x1<<5)
+#define PFUZE100_VGEN1VOL_EN   (0x1<<4)
+#define PFUZE100_VGEN1VOL_VSEL 0
+#ifdef PFUZE100_FIRST_VERSION
+#define PFUZE100_VGEN1VOL_VSEL_M       (0x7<<0)
+#else
+#define PFUZE100_VGEN1VOL_VSEL_M       (0xf<<0)
+#endif
+/*VGEN2*/
+#define PFUZE100_VGEN2VOL              109
+#define PFUZE100_VGEN2VOL_STBY_VAL     0x0
+#define PFUZE100_VGEN2VOL_STBY_M       (0x1<<5)
+#define PFUZE100_VGEN2VOL_EN   (0x1<<4)
+#define PFUZE100_VGEN2VOL_VSEL 0
+#ifdef PFUZE100_FIRST_VERSION
+#define PFUZE100_VGEN2VOL_VSEL_M       (0x7<<0)
+#else
+#define PFUZE100_VGEN2VOL_VSEL_M       (0xf<<0)
+#endif
+/*VGEN3*/
+#define PFUZE100_VGEN3VOL              110
+#define PFUZE100_VGEN3VOL_STBY_VAL     0x0
+#define PFUZE100_VGEN3VOL_STBY_M       (0x1<<5)
+#define PFUZE100_VGEN3VOL_EN   (0x1<<4)
+#define PFUZE100_VGEN3VOL_VSEL 0
+#define PFUZE100_VGEN3VOL_VSEL_M       (0xf<<0)
+/*VGEN4*/
+#define PFUZE100_VGEN4VOL              111
+#define PFUZE100_VGEN4VOL_STBY_VAL     0x0
+#define PFUZE100_VGEN4VOL_STBY_M       (0x1<<5)
+#define PFUZE100_VGEN4VOL_EN   (0x1<<4)
+#define PFUZE100_VGEN4VOL_VSEL 0
+#define PFUZE100_VGEN4VOL_VSEL_M       (0xf<<0)
+/*VGEN5*/
+#define PFUZE100_VGEN5VOL              112
+#define PFUZE100_VGEN5VOL_STBY_VAL     0x0
+#define PFUZE100_VGEN5VOL_STBY_M       (0x1<<5)
+#define PFUZE100_VGEN5VOL_EN   (0x1<<4)
+#define PFUZE100_VGEN5VOL_VSEL 0
+#define PFUZE100_VGEN5VOL_VSEL_M       (0xf<<0)
+/*VGEN6*/
+#define PFUZE100_VGEN6VOL              113
+#define PFUZE100_VGEN6VOL_STBY_VAL     0x0
+#define PFUZE100_VGEN6VOL_STBY_M       (0x1<<5)
+#define PFUZE100_VGEN6VOL_EN   (0x1<<4)
+#define PFUZE100_VGEN6VOL_VSEL 0
+#define PFUZE100_VGEN6VOL_VSEL_M       (0xf<<0)
+static struct pfuze_regulator pfuze100_regulators[] = {
+       PFUZE100_SW_DEFINE(SW1A, SW1AVOL, pfuze100_sw1),
+       PFUZE100_SW_DEFINE(SW1B, SW1BVOL, pfuze100_sw1),
+       PFUZE100_SW_DEFINE(SW1C, SW1CVOL, pfuze100_sw1),
+       PFUZE100_SW_DEFINE(SW2, SW2VOL, pfuze100_sw2),
+       PFUZE100_SW_DEFINE(SW3A, SW3AVOL, pfuze100_sw3),
+       PFUZE100_SW_DEFINE(SW3B, SW3BVOL, pfuze100_sw3),
+       PFUZE100_SW_DEFINE(SW4, SW4VOL, pfuze100_sw4),
+       PFUZE100_SW_DEFINE(SWBST, SWBSTCON1, pfuze100_swbst),
+       PFUZE100_SW_DEFINE(VSNVS, VSNVSVOL, pfuze100_vsnvs),
+       PFUZE100_FIXED_VOL_DEFINE(VREFDDR, VREFDDRCON, pfuze100_vrefddr),
+       PFUZE100_VGEN_DEFINE(VGEN1, VGEN1VOL, pfuze100_vgen12),
+       PFUZE100_VGEN_DEFINE(VGEN2, VGEN2VOL, pfuze100_vgen12),
+       PFUZE100_VGEN_DEFINE(VGEN3, VGEN3VOL, pfuze100_vgen36),
+       PFUZE100_VGEN_DEFINE(VGEN4, VGEN4VOL, pfuze100_vgen36),
+       PFUZE100_VGEN_DEFINE(VGEN5, VGEN5VOL, pfuze100_vgen36),
+       PFUZE100_VGEN_DEFINE(VGEN6, VGEN6VOL, pfuze100_vgen36),
+};
+
+static int pfuze100_regulator_enable(struct regulator_dev *rdev)
+{
+       struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+       int id = rdev_get_id(rdev);
+       int ret;
+
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+       pfuze_lock(priv->pfuze);
+       ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].reg,
+                           pfuze100_regulators[id].enable_bit,
+                           pfuze100_regulators[id].enable_bit);
+       pfuze_unlock(priv->pfuze);
+       return ret;
+}
+
+static int pfuze100_regulator_disable(struct regulator_dev *rdev)
+{
+       struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+       int id = rdev_get_id(rdev);
+       int ret;
+
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+       pfuze_lock(priv->pfuze);
+       ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].reg,
+                           pfuze100_regulators[id].enable_bit, 0);
+       pfuze_unlock(priv->pfuze);
+       return ret;
+}
+
+static int pfuze100_regulator_is_enabled(struct regulator_dev *rdev)
+{
+       struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+       int id = rdev_get_id(rdev);
+       int ret;
+       unsigned char val;
+
+       pfuze_lock(priv->pfuze);
+       ret = pfuze_reg_read(priv->pfuze, pfuze100_regulators[id].reg, &val);
+       pfuze_unlock(priv->pfuze);
+       if (ret)
+               return ret;
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+       return (val & pfuze100_regulators[id].enable_bit) != 0;
+}
+
+int pfuze100_regulator_list_voltage(struct regulator_dev *rdev,
+                                   unsigned selector)
+{
+       int id = rdev_get_id(rdev);
+
+       if (selector >= pfuze100_regulators[id].desc.n_voltages)
+               return -EINVAL;
+       return pfuze100_regulators[id].voltages[selector];
+}
+
+int pfuze100_get_best_voltage_index(struct regulator_dev *rdev, int min_uV,
+                                   int max_uV)
+{
+       int reg_id = rdev_get_id(rdev);
+       int i, bestmatch, bestindex;
+
+       bestmatch = INT_MAX;
+       bestindex = -1;
+       for (i = 0; i < pfuze100_regulators[reg_id].desc.n_voltages; i++) {
+               if (pfuze100_regulators[reg_id].voltages[i] >= min_uV &&
+                   pfuze100_regulators[reg_id].voltages[i] < bestmatch) {
+                       bestmatch = pfuze100_regulators[reg_id].voltages[i];
+                       bestindex = i;
+               }
+       }
+       if (bestindex < 0 || bestmatch > max_uV) {
+               dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
+                        min_uV, max_uV);
+               return -EINVAL;
+       }
+       return bestindex;
+}
+
+EXPORT_SYMBOL_GPL(pfuze100_get_best_voltage_index);
+
+static int
+pfuze100_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
+                              int max_uV, unsigned *selector)
+{
+
+       struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+       int value, id = rdev_get_id(rdev);
+       int ret;
+
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
+               __func__, id, min_uV, max_uV);
+       /* Find the best index */
+       value = pfuze100_get_best_voltage_index(rdev, min_uV, max_uV);
+       dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
+       if (value < 0)
+               return value;
+       pfuze_lock(priv->pfuze);
+       ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].reg,
+                           pfuze100_regulators[id].vsel_mask,
+                           value << pfuze100_regulators[id].vsel_shift);
+       pfuze_unlock(priv->pfuze);
+       return ret;
+
+}
+
+static int pfuze100_regulator_get_voltage(struct regulator_dev *rdev)
+{
+       struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+       int ret, id = rdev_get_id(rdev);
+       unsigned char val;
+
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+       pfuze_lock(priv->pfuze);
+       ret = pfuze_reg_read(priv->pfuze, pfuze100_regulators[id].reg, &val);
+       pfuze_unlock(priv->pfuze);
+       if (ret)
+               return ret;
+       val = (val & pfuze100_regulators[id].vsel_mask)
+           >> pfuze100_regulators[id].vsel_shift;
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
+       BUG_ON(val > pfuze100_regulators[id].desc.n_voltages);
+       return pfuze100_regulators[id].voltages[val];
+}
+
+static struct regulator_ops pfuze100_ldo_regulator_ops = {
+       .enable = pfuze100_regulator_enable,
+       .disable = pfuze100_regulator_disable,
+       .is_enabled = pfuze100_regulator_is_enabled,
+       .list_voltage = pfuze100_regulator_list_voltage,
+       .set_voltage = pfuze100_regulator_set_voltage,
+       .get_voltage = pfuze100_regulator_get_voltage,
+};
+
+static int pfuze100_fixed_regulator_set_voltage(struct regulator_dev *rdev,
+                                               int min_uV, int max_uV,
+                                               unsigned *selector)
+{
+       int id = rdev_get_id(rdev);
+
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
+               __func__, id, min_uV, max_uV);
+       if (min_uV >= pfuze100_regulators[id].voltages[0] &&
+           max_uV <= pfuze100_regulators[id].voltages[0])
+               return 0;
+       else
+               return -EINVAL;
+
+}
+
+static int pfuze100_fixed_regulator_get_voltage(struct regulator_dev *rdev)
+{
+       int id = rdev_get_id(rdev);
+
+       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+       return pfuze100_regulators[id].voltages[0];
+}
+
+static struct regulator_ops pfuze100_fixed_regulator_ops = {
+       .enable = pfuze100_regulator_enable,
+       .disable = pfuze100_regulator_disable,
+       .is_enabled = pfuze100_regulator_is_enabled,
+       .set_voltage = pfuze100_fixed_regulator_set_voltage,
+       .get_voltage = pfuze100_fixed_regulator_get_voltage,
+};
+
+static int pfuze100_sw_regulator_is_enabled(struct regulator_dev *rdev)
+{
+       return 1;
+}
+
+static struct regulator_ops pfuze100_sw_regulator_ops = {
+       .is_enabled = pfuze100_sw_regulator_is_enabled,
+       .list_voltage = pfuze100_regulator_list_voltage,
+       .set_voltage = pfuze100_regulator_set_voltage,
+       .get_voltage = pfuze100_regulator_get_voltage,
+};
+
+static int __devinit pfuze100_regulator_probe(struct platform_device *pdev)
+{
+       struct pfuze_regulator_priv *priv;
+       struct mc_pfuze *pfuze100 = dev_get_drvdata(pdev->dev.parent);
+       struct pfuze_regulator_platform_data *pdata =
+           dev_get_platdata(&pdev->dev);
+       struct pfuze_regulator_init_data *init_data;
+       int i, ret;
+       struct regulator *test_regulator;
+
+       priv = kzalloc(sizeof(*priv) +
+                      pdata->num_regulators * sizeof(priv->regulators[0]),
+                      GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       priv->pfuze_regulators = pfuze100_regulators;
+       priv->pfuze = pfuze100;
+       pfuze_lock(pfuze100);
+       ret = pfuze_reg_rmw(pfuze100, PFUZE100_SWBSTCON1,
+                           PFUZE100_SWBSTCON1_SWBSTMOD_M,
+                           PFUZE100_SWBSTCON1_SWBSTMOD_VAL);
+       if (ret)
+               goto err_free;
+       pfuze_unlock(pfuze100);
+       for (i = 0; i < pdata->num_regulators; i++) {
+               init_data = &pdata->regulators[i];
+               priv->regulators[i] =
+                   regulator_register(&pfuze100_regulators[init_data->id].desc,
+                                      &pdev->dev, init_data->init_data, priv);
+               if (IS_ERR(priv->regulators[i])) {
+                       dev_err(&pdev->dev, "failed to register regulator %s\n",
+                               pfuze100_regulators[i].desc.name);
+                       ret = PTR_ERR(priv->regulators[i]);
+                       goto err;
+               }
+       }
+#if 0
+       test_regulator = regulator_get(&pdev->dev, "P1V325_VDDARM_SW1AB");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 1325000, 1325000);
+       test_regulator = regulator_get(&pdev->dev, "P1V325_VDDSOC_SW1C");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 1325000, 1325000);
+       test_regulator = regulator_get(&pdev->dev, "P3V0_VDDHIGH_SW2");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 3000000, 3000000);
+       test_regulator = regulator_get(&pdev->dev, "P1V5_DDR_SW3");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 1500000, 1500000);
+       test_regulator = regulator_get(&pdev->dev, "P1V8_SW4");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 1800000, 1800000);
+       test_regulator = regulator_get(&pdev->dev, "P5V0_SWBST");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 5000000, 5000000);
+       test_regulator = regulator_get(&pdev->dev, "P3V0_STBY");
+       if (test_regulator)
+               regulator_set_voltage(test_regulator, 3000000, 3000000);
+       test_regulator = regulator_get(&pdev->dev, "P1V2_VGEN1");
+       if (test_regulator) {
+               regulator_set_voltage(test_regulator, 1200000, 1200000);
+               regulator_enable(test_regulator);
+       }
+       test_regulator = regulator_get(&pdev->dev, "P1V5_VGEN2");
+       if (test_regulator) {
+               regulator_set_voltage(test_regulator, 1500000, 1500000);
+               regulator_enable(test_regulator);
+       }
+       test_regulator = regulator_get(&pdev->dev, "P1V8_VGEN3");
+       if (test_regulator) {
+               regulator_set_voltage(test_regulator, 1800000, 1800000);
+               regulator_enable(test_regulator);
+       }
+       test_regulator = regulator_get(&pdev->dev, "P1V8_VGEN4");
+       if (test_regulator) {
+               regulator_set_voltage(test_regulator, 1800000, 1800000);
+               regulator_enable(test_regulator);
+       }
+       test_regulator = regulator_get(&pdev->dev, "P2V5_VGEN5");
+       if (test_regulator) {
+               regulator_set_voltage(test_regulator, 2500000, 2500000);
+               regulator_enable(test_regulator);
+       }
+       test_regulator = regulator_get(&pdev->dev, "P2V8_VGEN6");
+       if (test_regulator) {
+               regulator_set_voltage(test_regulator, 2800000, 2800000);
+               regulator_enable(test_regulator);
+       }
+#endif
+
+       platform_set_drvdata(pdev, priv);
+       return 0;
+err:
+       while (--i >= 0)
+               regulator_unregister(priv->regulators[i]);
+err_free:
+       pfuze_unlock(pfuze100);
+       kfree(priv);
+       return ret;
+}
+
+static int __devexit pfuze100_regulator_remove(struct platform_device *pdev)
+{
+       struct pfuze_regulator_priv *priv = platform_get_drvdata(pdev);
+       struct pfuze_regulator_platform_data *pdata =
+           dev_get_platdata(&pdev->dev);
+       int i;
+
+       platform_set_drvdata(pdev, NULL);
+       for (i = 0; i < pdata->num_regulators; i++)
+               regulator_unregister(priv->regulators[i]);
+
+       kfree(priv);
+       return 0;
+}
+
+static struct platform_driver pfuze100_regulator_driver = {
+       .driver = {
+                  .name = "pfuze100-regulator",
+                  .owner = THIS_MODULE,
+                  },
+       .remove = __devexit_p(pfuze100_regulator_remove),
+       .probe = pfuze100_regulator_probe,
+};
+
+static int __init pfuze100_regulator_init(void)
+{
+       return platform_driver_register(&pfuze100_regulator_driver);
+}
+
+subsys_initcall(pfuze100_regulator_init);
+
+static void __exit pfuze100_regulator_exit(void)
+{
+       platform_driver_unregister(&pfuze100_regulator_driver);
+}
+
+module_exit(pfuze100_regulator_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100 PMIC");
+MODULE_ALIAS("pfuze100-regulator");