[PATCH 3/4] MXC: mc13783: Developing, trying to full support regulators.
Alberto Panizzo
maramaopercheseimorto at gmail.com
Thu Dec 10 13:50:13 EST 2009
This patch add the ability to change voltages settings
for all possible mc13783 regulators.
Pay attention that it is a development patch with many
debug messages enabled.
Signed-off-by: Alberto Panizzo <alberto.panizzo at gmail.com>
---
drivers/mfd/mc13783-core.c | 20 ++
drivers/regulator/mc13783.c | 489 ++++++++++++++++++++++++++++++++--
drivers/spi/spi_imx.c | 2 +
include/linux/mfd/mc13783-private.h | 53 ++++-
4 files changed, 534 insertions(+), 30 deletions(-)
diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c
index e354d29..50fd9d8 100644
--- a/drivers/mfd/mc13783-core.c
+++ b/drivers/mfd/mc13783-core.c
@@ -20,6 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define DEBUG 1
#include <linux/mfd/mc13783-private.h>
#include <linux/platform_device.h>
@@ -35,6 +36,10 @@
#include <linux/slab.h>
#include <linux/irq.h>
+#include <mach/hardware.h>
+#include <mach/board-mx31pdk.h>
+#include <linux/io.h>
+
#define MC13783_MAX_REG_NUM 0x3f
#define MC13783_FRAME_MASK 0x00ffffff
#define MC13783_MAX_REG_NUM 0x3f
@@ -87,6 +92,8 @@ static int mc13783_write(struct mc13783 *mc13783, int reg_num, u32 reg_val)
frame |= reg_num << MC13783_REG_NUM_SHIFT;
frame |= reg_val & MC13783_FRAME_MASK;
+ printk(KERN_DEBUG "%s frame: 0x%x\n", __func__, frame);
+
return spi_rw(mc13783->spi_device, (u8 *)&frame, 4);
}
@@ -127,15 +134,28 @@ int mc13783_set_bits(struct mc13783 *mc13783, int reg, u32 mask, u32 val)
u32 tmp;
int ret;
+ printk(KERN_DEBUG "%s reg: %d, mask: 0x%x, val: 0x%x\n", __func__, reg, mask, val);
+
mutex_lock(&mc13783->io_lock);
+ __raw_writew(__raw_readw(CPLD_LED_REG) | 0x10, CPLD_LED_REG);
+
ret = mc13783_read(mc13783, reg, &tmp);
+
+ printk(KERN_DEBUG "%s read ret: %d, tmp: 0x%x\n", __func__,ret,tmp);
+
tmp = (tmp & ~mask) | val;
if (ret == 0)
ret = mc13783_write(mc13783, reg, tmp);
+ printk(KERN_DEBUG "%s write ret: %d, tmp: 0x%x\n", __func__,ret,tmp);
+
mutex_unlock(&mc13783->io_lock);
+ printk(KERN_DEBUG "%s done\n", __func__);
+
+ __raw_writew(__raw_readw(CPLD_LED_REG) & 0xef, CPLD_LED_REG);
+
return ret;
}
EXPORT_SYMBOL_GPL(mc13783_set_bits);
diff --git a/drivers/regulator/mc13783.c b/drivers/regulator/mc13783.c
index 710211f..f265f07 100644
--- a/drivers/regulator/mc13783.c
+++ b/drivers/regulator/mc13783.c
@@ -2,12 +2,15 @@
* Regulator Driver for Freescale MC13783 PMIC
*
* Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer at pengutronix.de>
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#define DEBUG 1
+
#include <linux/mfd/mc13783-private.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/driver.h>
@@ -19,23 +22,220 @@
struct mc13783_regulator {
struct regulator_desc desc;
- int reg;
+ int control_reg;
int enable_bit;
+ int vsel_reg;
+ int vsel_shift;
+ int vsel_mask;
+ int const *voltages;
+};
+
+/*
+ * Voltage Values
+ */
+static const int const mc13783_sw_voltages[] = {
+ 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,1700000,1700000,1700000,
+ 1800000,1800000,1800000,1800000,
+ 1850000,1850000,1850000,1850000,
+ 2000000,2000000,2000000,2000000,
+ 2100000,2100000,2100000,2100000,
+ 2200000,2200000,2200000,2200000,
+ 2200000,2200000,2200000,2200000,
+ 2200000,2200000,2200000,2200000,
+};
+
+static const int const mc13783_sw3_voltages[] = {
+ 5000000,
+ 5000000,
+ 5000000,
+ 5500000,
+};
+
+static const int const mc13783_vaudio_voltages[] = {
+ 2775000,
+};
+
+static const int const mc13783_viohi_voltages[] = {
+ 2775000,
+};
+
+static const int const mc13783_violo_voltage[] = {
+ 1200000,
+ 1300000,
+ 1500000,
+ 1800000,
+};
+
+static const int const mc13783_vdig_voltage[] = {
+ 1200000,
+ 1300000,
+ 1500000,
+ 1800000,
+};
+
+static const int const mc13783_vgen_voltage[] = {
+ 1200000,
+ 1300000,
+ 1500000,
+ 1800000,
+ 1100000,
+ 2000000,
+ 2775000,
+ 2400000,
+};
+
+static const int const mc13783_vrfdig_voltage[] = {
+ 1200000,
+ 1500000,
+ 1800000,
+ 1875000,
+};
+
+static const int const mc13783_vrfref_voltage[] = {
+ 2475000,
+ 2600000,
+ 2700000,
+ 2775000,
+};
+
+static const int const mc13783_vrfcp_voltage[] = {
+ 2700000,
+ 2775000,
+};
+
+static const int const mc13783_vsim_voltage[] = {
+ 1800000,
+ 2900000,
+ 3000000,
+};
+
+static const int const mc13783_vesim_voltage[] = {
+ 1800000,
+ 2900000,
+};
+
+static const int const mc13783_vcam_voltage[] = {
+ 1500000,
+ 1800000,
+ 2500000,
+ 2550000,
+ 2600000,
+ 2750000,
+ 2800000,
+ 3000000,
+};
+
+static const int const mc13783_vrfbg_voltages[] = {
+ 1250000,
+};
+
+static const int const mc13783_vvib_voltage[] = {
+ 1300000,
+ 1800000,
+ 2000000,
+ 3000000,
+};
+
+static const int const mc13783_vmmc_voltage[] = {
+ 1600000,
+ 1800000,
+ 2000000,
+ 2600000,
+ 2700000,
+ 2800000,
+ 2900000,
+ 3000000,
+};
+
+static const int const mc13783_vrf_voltage[] = {
+ 1500000,
+ 1875000,
+ 2700000,
+ 2775000,
};
static struct regulator_ops mc13783_regulator_ops;
static struct mc13783_regulator mc13783_regulators[] = {
+ [MC13783_SW_SW1A] = {
+ .desc = {
+ .name = "SW_SW1A",
+ .n_voltages = ARRAY_SIZE(mc13783_sw_voltages),
+ .ops = &mc13783_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = MC13783_SW_SW1A,
+ .owner = THIS_MODULE,
+ },
+ .vsel_reg = MC13783_REG_SWITCHERS_0,
+ .vsel_shift = MC13783_REGSET_SW_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_SW_VSEL_MASK,
+ .voltages = mc13783_sw_voltages,
+ },
+ [MC13783_SW_SW1B] = {
+ .desc = {
+ .name = "SW_SW1B",
+ .n_voltages = ARRAY_SIZE(mc13783_sw_voltages),
+ .ops = &mc13783_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = MC13783_SW_SW1B,
+ .owner = THIS_MODULE,
+ },
+ .vsel_reg = MC13783_REG_SWITCHERS_1,
+ .vsel_shift = MC13783_REGSET_SW_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_SW_VSEL_MASK,
+ .voltages = mc13783_sw_voltages,
+ },
+ [MC13783_SW_SW2A] = {
+ .desc = {
+ .name = "SW_SW2A",
+ .n_voltages = ARRAY_SIZE(mc13783_sw_voltages),
+ .ops = &mc13783_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = MC13783_SW_SW2A,
+ .owner = THIS_MODULE,
+ },
+ .vsel_reg = MC13783_REG_SWITCHERS_2,
+ .vsel_shift = MC13783_REGSET_SW_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_SW_VSEL_MASK,
+ .voltages = mc13783_sw_voltages,
+ },
+ [MC13783_SW_SW2B] = {
+ .desc = {
+ .name = "SW_SW2B",
+ .n_voltages = ARRAY_SIZE(mc13783_sw_voltages),
+ .ops = &mc13783_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = MC13783_SW_SW2B,
+ .owner = THIS_MODULE,
+ },
+ .vsel_reg = MC13783_REG_SWITCHERS_3,
+ .vsel_shift = MC13783_REGSET_SW_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_SW_VSEL_MASK,
+ .voltages = mc13783_sw_voltages,
+ },
[MC13783_SW_SW3] = {
.desc = {
.name = "SW_SW3",
+ .n_voltages = ARRAY_SIZE(mc13783_sw3_voltages),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_SW_SW3,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_SWITCHERS_5,
+ .control_reg = MC13783_REG_SWITCHERS_5,
.enable_bit = MC13783_SWCTRL_SW3_EN,
+ .vsel_reg = MC13783_REG_SWITCHERS_5,
+ .vsel_shift = MC13783_REGSET_SW3_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_SW3_VSEL_MASK,
+ .voltages = mc13783_sw3_voltages,
},
[MC13783_SW_PLL] = {
.desc = {
@@ -45,195 +245,271 @@ static struct mc13783_regulator mc13783_regulators[] = {
.id = MC13783_SW_PLL,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_SWITCHERS_4,
+ .control_reg = MC13783_REG_SWITCHERS_4,
.enable_bit = MC13783_SWCTRL_PLL_EN,
},
[MC13783_REGU_VAUDIO] = {
.desc = {
.name = "REGU_VAUDIO",
+ .n_voltages = ARRAY_SIZE(mc13783_vaudio_voltages),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VAUDIO,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VAUDIO_EN,
+ .voltages = mc13783_vaudio_voltages,
},
[MC13783_REGU_VIOHI] = {
.desc = {
.name = "REGU_VIOHI",
+ .n_voltages = ARRAY_SIZE(mc13783_viohi_voltages),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VIOHI,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VIOHI_EN,
+ .voltages = mc13783_viohi_voltages,
},
[MC13783_REGU_VIOLO] = {
.desc = {
.name = "REGU_VIOLO",
+ .n_voltages = ARRAY_SIZE(mc13783_violo_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VIOLO,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VIOLO_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VIOLO_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VIOLO_VSEL_MASK,
+ .voltages = mc13783_violo_voltage,
},
[MC13783_REGU_VDIG] = {
.desc = {
.name = "REGU_VDIG",
+ .n_voltages = ARRAY_SIZE(mc13783_vdig_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VDIG,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VDIG_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VDIG_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VDIG_VSEL_MASK,
+ .voltages = mc13783_vdig_voltage,
},
[MC13783_REGU_VGEN] = {
.desc = {
.name = "REGU_VGEN",
+ .n_voltages = ARRAY_SIZE(mc13783_vgen_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VGEN,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VGEN_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VGEN_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VGEN_VSEL_MASK,
+ .voltages = mc13783_vgen_voltage,
},
[MC13783_REGU_VRFDIG] = {
.desc = {
.name = "REGU_VRFDIG",
+ .n_voltages = ARRAY_SIZE(mc13783_vrfdig_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VRFDIG,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VRFDIG_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VRFDIG_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VRFDIG_VSEL_MASK,
+ .voltages = mc13783_vrfdig_voltage,
},
[MC13783_REGU_VRFREF] = {
.desc = {
.name = "REGU_VRFREF",
+ .n_voltages = ARRAY_SIZE(mc13783_vrfref_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VRFREF,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VRFREF_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VRFREF_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VRFREF_VSEL_MASK,
+ .voltages = mc13783_vrfref_voltage,
},
[MC13783_REGU_VRFCP] = {
.desc = {
.name = "REGU_VRFCP",
+ .n_voltages = ARRAY_SIZE(mc13783_vrfcp_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VRFCP,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_0,
+ .control_reg = MC13783_REG_REGULATOR_MODE_0,
.enable_bit = MC13783_REGCTRL_VRFCP_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VRFCP_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VRFCP_VSEL_MASK,
+ .voltages = mc13783_vrfcp_voltage,
},
[MC13783_REGU_VSIM] = {
.desc = {
.name = "REGU_VSIM",
+ .n_voltages = ARRAY_SIZE(mc13783_vsim_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VSIM,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VSIM_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VSIM_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VSIM_VSEL_MASK,
+ .voltages = mc13783_vsim_voltage,
},
[MC13783_REGU_VESIM] = {
.desc = {
.name = "REGU_VESIM",
+ .n_voltages = ARRAY_SIZE(mc13783_vesim_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VESIM,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VESIM_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VESIM_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VESIM_VSEL_MASK,
+ .voltages = mc13783_vesim_voltage,
},
[MC13783_REGU_VCAM] = {
.desc = {
.name = "REGU_VCAM",
+ .n_voltages = ARRAY_SIZE(mc13783_vcam_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VCAM,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VCAM_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_0,
+ .vsel_shift = MC13783_REGSET_VCAM_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VCAM_VSEL_MASK,
+ .voltages = mc13783_vcam_voltage,
},
[MC13783_REGU_VRFBG] = {
.desc = {
.name = "REGU_VRFBG",
+ .n_voltages = ARRAY_SIZE(mc13783_vrfbg_voltages),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VRFBG,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VRFBG_EN,
+ .voltages = mc13783_vrfbg_voltages
},
[MC13783_REGU_VVIB] = {
.desc = {
.name = "REGU_VVIB",
+ .n_voltages = ARRAY_SIZE(mc13783_vvib_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VVIB,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VVIB_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_1,
+ .vsel_shift = MC13783_REGSET_VVIB_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VVIB_VSEL_MASK,
+ .voltages = mc13783_vvib_voltage,
},
[MC13783_REGU_VRF1] = {
.desc = {
.name = "REGU_VRF1",
+ .n_voltages = ARRAY_SIZE(mc13783_vrf_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VRF1,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VRF1_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_1,
+ .vsel_shift = MC13783_REGSET_VRF1_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VRF1_VSEL_MASK,
+ .voltages = mc13783_vrf_voltage,
},
[MC13783_REGU_VRF2] = {
.desc = {
.name = "REGU_VRF2",
+ .n_voltages = ARRAY_SIZE(mc13783_vrf_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VRF2,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VRF2_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_1,
+ .vsel_shift = MC13783_REGSET_VRF2_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VRF2_VSEL_MASK,
+ .voltages = mc13783_vrf_voltage,
},
[MC13783_REGU_VMMC1] = {
.desc = {
.name = "REGU_VMMC1",
+ .n_voltages = ARRAY_SIZE(mc13783_vmmc_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VMMC1,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VMMC1_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_1,
+ .vsel_shift = MC13783_REGSET_VMMC1_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VMMC1_VSEL_MASK,
+ .voltages = mc13783_vmmc_voltage,
},
[MC13783_REGU_VMMC2] = {
.desc = {
.name = "REGU_VMMC2",
+ .n_voltages = ARRAY_SIZE(mc13783_vmmc_voltage),
.ops = &mc13783_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = MC13783_REGU_VMMC2,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_REGULATOR_MODE_1,
+ .control_reg = MC13783_REG_REGULATOR_MODE_1,
.enable_bit = MC13783_REGCTRL_VMMC2_EN,
+ .vsel_reg = MC13783_REG_REGULATOR_SETTING_1,
+ .vsel_shift = MC13783_REGSET_VMMC2_VSEL_SHIFT,
+ .vsel_mask = MC13783_REGSET_VMMC2_VSEL_MASK,
+ .voltages = mc13783_vmmc_voltage,
},
[MC13783_REGU_GPO1] = {
.desc = {
@@ -243,7 +519,7 @@ static struct mc13783_regulator mc13783_regulators[] = {
.id = MC13783_REGU_GPO1,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_POWER_MISCELLANEOUS,
+ .control_reg = MC13783_REG_POWER_MISCELLANEOUS,
.enable_bit = MC13783_REGCTRL_GPO1_EN,
},
[MC13783_REGU_GPO2] = {
@@ -254,7 +530,7 @@ static struct mc13783_regulator mc13783_regulators[] = {
.id = MC13783_REGU_GPO2,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_POWER_MISCELLANEOUS,
+ .control_reg = MC13783_REG_POWER_MISCELLANEOUS,
.enable_bit = MC13783_REGCTRL_GPO2_EN,
},
[MC13783_REGU_GPO3] = {
@@ -265,7 +541,7 @@ static struct mc13783_regulator mc13783_regulators[] = {
.id = MC13783_REGU_GPO3,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_POWER_MISCELLANEOUS,
+ .control_reg = MC13783_REG_POWER_MISCELLANEOUS,
.enable_bit = MC13783_REGCTRL_GPO3_EN,
},
[MC13783_REGU_GPO4] = {
@@ -276,7 +552,7 @@ static struct mc13783_regulator mc13783_regulators[] = {
.id = MC13783_REGU_GPO4,
.owner = THIS_MODULE,
},
- .reg = MC13783_REG_POWER_MISCELLANEOUS,
+ .control_reg = MC13783_REG_POWER_MISCELLANEOUS,
.enable_bit = MC13783_REGCTRL_GPO4_EN,
},
};
@@ -292,11 +568,25 @@ static int mc13783_enable(struct regulator_dev *rdev)
struct mc13783_priv *priv = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
+ /* Print out all mc13783 registers */
+ int i, ret;
+ for(i = 0; id >= MC13783_REGU_GPO1 && i < MC13783_REG_NB; i++)
+ {
+ mc13783_reg_read(priv->mc13783,i, &ret);
+ dev_dbg(rdev_get_dev(rdev), "reg: %d, val: %x\n",i , ret);
+ }
+
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
- return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
+ /* The regulator is enabled by default? */
+ if (!mc13783_regulators[id].control_reg)
+ return 0;
+
+ ret = mc13783_set_bits(priv->mc13783, mc13783_regulators[id].control_reg,
mc13783_regulators[id].enable_bit,
mc13783_regulators[id].enable_bit);
+ dev_dbg(rdev_get_dev(rdev), "%s ret: %d\n", __func__, ret);
+ return ret;
}
static int mc13783_disable(struct regulator_dev *rdev)
@@ -306,7 +596,10 @@ static int mc13783_disable(struct regulator_dev *rdev)
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
- return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
+ if (!mc13783_regulators[id].control_reg)
+ return -EINVAL;
+
+ return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].control_reg,
mc13783_regulators[id].enable_bit, 0);
}
@@ -316,17 +609,138 @@ static int mc13783_is_enabled(struct regulator_dev *rdev)
int ret, id = rdev_get_id(rdev);
unsigned int val;
- ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+ /* The regulator is enabled by default */
+ if (!mc13783_regulators[id].control_reg)
+ return true;
+
+ ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].control_reg, &val);
if (ret)
return ret;
return (val & mc13783_regulators[id].enable_bit) != 0;
}
+static int mc13783_list_voltage (struct regulator_dev *rdev, unsigned selector)
+{
+ int id = rdev_get_id(rdev);
+
+ if (selector >= mc13783_regulators[id].desc.n_voltages)
+ return -EINVAL;
+
+ return mc13783_regulators[id].voltages[selector];
+}
+
+static int mc13783_get_best_voltage_index(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ int reg_id = rdev_get_id(rdev);
+ int i;
+ int bestmatch;
+ int bestindex;
+
+ /*
+ * Locate the minimum voltage fitting the criteria on
+ * this regulator. The switchable voltages are not
+ * in strict falling order so we need to check them
+ * all for the best match.
+ */
+ bestmatch = INT_MAX;
+ bestindex = -1;
+ for (i = 0; i < mc13783_regulators[reg_id].desc.n_voltages; i++) {
+ if (mc13783_regulators[reg_id].voltages[i] <= max_uV &&
+ mc13783_regulators[reg_id].voltages[i] >= min_uV &&
+ mc13783_regulators[reg_id].voltages[i] < bestmatch) {
+ bestmatch = mc13783_regulators[reg_id].voltages[i];
+ bestindex = i;
+ }
+ }
+
+ if (bestindex < 0) {
+ dev_warn(&rdev->dev, "requested %d<=x<=%d uV, out of range!\n",
+ min_uV, max_uV);
+ return -EINVAL;
+ }
+ return bestindex;
+}
+
+static int mc13783_set_voltage (struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+ struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+ int value, 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);
+
+ dev_dbg(rdev_get_dev(rdev), "%s n_voltages: %d \n",
+ __func__, mc13783_regulators[id].desc.n_voltages);
+
+ /* If not coherent return -EINVAL */
+ if (mc13783_regulators[id].desc.n_voltages == 0)
+ return -EINVAL;
+
+ /* If it is a fixed regulator*/
+ if (mc13783_regulators[id].desc.n_voltages == 1)
+ {
+ if (min_uV > mc13783_regulators[id].voltages[0] &&
+ max_uV < mc13783_regulators[id].voltages[0])
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ /* Find the best index */
+ value = mc13783_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;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d best index: %d\n",
+ __func__, id, value);
+
+ return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].vsel_reg,
+ mc13783_regulators[id].vsel_mask,
+ value << mc13783_regulators[id].vsel_shift);
+}
+
+static int mc13783_get_voltage (struct regulator_dev *rdev)
+{
+ struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+ int ret, id = rdev_get_id(rdev);
+ unsigned int val;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+ /* If not coherent return -EINVAL */
+ if (!mc13783_regulators[id].desc.n_voltages)
+ return -EINVAL;
+
+ /* If it is a fixed voltage regulator */
+ if (mc13783_regulators[id].desc.n_voltages == 1)
+ return mc13783_regulators[id].voltages[0];
+
+ ret = mc13783_reg_read( priv->mc13783,
+ mc13783_regulators[id].vsel_reg, &val);
+ if (ret)
+ return ret;
+
+ val =(val & mc13783_regulators[id].vsel_mask)
+ >> mc13783_regulators[id].vsel_shift;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
+
+ BUG_ON(val > mc13783_regulators[id].desc.n_voltages);
+
+ return mc13783_regulators[id].voltages[val];
+}
+
static struct regulator_ops mc13783_regulator_ops = {
.enable = mc13783_enable,
.disable = mc13783_disable,
.is_enabled = mc13783_is_enabled,
+ .list_voltage = mc13783_list_voltage,
+ .set_voltage = mc13783_set_voltage,
+ .get_voltage = mc13783_get_voltage,
};
static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
@@ -345,6 +759,23 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
priv->mc13783 = mc13783;
+ /*
+ * IMX31PDK specific
+ * will be removed
+ * START
+ */
+
+ /*most regulators are controled by standby signal*/
+ /*except violo*/
+ mc13783_set_bits(priv->mc13783, MC13783_REG_REGULATOR_MODE_0,0x492412,0x492412);
+ mc13783_set_bits(priv->mc13783, MC13783_REG_REGULATOR_MODE_1,0x492492,0x492492);
+ /*also sw3 is controled by standby signal*/
+ mc13783_set_bits(priv->mc13783, MC13783_REG_SWITCHERS_5,0x200000,0x200000);
+
+ /*
+ * END
+ */
+
for (i = 0; i < mc13783->num_regulators; i++) {
init_data = &mc13783->regulators[i];
priv->regulators[i] = regulator_register(
@@ -389,12 +820,12 @@ static struct platform_driver mc13783_regulator_driver = {
.owner = THIS_MODULE,
},
.remove = __devexit_p(mc13783_regulator_remove),
+ .probe = mc13783_regulator_probe,
};
static int __init mc13783_regulator_init(void)
{
- return platform_driver_probe(&mc13783_regulator_driver,
- mc13783_regulator_probe);
+ return platform_driver_register(&mc13783_regulator_driver);
}
subsys_initcall(mc13783_regulator_init);
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 89c22ef..de1f323 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -18,6 +18,8 @@
* Boston, MA 02110-1301, USA.
*/
+#define DEBUG 1
+
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
diff --git a/include/linux/mfd/mc13783-private.h b/include/linux/mfd/mc13783-private.h
index 47e698c..6614de9 100644
--- a/include/linux/mfd/mc13783-private.h
+++ b/include/linux/mfd/mc13783-private.h
@@ -251,6 +251,17 @@ int mc13783_register_irq(struct mc13783 *mc13783, int irq,
#define MC13783_REGCTRL_VIBPINCTRL (1 << 14)
/*
+ * Reg Switchers
+ * 0, 1, 2, 3 (1A, 1B, 2A, 2B)
+ */
+#define MC13783_REGSET_SW_VSEL_SHIFT 0
+#define MC13783_REGSET_SW_DVS_VSEL_SHIFT 6
+#define MC13783_REGSET_SW_STBY_VSEL_SHIFT 12
+#define MC13783_REGSET_SW_VSEL_MASK (0x3F << 0)
+#define MC13783_REGSET_SW_DVS_VSEL_MASK (0x3F << 6)
+#define MC13783_REGSET_SW_STBY_VSEL_MASK (0x3F << 12)
+
+/*
* Reg Switcher 4
*/
#define MC13783_SWCTRL_SW1A_MODE (1 << 0)
@@ -279,12 +290,52 @@ int mc13783_register_irq(struct mc13783 *mc13783, int irq,
#define MC13783_SWCTRL_SW2B_DVS_SPEED (1 << 14)
#define MC13783_SWCTRL_SW2B_PANIC_MODE (1 << 16)
#define MC13783_SWCTRL_SW2B_SOFTSTART (1 << 17)
-#define MC13783_SWSET_SW3 (1 << 18)
+#define MC13783_REGSET_SW3_VSEL_SHIFT 18
+#define MC13783_REGSET_SW3_VSEL_MASK (3 << 18)
#define MC13783_SWCTRL_SW3_EN (1 << 20)
#define MC13783_SWCTRL_SW3_STBY (1 << 21)
#define MC13783_SWCTRL_SW3_MODE (1 << 22)
/*
+ * Reg Setting 0
+ */
+#define MC13783_REGSET_VIOLO_VSEL_SHIFT 2
+#define MC13783_REGSET_VDIG_VSEL_SHIFT 4
+#define MC13783_REGSET_VGEN_VSEL_SHIFT 6
+#define MC13783_REGSET_VRFDIG_VSEL_SHIFT 9
+#define MC13783_REGSET_VRFREF_VSEL_SHIFT 11
+#define MC13783_REGSET_VRFCP_VSEL_SHIFT 13
+#define MC13783_REGSET_VSIM_VSEL_SHIFT 14
+#define MC13783_REGSET_VESIM_VSEL_SHIFT 15
+#define MC13783_REGSET_VCAM_VSEL_SHIFT 16
+
+#define MC13783_REGSET_VIOLO_VSEL_MASK (3 << 2)
+#define MC13783_REGSET_VDIG_VSEL_MASK (3 << 4)
+#define MC13783_REGSET_VGEN_VSEL_MASK (7 << 6)
+#define MC13783_REGSET_VRFDIG_VSEL_MASK (3 << 9)
+#define MC13783_REGSET_VRFREF_VSEL_MASK (3 << 11)
+#define MC13783_REGSET_VRFCP_VSEL_MASK (1 << 13)
+#define MC13783_REGSET_VSIM_VSEL_MASK (1 << 14)
+#define MC13783_REGSET_VESIM_VSEL_MASK (1 << 15)
+#define MC13783_REGSET_VCAM_VSEL_MASK (7 << 16)
+
+/*
+ * Reg Setting 1
+ */
+#define MC13783_REGSET_VVIB_VSEL_SHIFT 0
+#define MC13783_REGSET_VRF1_VSEL_SHIFT 2
+#define MC13783_REGSET_VRF2_VSEL_SHIFT 4
+#define MC13783_REGSET_VMMC1_VSEL_SHIFT 6
+#define MC13783_REGSET_VMMC2_VSEL_SHIFT 9
+
+#define MC13783_REGSET_VVIB_VSEL_MASK (3 << 0)
+#define MC13783_REGSET_VRF1_VSEL_MASK (3 << 2)
+#define MC13783_REGSET_VRF2_VSEL_MASK (3 << 4)
+#define MC13783_REGSET_VMMC1_VSEL_MASK (7 << 6)
+#define MC13783_REGSET_VMMC2_VSEL_MASK (7 << 9)
+
+
+/*
* ADC/Touch
*/
#define MC13783_ADC0_LICELLCON (1 << 0)
--
1.6.3.3
More information about the linux-arm-kernel
mailing list