4 #include <asm/arch/regs_adi.h>
5 #include <asm/arch/adi_hal_internal.h>
6 #include <asm/arch/sprd_reg.h>
7 #include <asm/arch/sprd_eic.h>
8 #include <sprd_battery.h>
11 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0)
13 #define debugf(fmt, args...)
15 #define ADC_CAL_TYPE_NO 0
16 #define ADC_CAL_TYPE_NV 1
17 #define ADC_CAL_TYPE_EFUSE 2
19 extern int charger_connected(void);
20 extern int read_adc_calibration_data(char *buffer, int size);
21 extern int sci_efuse_calibration_get(unsigned int *p_cal_data);
22 extern int sprd_eic_request(unsigned offset);
23 extern int sprd_eic_get(unsigned offset);
24 extern void power_down_devices(unsigned pd_cmd);
27 uint16_t adc_voltage_table[2][2] = {
32 uint32_t adc_cal_flag = 0;
34 uint16_t sprdbat_auxadc2vbatvol(uint16_t adcvalue)
37 temp = adc_voltage_table[0][1] - adc_voltage_table[1][1];
38 temp = temp * (adcvalue - adc_voltage_table[0][0]);
39 temp = temp / (adc_voltage_table[0][0] - adc_voltage_table[1][0]);
41 debugf("uboot battery voltage:%d,adc4200:%d,adc3600:%d\n",
42 temp + adc_voltage_table[0][1], adc_voltage_table[0][0],
43 adc_voltage_table[1][0]);
45 return temp + adc_voltage_table[0][1];
48 void sprdchg_stop_charge(void)
50 ANA_REG_MSK_OR(ANA_REG_GLB_CHGR_CTRL0, BIT_CHGR_PD, BIT_CHGR_PD);
53 static void sprdchg_set_recharge(void)
55 ANA_REG_OR(ANA_REG_GLB_CHGR_CTRL2, BIT_RECHG);
58 void sprdchg_set_chg_cur(uint32_t chg_current)
62 if (chg_current < 1400) {
63 temp = ((chg_current - 300) / 50);
65 temp = ((chg_current - 1400) / 100);
69 sci_adi_clr(ANA_REG_GLB_CHGR_CTRL2, BIT_CHGR_CC_EN);
71 sci_adi_write(ANA_REG_GLB_CHGR_CTRL1,
72 BITS_CHGR_CC_I(temp), BITS_CHGR_CC_I(~0));
74 sci_adi_set(ANA_REG_GLB_CHGR_CTRL2, BIT_CHGR_CC_EN);
77 void sprdchg_start_charge() {
78 ANA_REG_OR(ANA_REG_GLB_CHGR_CTRL2, BIT_RECHG);
79 ANA_REG_OR(ANA_REG_GLB_CHGR_CTRL1, BIT_12|BIT_10);
82 uint32_t sprdbat_get_vbatauxadc_caltype(void)
87 #ifndef CONFIG_FDL2_BUILD
88 extern void sprd_ext_charger_init(void);
89 extern void sprd_ext_charger_uninit(void);
90 void sprdchg_lowbat_charge(void)
92 #ifdef CONFIG_SPRD_EXT_IC_POWER
93 sprd_ext_charger_init();
99 void sprdbat_lateinit(void)
101 #ifdef CONFIG_SPRD_EXT_IC_POWER
102 sprd_ext_charger_uninit();
111 /* used to get adc calibration data from nv or efuse */
112 void sprdbat_get_vbatauxadc_caldata(void)
114 unsigned int adc_data[64];
117 adc_cal_flag = ADC_CAL_TYPE_NO;
119 #ifndef FDL_CHG_SP8830
120 /* get voltage values from nv */
121 ret = read_adc_calibration_data((char *)adc_data, 48);
123 ((adc_data[2] & 0xFFFF) < 4500) && ((adc_data[2] & 0xFFFF) > 3000)
124 && ((adc_data[3] & 0xFFFF) < 4500)
125 && ((adc_data[3] & 0xFFFF) > 3000)) {
126 debugf("adc_para from nv is 0x%x 0x%x \n", adc_data[2],
128 adc_voltage_table[0][1] = adc_data[2] & 0xFFFF;
129 adc_voltage_table[0][0] = (adc_data[2] >> 16) & 0xFFFF;
130 adc_voltage_table[1][1] = adc_data[3] & 0xFFFF;
131 adc_voltage_table[1][0] = (adc_data[3] >> 16) & 0xFFFF;
132 adc_cal_flag = ADC_CAL_TYPE_NV;
135 /* get voltage values from efuse */
136 if (adc_cal_flag == ADC_CAL_TYPE_NO) {
137 ret = sci_efuse_calibration_get(adc_data);
139 debugf("adc_para from efuse is 0x%x 0x%x \n",
140 adc_data[0], adc_data[1]);
141 adc_voltage_table[0][1] = adc_data[0] & 0xFFFF;
142 adc_voltage_table[0][0] = (adc_data[0] >> 16) & 0xFFFF;
143 adc_voltage_table[1][1] = adc_data[1] & 0xFFFF;
144 adc_voltage_table[1][0] = (adc_data[1] >> 16) & 0xFFFF;
145 adc_cal_flag = ADC_CAL_TYPE_EFUSE;
151 #ifndef FDL_CHG_SP8830
152 int sprdchg_charger_is_adapter(void)
154 int ret = ADP_TYPE_UNKNOW;
156 charger_status = sci_adi_read(ANA_REG_GLB_CHGR_STATUS)
157 & (BIT_CDP_INT | BIT_DCP_INT | BIT_SDP_INT);
159 switch (charger_status) {
175 #define REGS_FGU_BASE SPRD_ANA_FPU_PHYS
176 #define REG_FGU_START SCI_ADDR(REGS_FGU_BASE, 0x0000)
177 #define REG_FGU_CONFIG SCI_ADDR(REGS_FGU_BASE, 0x0004)
178 #define REG_FGU_INT_EN SCI_ADDR(REGS_FGU_BASE, 0x0010)
179 #define REG_FGU_INT_CLR SCI_ADDR(REGS_FGU_BASE, 0x0014)
180 #define REG_FGU_VOLT_VAL SCI_ADDR(REGS_FGU_BASE, 0x0020)
181 #define REG_FGU_OCV_VAL SCI_ADDR(REGS_FGU_BASE, 0x0024)
182 #define REG_FGU_POCV_VAL SCI_ADDR(REGS_FGU_BASE, 0x0028)
183 #define REG_FGU_CURT_VAL SCI_ADDR(REGS_FGU_BASE, 0x002c)
184 #define REG_FGU_CURT_OFFSET SCI_ADDR(REGS_FGU_BASE, 0x0090)
185 #define BIT_VOLT_H_VALID ( BIT(12) )
186 #define BITS_VOLT_DUTY(_x_) ( (_x_) << 5 & (BIT(5)|BIT(6)) )
188 #define REG_FGU_USER_AREA_SET SCI_ADDR(REGS_FGU_BASE, 0x00A0)
189 #define REG_FGU_USER_AREA_CLEAR SCI_ADDR(REGS_FGU_BASE, 0x00A4)
190 #define REG_FGU_USER_AREA_STATUS SCI_ADDR(REGS_FGU_BASE, 0x00A8)
192 #define BITS_POWERON_TYPE_SHIFT 12
193 #define BITS_POWERON_TYPE(_x_) ( (_x_) << 12 & (0xF000))
194 #define BITS_RTC_AREA_SHIFT 0
195 #define BITS_RTC_AREA(_x_) ( (_x_) << 0 & (0xFFF) )
197 #define FIRST_POWERTON 0xF
198 #define NORMAIL_POWERTON 0x5
199 #define WDG_POWERTON 0xA
201 static void sprdfgu_rtc_reg_write(uint32_t val)
203 sci_adi_write(REG_FGU_USER_AREA_CLEAR, BITS_RTC_AREA(~val),
205 sci_adi_write(REG_FGU_USER_AREA_SET, BITS_RTC_AREA(val),
209 static uint32_t sprdfgu_rtc_reg_read(void)
211 return (sci_adi_read(REG_FGU_USER_AREA_STATUS) & BITS_RTC_AREA(~0)) >>
215 static void sprdfgu_poweron_type_write(uint32_t val)
217 sci_adi_write(REG_FGU_USER_AREA_CLEAR, BITS_POWERON_TYPE(~val),
218 BITS_POWERON_TYPE(~0));
219 sci_adi_write(REG_FGU_USER_AREA_SET, BITS_POWERON_TYPE(val),
220 BITS_POWERON_TYPE(~0));
223 static uint32_t sprdfgu_poweron_type_read(void)
225 return (sci_adi_read(REG_FGU_USER_AREA_STATUS) & BITS_POWERON_TYPE(~0))
226 >> BITS_POWERON_TYPE_SHIFT;
229 #define mdelay(_ms) udelay(_ms*1000)
230 unsigned int fgu_vol, fgu_cur;
232 unsigned int get_fgu_vol() {
236 unsigned int get_fgu_cur() {
240 void sprdfgu_init(void)
243 sci_adi_set(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_FGU_EN);
244 sci_adi_set(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_FGU_EN | BIT_RTC_FGUA_EN);
246 sci_adi_clr(REG_FGU_INT_EN, 0xFFFF); //disable int after watchdog reset
247 sci_adi_set(REG_FGU_INT_CLR, 0xFFFF);
248 sci_adi_write(REG_FGU_CURT_OFFSET, 0, ~0); //init offset after watchdog reset
252 fgu_vol = sci_adi_read(REG_FGU_VOLT_VAL);
253 fgu_cur = sci_adi_read(REG_FGU_CURT_VAL);
255 debugf("fgu_init fgu_vol 0x%x fgu_cur 0x%x \n", fgu_vol, fgu_cur);
258 int sprdbat_is_battery_connected(void)
260 printf("eica status bat%x\n", sprd_eic_get(EIC_BATDET));
262 return ! !sprd_eic_get(EIC_BATDET);
265 void sprdbat_init(void)
267 #ifdef CONFIG_SHARK_PAD_HW_V102
268 sprd_gpio_request(NULL, USB_CHG_EN);
269 sprd_gpio_direction_output(NULL, USB_CHG_EN, 1);
270 sprd_gpio_set(NULL, USB_CHG_EN, 1);
272 sprd_gpio_set(NULL, USB_CHG_EN, 0);
275 sprd_eic_request(EIC_BATDET); //enable battery detect eic
277 //set charge current 500mA(USB) or 600mA(AC)
278 if (charger_connected()) {
279 enum sprd_adapter_type adp_type = sprdchg_charger_is_adapter();
280 if (adp_type == ADP_TYPE_CDP || adp_type == ADP_TYPE_DCP) {
281 debugf("uboot adp AC\n");
282 // sprdchg_set_chg_cur(700);
284 debugf("uboot adp USB\n");
285 // sprdchg_set_chg_cur(450);
288 #if defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
289 sci_adi_write(ANA_REG_GLB_CHGR_CTRL2,
290 BITS_CHGR_DPM(3), BITS_CHGR_DPM(~0)); //fixed bug367845, only for 2723
293 sprdchg_set_recharge();
294 ANA_REG_OR(ANA_REG_GLB_CHGR_CTRL2, BIT_CHGR_CC_EN);
295 sprdchg_start_charge();
297 sprdbat_get_vbatauxadc_caldata();
299 //if battery do NOT connect, shutdown charge,maybe system poweroff
300 if (!sprdbat_is_battery_connected()) {
301 printf("battery unconnected shutdown charge!!!!!\n");
302 sprdchg_stop_charge();
304 if (charger_connected()) {
305 if ((FIRST_POWERTON == sprdfgu_poweron_type_read())
306 || (sprdfgu_rtc_reg_read() == 0xFFF)) {
307 sprdfgu_rtc_reg_write(0xFF);
309 sprdfgu_poweron_type_write(NORMAIL_POWERTON);
310 printf("charge first poweron reset!!!!!\n");
312 sprdchg_stop_charge();
313 power_down_devices(0);
317 if (sprdfgu_rtc_reg_read() == 0xFF) {
318 printf("secend poweron !!!!!\n");
319 sprdfgu_poweron_type_write(FIRST_POWERTON);
321 sprdfgu_rtc_reg_write(0xFFF);