@@ -19,8 +19,8 @@
#include <linux/i2c/twl.h>
#include "voltage.h"
-
#include "pm.h"
+#include "twl-common.h"
#define OMAP3_SRI2C_SLAVE_ADDR 0x12
#define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00
@@ -170,7 +170,7 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
.uv_to_vsel = twl4030_uv_to_vsel,
};
-static struct omap_voltdm_pmic omap4_mpu_pmic = {
+static struct omap_voltdm_pmic twl6030_vcore1_pmic = {
.slew_rate = 4000,
.step_size = 12660,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
@@ -188,7 +188,7 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
.uv_to_vsel = twl6030_uv_to_vsel,
};
-static struct omap_voltdm_pmic omap4_iva_pmic = {
+static struct omap_voltdm_pmic twl6030_vcore2_pmic = {
.slew_rate = 4000,
.step_size = 12660,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
@@ -206,7 +206,7 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
.uv_to_vsel = twl6030_uv_to_vsel,
};
-static struct omap_voltdm_pmic omap4_core_pmic = {
+static struct omap_voltdm_pmic twl6030_vcore3_pmic = {
.slew_rate = 4000,
.step_size = 12660,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
@@ -224,31 +224,9 @@ static struct omap_voltdm_pmic omap4_core_pmic = {
.uv_to_vsel = twl6030_uv_to_vsel,
};
-int __init omap4_twl_init(void)
+static int __init twl_set_sr(struct voltagedomain *voltdm)
{
- struct voltagedomain *voltdm;
-
- if (!cpu_is_omap44xx())
- return -ENODEV;
-
- voltdm = voltdm_lookup("mpu");
- omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
-
- voltdm = voltdm_lookup("iva");
- omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
-
- voltdm = voltdm_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
-
- return 0;
-}
-
-int __init omap3_twl_init(void)
-{
- struct voltagedomain *voltdm;
-
- if (!cpu_is_omap34xx())
- return -ENODEV;
+ int r = 0;
/*
* The smartreflex bit on twl4030 specifies if the setting of voltage
@@ -260,15 +238,50 @@ int __init omap3_twl_init(void)
* voltage scaling will not function on TWL over I2C_SR.
*/
if (!twl_sr_enable_autoinit)
- omap3_twl_set_sr_bit(true);
+ r = omap3_twl_set_sr_bit(true);
- voltdm = voltdm_lookup("mpu_iva");
- omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
+ return r;
+}
- voltdm = voltdm_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap3_core_pmic);
+static __initdata struct omap_pmic_map omap_twl_map[] = {
+ {
+ .name = "mpu_iva",
+ .cpu = PMIC_CPU_OMAP3,
+ .pmic_data = &omap3_mpu_pmic,
+ .special_action = twl_set_sr,
+ },
+ {
+ .name = "core",
+ .cpu = PMIC_CPU_OMAP3,
+ .pmic_data = &omap3_core_pmic,
+ },
+ {
+ .name = "mpu",
+ .cpu = PMIC_CPU_OMAP4430,
+ .pmic_data = &twl6030_vcore1_pmic,
+ },
+ {
+ .name = "core",
+ .cpu = PMIC_CPU_OMAP4430,
+ .pmic_data = &twl6030_vcore3_pmic,
+ },
+ {
+ .name = "core",
+ .cpu = PMIC_CPU_OMAP4460,
+ .pmic_data = &twl6030_vcore1_pmic,
+ },
+ {
+ .name = "iva",
+ .cpu = PMIC_CPU_OMAP44XX,
+ .pmic_data = &twl6030_vcore2_pmic,
+ },
+ /* Terminator */
+ { .name = NULL, .pmic_data = NULL},
+};
- return 0;
+int __init omap_twl_init(void)
+{
+ return omap_pmic_register_data(omap_twl_map);
}
/**
@@ -122,15 +122,10 @@ static inline void omap_enable_smartreflex_on_init(void) {}
#endif
#ifdef CONFIG_TWL4030_CORE
-extern int omap3_twl_init(void);
-extern int omap4_twl_init(void);
+extern int omap_twl_init(void);
extern int omap3_twl_set_sr_bit(bool enable);
#else
-static inline int omap3_twl_init(void)
-{
- return -EINVAL;
-}
-static inline int omap4_twl_init(void)
+static inline int omap_twl_init(void)
{
return -EINVAL;
}
@@ -97,11 +97,7 @@ void __init omap4_pmic_init(const char *pmic_type,
void __init omap_pmic_late_init(void)
{
- /* Init the OMAP TWL parameters (if PMIC has been registered) */
- if (pmic_i2c_board_info.irq)
- omap3_twl_init();
- if (omap4_i2c1_board_info[0].irq)
- omap4_twl_init();
+ omap_twl_init();
}
#if defined(CONFIG_ARCH_OMAP3)
@@ -538,3 +534,55 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
pmic_data->v2v1 = &omap4_v2v1_idata;
}
#endif /* CONFIG_ARCH_OMAP4 */
+
+/**
+ * omap_pmic_register_data() - Register the PMIC information to OMAP mapping
+ * @omap_pmic_maps: array ending with a empty element representing the maps
+ */
+int __init omap_pmic_register_data(struct omap_pmic_map *map)
+{
+ struct voltagedomain *voltdm;
+ int r;
+
+ if (!map)
+ return 0;
+
+ while (map->name) {
+ if (cpu_is_omap34xx() && !(map->cpu & PMIC_CPU_OMAP3))
+ goto next;
+
+ if (cpu_is_omap443x() && !(map->cpu & PMIC_CPU_OMAP4430))
+ goto next;
+
+ if (cpu_is_omap446x() && !(map->cpu & PMIC_CPU_OMAP4460))
+ goto next;
+
+ voltdm = voltdm_lookup(map->name);
+ if (IS_ERR_OR_NULL(voltdm)) {
+ pr_err("%s: unable to find map %s\n", __func__,
+ map->name);
+ goto next;
+ }
+ if (IS_ERR_OR_NULL(map->pmic_data)) {
+ pr_warn("%s: domain[%s] has no pmic data\n",
+ __func__, map->name);
+ goto next;
+ }
+
+ r = omap_voltage_register_pmic(voltdm, map->pmic_data);
+ if (r) {
+ pr_warn("%s: domain[%s] register returned %d\n",
+ __func__, map->name, r);
+ goto next;
+ }
+ if (map->special_action) {
+ r = map->special_action(voltdm);
+ WARN(r, "%s: domain[%s] action returned %d\n", __func__,
+ map->name, r);
+ }
+next:
+ map++;
+ }
+
+ return 0;
+}
@@ -2,6 +2,7 @@
#define __OMAP_PMIC_COMMON__
#include <plat/irqs.h>
+#include "voltage.h"
#define TWL_COMMON_PDATA_USB (1 << 0)
#define TWL_COMMON_PDATA_BCI (1 << 1)
@@ -59,4 +60,30 @@ void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags);
+/**
+ * struct omap_pmic_map - Describe the OMAP PMIC data for OMAP
+ * @name: name of the voltage domain
+ * @pmic_data: pmic data associated with it
+ * @cpu: CPUs this PMIC data is valid for
+ * @special_action: callback for any specific action to take for that map
+ *
+ * Since we support multiple PMICs each potentially functioning on multiple
+ * OMAP devices, we describe the parameters in a map allowing us to reuse the
+ * data as necessary.
+ */
+struct omap_pmic_map {
+ char *name;
+ struct omap_voltdm_pmic *pmic_data;
+ u32 cpu;
+ int (*special_action)(struct voltagedomain *);
+};
+
+#define PMIC_CPU_OMAP3 (1 << 0)
+#define PMIC_CPU_OMAP4430 (1 << 1)
+#define PMIC_CPU_OMAP4460 (1 << 2)
+#define PMIC_CPU_OMAP44XX (PMIC_CPU_OMAP4430 | PMIC_CPU_OMAP4460)
+
+extern int omap_pmic_register_data(struct omap_pmic_map *map);
+extern void omap_pmic_data_init(void);
+
#endif /* __OMAP_PMIC_COMMON__ */