4 #include <asm/arch/regs_adi.h>
5 #include <asm/arch/adi_hal_internal.h>
6 #include <asm/arch/sprd_reg.h>
7 #include <sprd_battery.h>
10 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0)
12 #define debugf(fmt, args...)
14 #define ADC_CAL_TYPE_NO 0
15 #define ADC_CAL_TYPE_NV 1
16 #define ADC_CAL_TYPE_EFUSE 2
18 extern int charger_connected(void);
19 extern int read_adc_calibration_data(char *buffer,int size);
20 extern int sci_efuse_calibration_get(unsigned int * p_cal_data);
21 uint16_t adc_voltage_table[2][2] = {
26 uint32_t adc_cal_flag = 0;
28 uint16_t sprdbat_auxadc2vbatvol(uint16_t adcvalue)
31 temp = adc_voltage_table[0][1] - adc_voltage_table[1][1];
32 temp = temp * (adcvalue - adc_voltage_table[0][0]);
33 temp = temp / (adc_voltage_table[0][0] - adc_voltage_table[1][0]);
35 debugf("uboot battery voltage:%d,adc4200:%d,adc3600:%d\n",
36 temp + adc_voltage_table[0][1], adc_voltage_table[0][0],
37 adc_voltage_table[1][0]);
39 return temp + adc_voltage_table[0][1];
42 void sprdchg_start_charge(void)
44 #if defined(CONFIG_SPX15) || defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
45 ANA_REG_MSK_OR(ANA_REG_GLB_CHGR_CTRL0, 0, BIT_CHGR_PD);
47 ANA_REG_MSK_OR(ANA_REG_GLB_CHGR_CTRL0, BIT_CHGR_PD_RTCCLR, (BIT_CHGR_PD_RTCCLR | BIT_CHGR_PD_RTCSET));
51 void sprdchg_stop_charge(void)
53 #if defined(CONFIG_SPX15) || defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
54 ANA_REG_MSK_OR(ANA_REG_GLB_CHGR_CTRL0, BIT_CHGR_PD, BIT_CHGR_PD);
56 ANA_REG_MSK_OR(ANA_REG_GLB_CHGR_CTRL0, BIT_CHGR_PD_RTCSET, (BIT_CHGR_PD_RTCCLR | BIT_CHGR_PD_RTCSET));
60 static void sprdchg_set_recharge(void)
62 ANA_REG_OR(ANA_REG_GLB_CHGR_CTRL2, BIT_RECHG);
64 void sprdchg_set_chg_cur(uint32_t chg_current)
68 if (chg_current < 1400) {
69 temp = ((chg_current - 300) / 50);
71 temp = ((chg_current - 1400) / 100);
75 sci_adi_clr(ANA_REG_GLB_CHGR_CTRL2, BIT_CHGR_CC_EN);
77 sci_adi_write(ANA_REG_GLB_CHGR_CTRL1,
78 BITS_CHGR_CC_I(temp), BITS_CHGR_CC_I(~0));
80 sci_adi_set(ANA_REG_GLB_CHGR_CTRL2, BIT_CHGR_CC_EN);
83 uint32_t sprdbat_get_vbatauxadc_caltype(void)
88 #ifndef CONFIG_FDL2_BUILD
89 extern void sprd_ext_charger_init(void);
90 extern void sprd_ext_charger_uninit(void);
91 void sprdchg_lowbat_charge(void)
93 #ifdef CONFIG_SPRD_EXT_IC_POWER
94 sprd_ext_charger_init();
100 void sprdbat_lateinit(void)
102 #ifdef CONFIG_SPRD_EXT_IC_POWER
103 sprd_ext_charger_uninit();
113 /* used to get adc calibration data from nv or efuse */
114 void sprdbat_get_vbatauxadc_caldata(void)
116 unsigned int adc_data[64];
119 adc_cal_flag = ADC_CAL_TYPE_NO;
121 #ifndef FDL_CHG_SP8830
122 /* get voltage values from nv */
123 ret = read_adc_calibration_data((char *)adc_data,48);
125 ((adc_data[2] & 0xFFFF) < 4500 ) && ((adc_data[2] & 0xFFFF) > 3000) &&
126 ((adc_data[3] & 0xFFFF) < 4500 ) && ((adc_data[3] & 0xFFFF) > 3000)){
127 debugf("adc_para from nv is 0x%x 0x%x \n",adc_data[2],adc_data[3]);
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",adc_data[0],adc_data[1]);
140 adc_voltage_table[0][1]=adc_data[0] & 0xFFFF;
141 adc_voltage_table[0][0]=(adc_data[0]>>16) & 0xFFFF;
142 adc_voltage_table[1][1]=adc_data[1] & 0xFFFF;
143 adc_voltage_table[1][0]=(adc_data[1] >> 16) & 0xFFFF;
144 adc_cal_flag = ADC_CAL_TYPE_EFUSE;
150 #ifndef FDL_CHG_SP8830
151 int sprdchg_charger_is_adapter(void)
153 int ret = ADP_TYPE_UNKNOW;
155 charger_status = sci_adi_read(ANA_REG_GLB_CHGR_STATUS)
156 & (BIT_CDP_INT | BIT_DCP_INT | BIT_SDP_INT);
158 switch (charger_status) {
174 #define REGS_FGU_BASE SPRD_ANA_FPU_PHYS
175 #define REG_FGU_START SCI_ADDR(REGS_FGU_BASE, 0x0000)
176 #define REG_FGU_CONFIG SCI_ADDR(REGS_FGU_BASE, 0x0004)
177 #define REG_FGU_INT_EN SCI_ADDR(REGS_FGU_BASE, 0x0010)
178 #define REG_FGU_INT_CLR SCI_ADDR(REGS_FGU_BASE, 0x0014)
179 #define REG_FGU_VOLT_VAL SCI_ADDR(REGS_FGU_BASE, 0x0020)
180 #define REG_FGU_OCV_VAL SCI_ADDR(REGS_FGU_BASE, 0x0024)
181 #define REG_FGU_POCV_VAL SCI_ADDR(REGS_FGU_BASE, 0x0028)
182 #define REG_FGU_CURT_VAL SCI_ADDR(REGS_FGU_BASE, 0x002c)
183 #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 mdelay(_ms) udelay(_ms*1000)
189 unsigned int fgu_vol, fgu_cur;
190 void sprdfgu_init(void)
192 #if defined(CONFIG_SPX15) ||defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
193 //sci_adi_clr(ANA_REG_GLB_CHGR_DET_FGU_CTRL, (BIT_SD_CHOP_CAP_EN|BIT_CHOP_EN));
195 //sci_adi_set(ANA_REG_GLB_MP_MISC_CTRL, (BIT(1)));
196 sci_adi_write(ANA_REG_GLB_MP_MISC_CTRL, BIT(1), (BIT(1) | BIT(2)));
197 sci_adi_write(ANA_REG_GLB_DCDC_CTRL2, (4 << 8), (7 << 8));
199 sci_adi_set(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_FGU_EN);
200 sci_adi_set(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_FGU_EN | BIT_RTC_FGUA_EN);
205 sci_adi_set(ANA_REG_GLB_ARM_RST, BIT_ANA_FGU_SOFT_RST);
206 for (i = 0; i < 1000; i++) {;}
207 sci_adi_clr(ANA_REG_GLB_ARM_RST, BIT_ANA_FGU_SOFT_RST);
210 //sci_adi_clr(REG_FGU_INT_EN, 0xFFFF); //disable int after watchdog reset
211 //sci_adi_set(REG_FGU_INT_CLR, 0xFFFF);
212 //sci_adi_write(REG_FGU_CURT_OFFSET, 0, ~0); //init offset after watchdog reset
214 //sci_adi_clr(REG_FGU_CONFIG, BIT_VOLT_H_VALID);
215 //sci_adi_clr(REG_FGU_CONFIG, BIT_AD1_ENABLE);
216 #if defined(CONFIG_SPX15) ||defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
217 if(sci_get_adie_chip_id() < 0x2711A100) {
218 sci_adi_write(REG_FGU_CONFIG, BITS_VOLT_DUTY(3), BITS_VOLT_DUTY(3)|BIT_VOLT_H_VALID);
221 sci_adi_write(REG_FGU_CONFIG, BITS_VOLT_DUTY(3), BITS_VOLT_DUTY(3)|BIT_VOLT_H_VALID);
225 fgu_vol = 0; //sci_adi_read(REG_FGU_VOLT_VAL);
227 fgu_cur = 0; //sci_adi_read(REG_FGU_CURT_VAL);
228 debugf("fgu_init fgu_vol 0x%x fgu_cur 0x%x \n", fgu_vol, fgu_cur);
231 void sprdbat_init(void)
233 #ifdef CONFIG_SHARK_PAD_HW_V102
234 sprd_gpio_request(NULL,USB_CHG_EN);
235 sprd_gpio_direction_output(NULL, USB_CHG_EN, 1);
236 sprd_gpio_set(NULL, USB_CHG_EN, 1);
238 sprd_gpio_set(NULL, USB_CHG_EN, 0);
240 //set charge current 500mA(USB) or 600mA(AC)
241 if (charger_connected()) {
242 enum sprd_adapter_type adp_type = sprdchg_charger_is_adapter();
243 if (adp_type == ADP_TYPE_CDP || adp_type == ADP_TYPE_DCP) {
244 debugf("uboot adp AC\n");
245 sprdchg_set_chg_cur(700);
247 debugf("uboot adp USB\n");
248 sprdchg_set_chg_cur(500);
252 sprdchg_set_recharge();
253 ANA_REG_OR(ANA_REG_GLB_CHGR_CTRL2, BIT_CHGR_CC_EN);
254 sprdchg_start_charge();
256 sprdbat_get_vbatauxadc_caldata();