0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/err.h>
0010 #include <linux/io.h>
0011 #include <linux/kernel.h>
0012
0013 #include "soc.h"
0014 #include "pm.h"
0015 #include "voltage.h"
0016
0017 #include <linux/init.h>
0018 #include "vc.h"
0019
0020
0021
0022
0023
0024
0025
0026
0027 static unsigned long omap_cpcap_vsel_to_uv(unsigned char vsel)
0028 {
0029 if (vsel > 0x44)
0030 vsel = 0x44;
0031 return (((vsel * 125) + 6000)) * 100;
0032 }
0033
0034
0035
0036
0037
0038
0039
0040
0041 static unsigned char omap_cpcap_uv_to_vsel(unsigned long uv)
0042 {
0043 if (uv < 600000)
0044 uv = 600000;
0045 else if (uv > 1450000)
0046 uv = 1450000;
0047 return DIV_ROUND_UP(uv - 600000, 12500);
0048 }
0049
0050 static struct omap_voltdm_pmic omap_cpcap_core = {
0051 .slew_rate = 4000,
0052 .step_size = 12500,
0053 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
0054 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
0055 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
0056 .vddmin = 900000,
0057 .vddmax = 1350000,
0058 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
0059 .i2c_slave_addr = 0x02,
0060 .volt_reg_addr = 0x00,
0061 .cmd_reg_addr = 0x01,
0062 .i2c_high_speed = false,
0063 .vsel_to_uv = omap_cpcap_vsel_to_uv,
0064 .uv_to_vsel = omap_cpcap_uv_to_vsel,
0065 };
0066
0067 static struct omap_voltdm_pmic omap_cpcap_iva = {
0068 .slew_rate = 4000,
0069 .step_size = 12500,
0070 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
0071 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
0072 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
0073 .vddmin = 900000,
0074 .vddmax = 1375000,
0075 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
0076 .i2c_slave_addr = 0x44,
0077 .volt_reg_addr = 0x0,
0078 .cmd_reg_addr = 0x01,
0079 .i2c_high_speed = false,
0080 .vsel_to_uv = omap_cpcap_vsel_to_uv,
0081 .uv_to_vsel = omap_cpcap_uv_to_vsel,
0082 };
0083
0084
0085
0086
0087
0088
0089
0090
0091 static unsigned long omap_max8952_vsel_to_uv(unsigned char vsel)
0092 {
0093 if (vsel > 0x3F)
0094 vsel = 0x3F;
0095 return (((vsel * 100) + 7700)) * 100;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105 static unsigned char omap_max8952_uv_to_vsel(unsigned long uv)
0106 {
0107 if (uv < 770000)
0108 uv = 770000;
0109 else if (uv > 1400000)
0110 uv = 1400000;
0111 return DIV_ROUND_UP(uv - 770000, 10000);
0112 }
0113
0114 static struct omap_voltdm_pmic omap443x_max8952_mpu = {
0115 .slew_rate = 16000,
0116 .step_size = 10000,
0117 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
0118 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
0119 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
0120 .vddmin = 900000,
0121 .vddmax = 1400000,
0122 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
0123 .i2c_slave_addr = 0x60,
0124 .volt_reg_addr = 0x03,
0125 .cmd_reg_addr = 0x03,
0126 .i2c_high_speed = false,
0127 .vsel_to_uv = omap_max8952_vsel_to_uv,
0128 .uv_to_vsel = omap_max8952_uv_to_vsel,
0129 };
0130
0131
0132
0133
0134
0135
0136
0137
0138 static unsigned long omap_fan535503_vsel_to_uv(unsigned char vsel)
0139 {
0140
0141 vsel &= 0x3F;
0142
0143 return (((vsel * 125) + 7500)) * 100;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153 static unsigned long omap_fan535508_vsel_to_uv(unsigned char vsel)
0154 {
0155
0156 vsel &= 0x3F;
0157
0158 if (vsel > 0x37)
0159 vsel = 0x37;
0160 return (((vsel * 125) + 7500)) * 100;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 static unsigned char omap_fan535503_uv_to_vsel(unsigned long uv)
0172 {
0173 unsigned char vsel;
0174 if (uv < 750000)
0175 uv = 750000;
0176 else if (uv > 1537500)
0177 uv = 1537500;
0178
0179 vsel = DIV_ROUND_UP(uv - 750000, 12500);
0180 return vsel | 0xC0;
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190 static unsigned char omap_fan535508_uv_to_vsel(unsigned long uv)
0191 {
0192 unsigned char vsel;
0193 if (uv < 750000)
0194 uv = 750000;
0195 else if (uv > 1437500)
0196 uv = 1437500;
0197
0198 vsel = DIV_ROUND_UP(uv - 750000, 12500);
0199 return vsel | 0xC0;
0200 }
0201
0202
0203 static struct omap_voltdm_pmic omap4_fan_core = {
0204 .slew_rate = 4000,
0205 .step_size = 12500,
0206 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
0207 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
0208 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
0209 .vddmin = 850000,
0210 .vddmax = 1375000,
0211 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
0212 .i2c_slave_addr = 0x4A,
0213 .i2c_high_speed = false,
0214 .volt_reg_addr = 0x01,
0215 .cmd_reg_addr = 0x01,
0216 .vsel_to_uv = omap_fan535508_vsel_to_uv,
0217 .uv_to_vsel = omap_fan535508_uv_to_vsel,
0218 };
0219
0220
0221 static struct omap_voltdm_pmic omap4_fan_iva = {
0222 .slew_rate = 4000,
0223 .step_size = 12500,
0224 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
0225 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
0226 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
0227 .vddmin = 850000,
0228 .vddmax = 1375000,
0229 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
0230 .i2c_slave_addr = 0x48,
0231 .volt_reg_addr = 0x01,
0232 .cmd_reg_addr = 0x01,
0233 .i2c_high_speed = false,
0234 .vsel_to_uv = omap_fan535503_vsel_to_uv,
0235 .uv_to_vsel = omap_fan535503_uv_to_vsel,
0236 };
0237
0238 int __init omap4_cpcap_init(void)
0239 {
0240 struct voltagedomain *voltdm;
0241
0242 if (!of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
0243 return -ENODEV;
0244
0245 voltdm = voltdm_lookup("mpu");
0246 omap_voltage_register_pmic(voltdm, &omap443x_max8952_mpu);
0247
0248 if (of_machine_is_compatible("motorola,droid-bionic")) {
0249 voltdm = voltdm_lookup("core");
0250 omap_voltage_register_pmic(voltdm, &omap_cpcap_core);
0251
0252 voltdm = voltdm_lookup("iva");
0253 omap_voltage_register_pmic(voltdm, &omap_cpcap_iva);
0254 } else {
0255 voltdm = voltdm_lookup("core");
0256 omap_voltage_register_pmic(voltdm, &omap4_fan_core);
0257
0258 voltdm = voltdm_lookup("iva");
0259 omap_voltage_register_pmic(voltdm, &omap4_fan_iva);
0260 }
0261
0262 return 0;
0263 }
0264
0265 static int __init cpcap_late_init(void)
0266 {
0267 omap4_vc_set_pmic_signaling(PWRDM_POWER_RET);
0268
0269 return 0;
0270 }
0271 omap_late_initcall(cpcap_late_init);