a8bb4d2fd666800865121d83b590e9e8a8496c86
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / power / sprd_2713_fgu.c
1 /*
2  * Copyright (C) 2013 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/interrupt.h>
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/wakelock.h>
19 #include <linux/hrtimer.h>
20 #include <linux/delay.h>
21 #include <linux/device.h>
22 #include <linux/gpio.h>
23 #include <linux/platform_device.h>
24 #include <linux/power_supply.h>
25
26 #include <soc/sprd/sci.h>
27 #include <soc/sprd/sci_glb_regs.h>
28 #include <soc/sprd/adi.h>
29 #include <soc/sprd/adc.h>
30
31 #include "sprd_2713_fgu.h"
32 #include "sprd_battery.h"
33 #include <linux/battery/fuelgauge/sprd27x3_fuelgauge4samsung.h>
34 #include <linux/battery/sec_charging_common.h>
35
36 #define REGS_FGU_BASE ANA_FPU_INT_BASE
37
38 /*
39  */
40 /* registers definitions for controller REGS_FGU */
41 #define REG_FGU_START                   SCI_ADDR(REGS_FGU_BASE, 0x0000)
42 #define REG_FGU_CONFIG                  SCI_ADDR(REGS_FGU_BASE, 0x0004)
43 #define REG_FGU_ADC_CONFIG              SCI_ADDR(REGS_FGU_BASE, 0x0008)
44 #define REG_FGU_STATUS                  SCI_ADDR(REGS_FGU_BASE, 0x000c)
45 #define REG_FGU_INT_EN                  SCI_ADDR(REGS_FGU_BASE, 0x0010)
46 #define REG_FGU_INT_CLR                 SCI_ADDR(REGS_FGU_BASE, 0x0014)
47 #define REG_FGU_INT_RAW                 SCI_ADDR(REGS_FGU_BASE, 0x0018)
48 #define REG_FGU_INT_STS                 SCI_ADDR(REGS_FGU_BASE, 0x001c)
49 #define REG_FGU_VOLT_VAL                SCI_ADDR(REGS_FGU_BASE, 0x0020)
50 #define REG_FGU_OCV_VAL                 SCI_ADDR(REGS_FGU_BASE, 0x0024)
51 #define REG_FGU_POCV_VAL                SCI_ADDR(REGS_FGU_BASE, 0x0028)
52 #define REG_FGU_CURT_VAL                SCI_ADDR(REGS_FGU_BASE, 0x002c)
53 #define REG_FGU_HIGH_OVER               SCI_ADDR(REGS_FGU_BASE, 0x0030)
54 #define REG_FGU_LOW_OVER                SCI_ADDR(REGS_FGU_BASE, 0x0034)
55 #define REG_FGU_VTHRE_HH                SCI_ADDR(REGS_FGU_BASE, 0x0038)
56 #define REG_FGU_VTHRE_HL                SCI_ADDR(REGS_FGU_BASE, 0x003c)
57 #define REG_FGU_VTHRE_LH                SCI_ADDR(REGS_FGU_BASE, 0x0040)
58 #define REG_FGU_VTHRE_LL                SCI_ADDR(REGS_FGU_BASE, 0x0044)
59 #define REG_FGU_OCV_LOCKLO              SCI_ADDR(REGS_FGU_BASE, 0x0048)
60 #define REG_FGU_OCV_LOCKHI              SCI_ADDR(REGS_FGU_BASE, 0x004c)
61 #define REG_FGU_CLBCNT_SETH             SCI_ADDR(REGS_FGU_BASE, 0x0050)
62 #define REG_FGU_CLBCNT_SETL             SCI_ADDR(REGS_FGU_BASE, 0x0054)
63 #define REG_FGU_CLBCNT_DELTH          SCI_ADDR(REGS_FGU_BASE, 0x0058)
64 #define REG_FGU_CLBCNT_DELTL           SCI_ADDR(REGS_FGU_BASE, 0x005c)
65 #define REG_FGU_CLBCNT_LASTOCVH         SCI_ADDR(REGS_FGU_BASE, 0x0060)
66 #define REG_FGU_CLBCNT_LASTOCVL         SCI_ADDR(REGS_FGU_BASE, 0x0064)
67 #define REG_FGU_CLBCNT_VALH             SCI_ADDR(REGS_FGU_BASE, 0x0068)
68 #define REG_FGU_CLBCNT_VALL             SCI_ADDR(REGS_FGU_BASE, 0x006c)
69 #define REG_FGU_CLBCNT_QMAXH            SCI_ADDR(REGS_FGU_BASE, 0x0070)
70 #define REG_FGU_CLBCNT_QMAXL            SCI_ADDR(REGS_FGU_BASE, 0x0074)
71 #define REG_FGU_QMAX_TOSET        SCI_ADDR(REGS_FGU_BASE, 0x0078)
72 #define REG_FGU_QMAX_TIMER          SCI_ADDR(REGS_FGU_BASE, 0x007c)
73 #define REG_FGU_RELAX_CURT_THRE         SCI_ADDR(REGS_FGU_BASE, 0x0080)
74 #define REG_FGU_RELAX_CNT_THRE          SCI_ADDR(REGS_FGU_BASE, 0x0084)
75 #define REG_FGU_RELAX_CNT               SCI_ADDR(REGS_FGU_BASE, 0x0088)
76 #define REG_FGU_OCV_LAST_CNT            SCI_ADDR(REGS_FGU_BASE, 0x008c)
77 #define REG_FGU_CURT_OFFSET             SCI_ADDR(REGS_FGU_BASE, 0x0090)
78
79 #define REG_FGU_USER_AREA_SET             SCI_ADDR(REGS_FGU_BASE, 0x00A0)
80 #define REG_FGU_USER_AREA_CLEAR             SCI_ADDR(REGS_FGU_BASE, 0x00A4)
81 #define REG_FGU_USER_AREA_STATUS             SCI_ADDR(REGS_FGU_BASE, 0x00A8)
82
83 #define BITS_POWERON_TYPE(_x_)           ( (_x_) << 12 & (0xF000))
84 #define BITS_RTC_AREA(_x_)           ( (_x_) << 0 & (0xFFF) )
85
86 /* bits definitions for register REG_FGU_START */
87 #define BIT_QMAX_UPDATE_EN              ( BIT(2) )
88 #define BIT_FGU_RESET                   ( BIT(1) )
89 #define BIT_WRITE_SELCLB_EN             ( BIT(0) )
90
91 /* bits definitions for register REG_FGU_CONFIG */
92 #define BIT_VOLT_H_VALID                ( BIT(12) )
93 #define BIT_FGU_DISABLE_EN              ( BIT(11) )
94 #define BIT_CLBCNT_DELTA_MODE           ( BIT(10) )
95 #define BITS_ONEADC_DUTY(_x_)           ( (_x_) << 8 & (BIT(8)|BIT(9)) )
96 #define BIT_CURT_DUTY                   ( BIT(7) )
97 #define BITS_VOLT_DUTY(_x_)             ( (_x_) << 5 & (BIT(5)|BIT(6)) )
98 #define BIT_AD1_ENABLE                  ( BIT(4) )
99 #define BIT_SW_DIS_CURT                 ( BIT(3) )
100 #define BIT_FORCE_LOCK_EN               ( BIT(2) )
101 #define BIT_LOW_POWER_MODE              ( BIT(1) )
102 #define BIT_AUTO_LOW_POWER              ( BIT(0) )
103
104 /* bits definitions for register REG_FGU_ADC_CONFIG */
105 #define BIT_FORCE_AD1_VIN_EN            ( BIT(7) )
106 #define BIT_FORCE_AD0_VIN_EN            ( BIT(6) )
107 #define BIT_FORCE_AD0_IIN_EN            ( BIT(5) )
108 #define BIT_FORCE_AD_EN                 ( BIT(4) )
109 #define BIT_AD1_VOLT_REF                ( BIT(3) )
110 #define BIT_AD0_VOLT_REF                ( BIT(2) )
111 #define BIT_AD01_RESET                  ( BIT(1) )
112 #define BIT_AD01_PD                     ( BIT(0) )
113
114 /* bits definitions for register REG_FGU_STATUS */
115 #define BIT_POWER_LOW                   ( BIT(5) )
116 #define BIT_CURT_LOW                    ( BIT(4) )
117 #define BITS_OCV_LOCK_STS(_x_)          ( (_x_) << 2 & (BIT(2)|BIT(3)) )
118 #define BIT_QMAX_UPDATE_STS             ( BIT(1) )
119 #define BIT_WRITE_ACTIVE_STS            ( BIT(0) )
120
121 /* bits definitions for register REG_FGU_INT_EN */
122 #define BIT_CURT_RDEN_INT               ( BIT(7) )
123 #define BIT_VOLT_RDEN_INT               ( BIT(6) )
124 #define BIT_QMAX_UPD_TOUT               ( BIT(5) )
125 #define BIT_QMAX_UPD_DONE               ( BIT(4) )
126 #define BIT_RELX_CNT_INT                ( BIT(3) )
127 #define BIT_CLBCNT_DELTA_INT            ( BIT(2) )
128 #define BIT_VOLT_HIGH_INT               ( BIT(1) )
129 #define BIT_VOLT_LOW_INT                ( BIT(0) )
130
131 #define BITS_VOLT_VALUE(_x_)            ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)) )
132
133 /* bits definitions for register REG_FGU_CURT_VAL */
134 #define BITS_CURT_VALUE(_x_)            ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)) )
135
136 /* bits definitions for register REG_FGU_CLBCNT_SETH */
137 #define BITS_CLBCNT_SETH(_x_)           ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)) )
138
139 /* bits definitions for register REG_FGU_CLBCNT_SETL */
140 #define BITS_CLBCNT_SETL(_x_)           ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)|BIT(14)|BIT(15)) )
141
142 /* bits definitions for register REG_FGU_CLBCNT_DELTHAH */
143 #define BITS_CLBCNT_DELTHH(_x_)         ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)) )
144
145 /* bits definitions for register REG_FGU_CLBCNT_DELTAL */
146 #define BITS_CLBCNT_DELTHL(_x_)         ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)|BIT(14)|BIT(15)) )
147
148 /* bits definitions for register REG_FGU_RELAX_CURT_THRE */
149 #define BITS_RELAX_CUR_THRE(_x_)        ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)) )
150
151 /* bits definitions for register REG_FGU_RELAX_CNT_THRE */
152 #define BITS_RELAX_CNT_THRE(_x_)        ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)) )
153
154 /* bits definitions for register REG_FGU_RELAX_CNT */
155 #define BITS_RELAX_CNT_VAL(_x_)         ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)) )
156
157 /* bits definitions for register REG_FGU_OCV_LAST_CNT */
158 #define BITS_OCV_LAST_CNT(_x_)          ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)) )
159
160 /* bits definitions for register REG_FGU_CURT_OFFSET */
161 #define BITS_CURT_OFFSET_VAL(_x_)       ( (_x_) << 0 & (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9)|BIT(10)|BIT(11)|BIT(12)|BIT(13)) )
162
163 #define SPRDFGU__DEBUG
164 #ifdef SPRDFGU__DEBUG
165 #define FGU_DEBUG(format, arg...) do{\
166     pr_info("sprdfgu: " format, ## arg);\
167     }while(0)
168 #else
169 #define FGU_DEBUG(format, arg...)
170 #endif
171
172 #define SPRDFGU_TEMP_COMP_SOC
173
174 #define SPRDFGU_OCV_VALID_TIME    20
175
176 #define CUR_0ma_IDEA_ADC    8192
177
178 #define FGU_CUR_SAMPLE_HZ   2
179
180 #define FIRST_POWERTON  0xF
181 #define NORMAIL_POWERTON  0x5
182 #define WDG_POWERTON  0xA
183 struct sprdfgu_drivier_data {
184         struct sprd_battery_platform_data *pdata;
185         int adp_status;
186         int warning_cap;
187         int shutdown_vol;
188         int bat_full_vol;
189         int cur_rint;
190         int poweron_rint;
191         int init_cap;
192         int init_clbcnt;
193         unsigned int int_status;
194         struct delayed_work fgu_irq_work;
195         struct power_supply sprdfgu;
196         struct mutex lock;
197         struct wake_lock low_power_lock;
198 };
199
200 struct sprdfgu_drivier_data sprdfgu_data;
201 struct sprdfgu_cal {
202         int cur_1000ma_adc;
203         int vol_1000mv_adc;
204         int cur_offset;
205         int vol_offset;
206         int cal_type;
207 };
208 static struct sprdfgu_cal fgu_cal = { 2872, 678, 0, 0, SPRDBAT_FGUADC_CAL_NO };
209
210 /*for debug*/
211 struct delayed_work sprdfgu_debug_work;
212 uint32_t sprdfgu_debug_log_time = 120;
213 static int poweron_clbcnt;
214 static u32 start_time;
215 /*for debug end*/
216
217 static int fgu_nv_4200mv = 2752;
218 static int fgu_nv_3600mv = 2374;
219 static int fgu_0_cur_adc = 8338;
220
221 static int cmd_vol_raw, cmd_cur_raw;
222
223 static BLOCKING_NOTIFIER_HEAD(fgu_chain_head);
224 extern int in_calibration(void);
225
226 #define REG_SYST_VALUE                  ((void __iomem *)(SPRD_SYSCNT_BASE + 0x0004))
227 static u32 sci_syst_read(void)
228 {
229 #if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))    //mingwei TODO
230         u32 t = __raw_readl(REG_SYST_VALUE);
231         while (t != __raw_readl(REG_SYST_VALUE))
232                 t = __raw_readl(REG_SYST_VALUE);
233         return t;
234 #else
235         return 0;
236 #endif
237 }
238
239 static int sprdfgu_vol2capacity(uint32_t voltage)
240 {
241         int percentum =
242             sprdbat_interpolate(voltage, sprdfgu_data.pdata->ocv_tab_size,
243                                 sprdfgu_data.pdata->ocv_tab);
244
245         return percentum;
246 }
247
248 static int __init fgu_cal_start(char *str)
249 {
250         unsigned int fgu_data[3] = { 0 };
251         char *cali_data = &str[1];
252         if (str) {
253                 printk("sprdfgu fgu_cal%s!\n", str);
254                 sscanf(cali_data, "%d,%d,%d", &fgu_data[0], &fgu_data[1],
255                        &fgu_data[2]);
256                 printk("sprdfgu fgu_data: 0x%x 0x%x,0x%x!\n", fgu_data[0],
257                        fgu_data[1], fgu_data[2]);
258                 fgu_nv_4200mv = (fgu_data[0] >> 16) & 0xffff;
259                 fgu_nv_3600mv = (fgu_data[1] >> 16) & 0xffff;
260                 fgu_0_cur_adc = fgu_data[2];
261                 fgu_cal.cal_type = SPRDBAT_FGUADC_CAL_NV;
262         }
263         return 1;
264 }
265
266 __setup("fgu_cal", fgu_cal_start);
267 static int __init fgu_cmd(char *str)
268 {
269         int fgu_data[2] = { 0 };
270         char *cali_data = &str[1];
271         if (str) {
272                 pr_info("fgu cmd%s!\n", str);
273                 sscanf(cali_data, "%d,%d", &fgu_data[0], &fgu_data[1]);
274                 pr_info("fgu_cmd adc_data: 0x%x 0x%x!\n", fgu_data[0],
275                         fgu_data[1]);
276                 cmd_vol_raw = fgu_data[0];
277                 cmd_cur_raw = fgu_data[1];
278         }
279         return 1;
280 }
281
282 __setup("fgu_init", fgu_cmd);
283
284 static int sprdfgu_cal_init(void)
285 {
286         BUG_ON(fgu_nv_4200mv <= fgu_nv_3600mv);
287         if (0 == fgu_nv_3600mv) {
288                 fgu_cal.vol_1000mv_adc =
289                     DIV_ROUND_CLOSEST((fgu_nv_4200mv) * 10, 42);
290                 fgu_cal.vol_offset = 0;
291                 fgu_cal.cur_offset = 0;
292                 fgu_cal.cur_1000ma_adc =
293                     DIV_ROUND_CLOSEST(fgu_cal.vol_1000mv_adc * 4 *
294                                       sprdfgu_data.pdata->rsense_real,
295                                       sprdfgu_data.pdata->rsense_spec);
296         } else {
297                 fgu_cal.vol_1000mv_adc =
298                     DIV_ROUND_CLOSEST((fgu_nv_4200mv - fgu_nv_3600mv) * 10, 6);
299                 fgu_cal.vol_offset =
300                     0 - (fgu_nv_4200mv * 10 - fgu_cal.vol_1000mv_adc * 42) / 10;
301                 fgu_cal.cur_offset = CUR_0ma_IDEA_ADC - fgu_0_cur_adc;
302                 fgu_cal.cur_1000ma_adc =
303                     DIV_ROUND_CLOSEST(fgu_cal.vol_1000mv_adc * 4 *
304                                       sprdfgu_data.pdata->rsense_real,
305                                       sprdfgu_data.pdata->rsense_spec);
306         }
307         if (SPRDBAT_FGUADC_CAL_CHIP == fgu_cal.cal_type) {
308                 fgu_cal.vol_offset += sprdfgu_data.pdata->fgu_cal_ajust;
309                 printk("sprdfgu: sprdfgu_data.pdata->fgu_cal_ajust = %d\n",
310                        sprdfgu_data.pdata->fgu_cal_ajust);
311         }
312
313         printk
314             ("sprdfgu: sprdfgu_cal_init fgu_nv_4200mv = %d,fgu_nv_3600mv = %d,fgu_0_cur_adc = %d\n",
315              fgu_nv_4200mv, fgu_nv_3600mv, fgu_0_cur_adc);
316         printk
317             ("sprdfgu: sprdfgu_cal_init fgu_cal.cur_1000ma_adc = %d,fgu_cal.vol_1000mv_adc = %d,fgu_cal.vol_offset = %d,fgu_cal.cur_offset = %d\n",
318              fgu_cal.cur_1000ma_adc, fgu_cal.vol_1000mv_adc, fgu_cal.vol_offset,
319              fgu_cal.cur_offset);
320         return 0;
321 }
322
323
324 #ifdef CONFIG_OTP_SPRD
325 int sci_efuse_fgu_cal_get(unsigned int *p_cal_data);
326 #endif
327 static int sprdfgu_cal_from_chip(void)
328 {
329         unsigned int fgu_data[4] = { 0 };
330
331 #ifdef CONFIG_OTP_SPRD
332         if (!sci_efuse_fgu_cal_get(fgu_data)) {
333                 printk("sprdfgu: sprdfgu_cal_from_chip efuse no cal data\n");
334                 return 1;
335         }
336 #endif
337         printk("sprdfgu fgu_data: 0x%x 0x%x,0x%x,0x%x!\n", fgu_data[0],
338                fgu_data[1], fgu_data[2], fgu_data[3]);
339         printk("sprdfgu: sprdfgu_cal_from_chip\n");
340
341         fgu_nv_4200mv = fgu_data[0];
342 #if defined(CONFIG_ADIE_SC2723) //2723 use one point to cal fgu adc
343         fgu_nv_3600mv = 0;
344         fgu_0_cur_adc = 0;
345 #else
346         fgu_nv_3600mv = fgu_data[1];
347         fgu_0_cur_adc = fgu_data[2];
348 #endif
349         fgu_cal.cal_type = SPRDBAT_FGUADC_CAL_CHIP;
350
351         return 0;
352 }
353
354 static u32 sprdfgu_adc2vol_mv(u32 adc)
355 {
356         return ((adc + fgu_cal.vol_offset) * 1000) / fgu_cal.vol_1000mv_adc;
357 }
358
359 static u32 sprdfgu_vol2adc_mv(u32 vol)
360 {
361         return (vol * fgu_cal.vol_1000mv_adc) / 1000 - fgu_cal.vol_offset;
362 }
363
364 static int sprdfgu_adc2cur_ma(int adc)
365 {
366         return (adc * 1000) / fgu_cal.cur_1000ma_adc;
367 }
368
369 static u32 sprdfgu_cur2adc_ma(u32 cur)
370 {
371         return (cur * fgu_cal.cur_1000ma_adc) / 1000;
372 }
373
374 #if defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
375 static void sprdfgu_rtc_reg_write(uint32_t val)
376 {
377         sci_adi_write(REG_FGU_USER_AREA_CLEAR, BITS_RTC_AREA(~val),
378                       BITS_RTC_AREA(~0));
379         sci_adi_write(REG_FGU_USER_AREA_SET, BITS_RTC_AREA(val),
380                       BITS_RTC_AREA(~0));
381 }
382
383 static uint32_t sprdfgu_rtc_reg_read(void)
384 {
385         int shft = __ffs(BITS_RTC_AREA(~0));
386         return (sci_adi_read(REG_FGU_USER_AREA_STATUS) & BITS_RTC_AREA(~0)) >>
387             shft;
388 }
389
390 static void sprdfgu_poweron_type_write(uint32_t val)
391 {
392         sci_adi_write(REG_FGU_USER_AREA_CLEAR, BITS_POWERON_TYPE(~val),
393                       BITS_POWERON_TYPE(~0));
394         sci_adi_write(REG_FGU_USER_AREA_SET, BITS_POWERON_TYPE(val),
395                       BITS_POWERON_TYPE(~0));
396 }
397
398 static uint32_t sprdfgu_poweron_type_read(void)
399 {
400         int shft = __ffs(BITS_POWERON_TYPE(~0));
401         return (sci_adi_read(REG_FGU_USER_AREA_STATUS) & BITS_POWERON_TYPE(~0))
402             >> shft;
403 }
404 #endif
405 static inline int sprdfgu_clbcnt_get(void)
406 {
407         volatile int cc1 = 0, cc2 = 1;
408
409         do {
410                 cc1 = (sci_adi_read(REG_FGU_CLBCNT_VALL)) & 0xFFFF;
411                 cc1 |= (((sci_adi_read(REG_FGU_CLBCNT_VALH)) & 0xFFFF) << 16);
412
413                 cc2 = (sci_adi_read(REG_FGU_CLBCNT_VALL)) & 0xFFFF;
414                 cc2 |= (((sci_adi_read(REG_FGU_CLBCNT_VALH)) & 0xFFFF) << 16);
415         } while (cc1 != cc2);
416
417         //FGU_DEBUG("sprdfgu_clbcnt_get cc: %d\n", cc1);
418         return cc1;
419 }
420
421 static inline int sprdfgu_clbcnt_set(int clbcc)
422 {
423         sci_adi_write(REG_FGU_CLBCNT_SETL, clbcc & 0xFFFF, ~0);
424         sci_adi_write(REG_FGU_CLBCNT_SETH, (clbcc >> 16) & 0xFFFF, ~0);
425         sci_adi_set(REG_FGU_START, BIT_WRITE_SELCLB_EN);
426         udelay(130);
427         return 0;
428 }
429
430 static inline int sprdfgu_reg_get(unsigned long reg)
431 {
432         volatile int vaule;
433
434         do {
435                 vaule = sci_adi_read(reg);
436         } while (vaule != sci_adi_read(reg));
437
438         return vaule;
439 }
440
441 static inline int sprdfgu_clbcnt_init(u32 capacity)
442 {
443         int init_cap =
444             DIV_ROUND_CLOSEST(sprdfgu_data.pdata->cnom * capacity, 100);
445         int clbcnt =
446             DIV_ROUND_CLOSEST(init_cap * fgu_cal.cur_1000ma_adc * 36 *
447                               FGU_CUR_SAMPLE_HZ, 10);
448         return clbcnt;
449 }
450
451 static inline void sprdfgu_soc_adjust(int capacity)
452 {
453         sprdfgu_data.init_cap = capacity;
454         sprdfgu_data.init_clbcnt = sprdfgu_clbcnt_get();
455         FGU_DEBUG("sprdfgu_soc_adjust sprdfgu_data.init_cap= %d,%d\n",
456                   sprdfgu_data.init_cap, sprdfgu_data.init_clbcnt);
457 }
458
459 uint32_t sprdfgu_read_vbat_vol(void)
460 {
461         u32 cur_vol_raw;
462         uint32_t temp;
463         cur_vol_raw = sprdfgu_reg_get(REG_FGU_VOLT_VAL);
464         //FGU_DEBUG("cur_vol_raw = %d\n", cur_vol_raw);
465         temp = sprdfgu_adc2vol_mv(cur_vol_raw);
466         //FGU_DEBUG("sprdfgu_read_vbat_vol : %d\n", temp);
467         return temp;
468 }
469
470 static inline u32 sprdfgu_ocv_vol_get(void)
471 {
472         u32 ocv_vol_raw;
473         ocv_vol_raw = sprdfgu_reg_get(REG_FGU_OCV_VAL);
474         //FGU_DEBUG("ocv_vol_raw = %x\n", ocv_vol_raw);
475         return sprdfgu_adc2vol_mv(ocv_vol_raw);
476 }
477
478 static inline int sprdfgu_cur_current_get(void)
479 {
480         int current_raw;
481
482         current_raw = sprdfgu_reg_get(REG_FGU_CURT_VAL);
483         //FGU_DEBUG("current_raw: %d\n", current_raw);
484
485         return sprdfgu_adc2cur_ma(current_raw - CUR_0ma_IDEA_ADC);
486 }
487
488 int sprdfgu_read_batcurrent(void)
489 {
490 #ifndef CONFIG_SPRD_NOFGUCURRENT_CHG
491         int temp = sprdfgu_cur_current_get();
492         //FGU_DEBUG("sprdfgu_read_batcurrent : %d\n", temp);
493         return temp;
494 #else
495         return 0;
496 #endif
497 }
498
499 static int sprdfgu_read_vbat_ocv_pure(uint32_t * vol)
500 {
501         if (sprdfgu_reg_get(REG_FGU_OCV_LAST_CNT) > SPRDFGU_OCV_VALID_TIME
502             || sprdfgu_reg_get(REG_FGU_OCV_VAL) == 0) {
503                 *vol = 0;
504                 return 0;
505         }
506         *vol = sprdfgu_ocv_vol_get();
507         return 1;
508 }
509
510 uint32_t sprdfgu_read_vbat_ocv(void)
511 {
512 #ifndef CONFIG_SPRD_NOFGUCURRENT_CHG
513         uint32_t vol;
514         int rint = sprdfgu_data.cur_rint;
515
516 #ifdef SPRDFGU_TEMP_COMP_SOC
517         {
518                 union power_supply_propval value;
519                 psy_do_property("battery", get, POWER_SUPPLY_PROP_TEMP, value);
520                 rint = sprdbat_interpolate(value.intval/10, sprdfgu_data.pdata->rint_temp_tab_size,
521                         sprdfgu_data.pdata->rint_temp_tab);
522                 FGU_DEBUG("rint:%d,value.intval:%d\n", rint, value.intval);
523         }
524 #endif
525
526         if (sprdfgu_read_vbat_ocv_pure(&vol)) {
527                 FGU_DEBUG("hwocv...\n");
528                 return vol;
529         } else {
530                 return sprdfgu_read_vbat_vol() -
531                     (sprdfgu_read_batcurrent() * rint) / 1000;
532         }
533 #else
534         return sprdfgu_read_vbat_vol();
535 #endif
536 }
537
538 static int sprdfgu_temp_comp_soc(int soc, int temp)
539 {
540         int cnom_temp;
541         int comp_soc, delta_soc;
542
543         cnom_temp = 0;
544
545         cnom_temp = sprdbat_interpolate(temp, sprdfgu_data.pdata->cnom_temp_tab_size,
546                                 sprdfgu_data.pdata->cnom_temp_tab);
547         delta_soc =
548             (sprdfgu_data.pdata->cnom - cnom_temp) * 100 / sprdfgu_data.pdata->cnom;
549
550         comp_soc = (long)(soc - delta_soc) * 100 / (100 - delta_soc);
551
552         if (comp_soc < 0)
553                 comp_soc = 0;
554
555         if (comp_soc > 100)
556                 comp_soc = 100;
557
558         FGU_DEBUG("cnom_temp %d, delta_soc %d,comp_soc%d,soc %d,temp %d\n",
559                   cnom_temp, delta_soc, comp_soc, soc, temp);
560
561         return (comp_soc);
562 }
563
564 int sprdfgu_read_soc(void)
565 {
566         int cur_cc, cc_delta, capcity_delta, temp;
567         uint32_t cur_ocv;
568
569         mutex_lock(&sprdfgu_data.lock);
570
571         cur_cc = sprdfgu_clbcnt_get();
572         cc_delta = cur_cc - sprdfgu_data.init_clbcnt;
573         temp = DIV_ROUND_CLOSEST(cc_delta, (3600 * FGU_CUR_SAMPLE_HZ));
574         temp = sprdfgu_adc2cur_ma(temp);
575         FGU_DEBUG("sprdfgu_read_soc delta %dmAh,sprdfgu_data.init_clbcnt:%d\n",
576                   temp, sprdfgu_data.init_clbcnt);
577         capcity_delta = DIV_ROUND_CLOSEST(temp * 100, sprdfgu_data.pdata->cnom);
578         FGU_DEBUG("sprdfgu_read_soc delta capacity %d,full capacity %d\n",
579                   capcity_delta, sprdfgu_data.pdata->cnom);
580
581         capcity_delta += sprdfgu_data.init_cap;
582
583         FGU_DEBUG("sprdfgu_read_soc soc %d,sprdfgu_data.init_cap %d\n",
584                   capcity_delta, sprdfgu_data.init_cap);
585
586         cur_ocv = sprdfgu_read_vbat_ocv();
587         if (cur_ocv >= sprdfgu_data.bat_full_vol) {
588                 FGU_DEBUG("sprdfgu_read_soc cur_ocv %d\n", cur_ocv);
589                 if (capcity_delta < 100 || capcity_delta > 102) {
590                         capcity_delta = 100;
591                         sprdfgu_soc_adjust(100);
592                 }
593         }
594
595         if (capcity_delta > 100) {
596                 capcity_delta = 100;
597                 sprdfgu_soc_adjust(100);
598         }
599         if (capcity_delta <= sprdfgu_data.warning_cap
600             && cur_ocv > sprdfgu_data.pdata->alm_vol) {
601                 FGU_DEBUG("sprdfgu_read_soc soc low...\n");
602                 capcity_delta = sprdfgu_data.warning_cap + 1;
603                 sprdfgu_soc_adjust(capcity_delta);
604         } else if (capcity_delta <= 0 && cur_ocv > sprdfgu_data.shutdown_vol) {
605                 FGU_DEBUG("sprdfgu_read_soc soc 0...\n");
606                 capcity_delta = 1;
607                 sprdfgu_soc_adjust(capcity_delta);
608         } else if (cur_ocv < sprdfgu_data.shutdown_vol) {
609                 FGU_DEBUG("sprdfgu_read_soc vol 0...\n");
610                 capcity_delta = 0;
611                 sprdfgu_soc_adjust(capcity_delta);
612         } else if (capcity_delta > sprdfgu_data.warning_cap
613                    && cur_ocv < sprdfgu_data.pdata->alm_vol) {
614                 FGU_DEBUG("sprdfgu_read_soc high...\n");
615                 sprdfgu_soc_adjust(sprdfgu_vol2capacity(cur_ocv));
616                 capcity_delta = sprdfgu_vol2capacity(cur_ocv);
617         }
618
619 #ifdef SPRDFGU_TEMP_COMP_SOC
620             {
621                 union power_supply_propval value;
622                 psy_do_property("battery", get, POWER_SUPPLY_PROP_TEMP, value);
623                 capcity_delta =
624                     sprdfgu_temp_comp_soc(capcity_delta, value.intval / 10);
625             }
626 #endif
627
628 #ifdef SPRDFGU_TEMP_COMP_SOC
629         if (sprdfgu_read_vbat_vol() < sprdfgu_data.pdata->soft_vbat_uvlo) {
630             FGU_DEBUG("TEMP_COMP_SOC vol 0...\n");
631             capcity_delta = 0;
632             sprdfgu_soc_adjust(capcity_delta);
633         }
634 #endif
635
636         mutex_unlock(&sprdfgu_data.lock);
637         return capcity_delta;
638 }
639
640 //for debug only
641 int sprdfgu_avg_current_query(void)
642 {
643         int cur_cc, cc_delta, raw_avg, temp, curr_avg, capcity;
644         u32 cur_time = sci_syst_read();
645         u32 time_delta;
646
647         cur_cc = sprdfgu_clbcnt_get();
648         time_delta = cur_time - start_time;
649         cc_delta = cur_cc - poweron_clbcnt;
650         temp = time_delta / 500;
651         raw_avg = cc_delta / temp;
652
653         //FGU_DEBUG("start_time:%d,cur_time : %d,poweron_clbcnt: 0x%x,cur_cc:0x%x\n",
654         //        start_time, cur_time, poweron_clbcnt, cur_cc);
655         FGU_DEBUG("time_delta : %d,cc_delta: %d,raw_avg = %d\n", time_delta,
656                   cc_delta, raw_avg);
657         curr_avg = sprdfgu_adc2cur_ma(raw_avg);
658
659         temp = time_delta / 3600;
660         capcity = temp * curr_avg;
661         FGU_DEBUG("capcity/1000 capcity = :  %dmah\n", capcity);
662         return curr_avg;
663 }
664
665 static void sprdfgu_debug_works(struct work_struct *work)
666 {
667         FGU_DEBUG("dump fgu msg s\n");
668         if (!sprdfgu_data.pdata->fgu_mode) {
669                 FGU_DEBUG("avg current = %d\n", sprdfgu_avg_current_query());
670         }
671         FGU_DEBUG("vol:%d,softocv:%d,hardocv:%d,current%d,cal_type:%d\n",
672                   sprdfgu_read_vbat_vol(), sprdfgu_read_vbat_ocv(),
673                   sprdfgu_ocv_vol_get(), sprdfgu_cur_current_get(),
674                   fgu_cal.cal_type);
675         //FGU_DEBUG("pocv_raw = 0x%x,pocv_voltage = %d\n",
676         //        sci_adi_read(REG_FGU_POCV_VAL),
677         //        sprdfgu_adc2vol_mv(sci_adi_read(REG_FGU_POCV_VAL)));
678         //FGU_DEBUG("REG_FGU_CURT_OFFSET--- = %d\n",
679         //sci_adi_read(REG_FGU_CURT_OFFSET));
680         //FGU_DEBUG("REG_FGU_RELAX_CURT_THRE--- = %d\n",
681         //        sci_adi_read(REG_FGU_RELAX_CURT_THRE));
682         //FGU_DEBUG("REG_FGU_RELAX_CNT--- = %d\n",
683         //        sci_adi_read(REG_FGU_RELAX_CNT));
684         //FGU_DEBUG("REG_FGU_OCV_LAST_CNT--- = %d\n",
685         //        sci_adi_read(REG_FGU_OCV_LAST_CNT));
686         //FGU_DEBUG("REG_FGU_LOW_OVER--- = %d\n", sci_adi_read(REG_FGU_LOW_OVER));
687         //FGU_DEBUG("REG_FGU_CONFIG--- = 0x%x\n", sci_adi_read(REG_FGU_CONFIG));
688         //printk("ANA_REG_GLB_MP_MISC_CTRL 0x%x ,0x%x \n", sci_adi_read(ANA_REG_GLB_MP_MISC_CTRL), sci_adi_read(ANA_REG_GLB_DCDC_CTRL2));
689         if (!sprdfgu_data.pdata->fgu_mode) {
690                 FGU_DEBUG("soc():%d\n", sprdfgu_read_soc());
691         }
692         FGU_DEBUG("dump fgu msg e\n");
693         schedule_delayed_work(&sprdfgu_debug_work, sprdfgu_debug_log_time * HZ);
694 }
695
696 static void sprdfgu_cal_battery_impedance(void)
697 {
698         int delta_vol_raw;
699         int delta_current_raw;
700         int temp;
701         int impedance;
702
703         delta_vol_raw = sprdfgu_reg_get(REG_FGU_VOLT_VAL);
704         delta_current_raw = sprdfgu_reg_get(REG_FGU_CURT_VAL);
705 #if 0                           //use pocv and poci to caculate impedance
706         cmd_vol_raw = sprdfgu_reg_get(REG_FGU_POCV_VAL);
707         cmd_cur_raw = sprdfgu_reg_get(REG_FGU_CLBCNT_QMAXL) << 1;
708 #endif
709         printk("sprdfgu: fgu delta_vol_raw: 0x%x delta_current_raw 0x%x!\n",
710                delta_vol_raw, delta_current_raw);
711         printk("sprdfgu: fgu cmd_vol_raw: 0x%x cmd_cur_raw 0x%x!\n",
712                cmd_vol_raw, cmd_cur_raw);
713         if (0 == cmd_vol_raw || 0 == cmd_cur_raw) {
714                 printk(KERN_ERR
715                        "sprdfgu: sprdfgu_cal_battery_impedance warning.....!\n");
716                 return;
717         }
718         delta_vol_raw -= cmd_vol_raw;
719         delta_current_raw -= cmd_cur_raw;
720         delta_vol_raw = ((delta_vol_raw) * 1000) / fgu_cal.vol_1000mv_adc;
721         delta_current_raw = sprdfgu_adc2cur_ma(delta_current_raw);
722         printk("sprdfgu: delta vol delta_vol_raw: %d delta_current_raw %d!\n",
723                (delta_vol_raw), (delta_current_raw));
724         temp = (delta_vol_raw * 1000) / delta_current_raw;
725
726         impedance = abs(temp);
727         if (impedance > 100) {
728                 sprdfgu_data.poweron_rint = impedance;
729         } else {
730                 printk("sprdfgu: impedance warning: %d!\n", impedance);
731         }
732         printk("sprdfgu: fgu sprdfgu_data.poweron_rint: %d!\n",
733                sprdfgu_data.poweron_rint);
734 }
735
736 uint32_t sprdfgu_read_capacity(void)
737 {
738         int32_t voltage;
739         int cap;
740
741         if (sprdfgu_data.pdata->fgu_mode) {
742                 voltage = sprdfgu_read_vbat_ocv();
743                 cap = sprdfgu_vol2capacity(voltage);
744         } else {
745                 cap = sprdfgu_read_soc();
746         }
747         if (cap > 100)
748                 cap = 100;
749         else if (cap < 0)
750                 cap = 0;
751         return cap;
752 }
753
754 uint32_t sprdfgu_poweron_capacity(void)
755 {
756         return sprdfgu_data.init_cap;
757 }
758
759 void sprdfgu_adp_status_set(int plugin)
760 {
761         sprdfgu_data.adp_status = plugin;
762         if (plugin) {
763                 uint32_t adc;
764                 adc = sprdfgu_vol2adc_mv(sprdfgu_data.pdata->alm_vol);
765                 sci_adi_set(REG_FGU_INT_CLR, BIT_VOLT_LOW_INT);
766                 sci_adi_write(REG_FGU_LOW_OVER, adc & 0xFFFF, ~0);
767                 sci_adi_clr(REG_FGU_INT_EN, BIT_CLBCNT_DELTA_INT);
768         }
769 }
770
771 static void sprdfgu_irq_works(struct work_struct *work)
772 {
773         uint32_t cur_ocv;
774         uint32_t adc;
775         int cur_soc;
776
777         wake_lock_timeout(&(sprdfgu_data.low_power_lock), 2 * HZ);
778
779         printk("sprdfgu: sprdfgu_irq_works......0x%x.cur vol = %d\n",
780                sprdfgu_data.int_status, sprdfgu_read_vbat_vol());
781         if (sprdfgu_data.int_status & BIT_VOLT_HIGH_INT) {
782                 blocking_notifier_call_chain(&fgu_chain_head, 1, 0);
783         }
784
785         if (sprdfgu_data.int_status & BIT_VOLT_LOW_INT) {
786                 cur_soc = sprdfgu_read_soc();   //it must be at here
787                 mutex_lock(&sprdfgu_data.lock);
788
789                 cur_ocv = sprdfgu_read_vbat_ocv();
790                 if (cur_ocv <= sprdfgu_data.shutdown_vol) {
791                         printk
792                             ("sprdfgu: sprdfgu_irq_works...sprdfgu_data.shutdown_vol .\n");
793                         sprdfgu_soc_adjust(0);
794                 } else if (cur_ocv <= sprdfgu_data.pdata->alm_vol) {
795                         printk
796                             ("sprdfgu: sprdfgu_irq_works...sprdfgu_data.pdata->alm_vol %d.\n",
797                              cur_soc);
798                         if (cur_soc > sprdfgu_data.warning_cap) {
799                                 sprdfgu_soc_adjust(sprdfgu_data.warning_cap);
800                         } else if (cur_soc <= 0) {
801                                 sprdfgu_soc_adjust(sprdfgu_vol2capacity
802                                                    (cur_ocv));
803                         }
804                         if (!sprdfgu_data.adp_status) {
805                                 adc =
806                                     sprdfgu_vol2adc_mv
807                                     (sprdfgu_data.shutdown_vol);
808                                 sci_adi_write(REG_FGU_LOW_OVER, adc & 0xFFFF,
809                                               ~0);
810                         }
811                 } else {
812                         //todo?
813                 }
814                 mutex_unlock(&sprdfgu_data.lock);
815         }
816 }
817
818 static irqreturn_t _sprdfgu_interrupt(int irq, void *dev_id)
819 {
820         sprdfgu_data.int_status = sci_adi_read(REG_FGU_INT_STS);
821         sci_adi_set(REG_FGU_INT_CLR, sprdfgu_data.int_status);
822         printk
823             ("sprdfgu: _sprdfgu_interrupt.....raw..0x%x,sprdfgu_data.int_status0x%x\n",
824              sci_adi_read(REG_FGU_INT_RAW), sprdfgu_data.int_status);
825         schedule_delayed_work(&sprdfgu_data.fgu_irq_work, 0);
826         udelay(60);             //fix int bug
827         return IRQ_HANDLED;
828 }
829
830 static int sprdfgu_int_init(void)
831 {
832         uint32_t adc;
833         int delta_cc = sprdfgu_clbcnt_init(1);
834         int ret = -ENODEV;
835
836         INIT_DELAYED_WORK(&sprdfgu_data.fgu_irq_work, sprdfgu_irq_works);
837
838         sci_adi_set(REG_FGU_INT_CLR, 0xFFFF);
839
840         adc = sprdfgu_vol2adc_mv(sprdfgu_data.pdata->chg_bat_safety_vol);
841         sci_adi_write(REG_FGU_HIGH_OVER, adc & 0xFFFF, ~0);
842         adc = sprdfgu_vol2adc_mv(sprdfgu_data.pdata->alm_vol);
843         sci_adi_write(REG_FGU_LOW_OVER, adc & 0xFFFF, ~0);
844
845         sci_adi_write(REG_FGU_CLBCNT_DELTL, delta_cc & 0xFFFF, ~0);
846         sci_adi_write(REG_FGU_CLBCNT_DELTH, (delta_cc >> 16) & 0xFFFF, ~0);
847
848         ret = request_irq(sprdfgu_data.pdata->irq_fgu, _sprdfgu_interrupt,
849                           IRQF_NO_SUSPEND, "sprdfgu", NULL);
850
851         if (ret) {
852                 printk(KERN_ERR "sprdfgu: request sprdfgu irq %d failed\n",
853                        sprdfgu_data.pdata->irq_fgu);
854         }
855
856         sci_adi_set(REG_FGU_INT_EN, BIT_VOLT_HIGH_INT);
857         return 0;
858 }
859
860 void sprdfgu_pm_op(int is_suspend)
861 {
862         if (is_suspend) {
863                 if (!sprdfgu_data.adp_status) {
864                         sci_adi_set(REG_FGU_INT_EN, BIT_VOLT_LOW_INT);
865                         if (sprdfgu_read_vbat_ocv() <
866                             sprdfgu_data.pdata->alm_vol) {
867                                 sci_adi_set(REG_FGU_INT_CLR,
868                                             BIT_CLBCNT_DELTA_INT);
869                                 sci_adi_set(REG_FGU_INT_EN,
870                                             BIT_CLBCNT_DELTA_INT);
871                         }
872                 }
873         } else {
874                 sci_adi_clr(REG_FGU_INT_EN,
875                             BIT_VOLT_LOW_INT | BIT_CLBCNT_DELTA_INT);
876         }
877 }
878 int __weak in_calibration(void){return 0;}
879 static void sprdfgu_hw_init(void)
880 {
881         u32 cur_vol_raw, ocv_raw;
882         int current_raw;
883         u32 pocv_raw;
884         FGU_DEBUG("FGU_Init\n");
885
886 #if !defined(CONFIG_ARCH_SCX15) && !defined(CONFIG_ADIE_SC2723S) && !defined(CONFIG_ADIE_SC2723)
887         //sci_adi_set(ANA_REG_GLB_MP_MISC_CTRL, (BIT(1)));
888         //sci_adi_write(ANA_REG_GLB_DCDC_CTRL2, (4 << 8), (7 << 8));
889 #endif
890
891         sci_adi_set(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_FGU_EN);
892         sci_adi_set(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_FGU_EN | BIT_RTC_FGUA_EN);
893
894 #if !defined(CONFIG_ARCH_SCX15) && !defined(CONFIG_ADIE_SC2723S) && !defined(CONFIG_ADIE_SC2723)
895         sci_adi_write(REG_FGU_CONFIG, BITS_VOLT_DUTY(3), BITS_VOLT_DUTY(3) | BIT_VOLT_H_VALID); //mingwei
896 #endif
897         sci_adi_write(REG_FGU_RELAX_CURT_THRE, BITS_RELAX_CUR_THRE(sprdfgu_cur2adc_ma(sprdfgu_data.pdata->relax_current)), BITS_RELAX_CUR_THRE(~0));    //mingwei
898         udelay(130);
899         sprdfgu_cal_battery_impedance();
900         pocv_raw = sci_adi_read(REG_FGU_POCV_VAL);
901         cur_vol_raw = sprdfgu_reg_get(REG_FGU_VOLT_VAL);
902         ocv_raw = sprdfgu_reg_get(REG_FGU_OCV_VAL);
903         current_raw = sprdfgu_reg_get(REG_FGU_CURT_VAL);
904         start_time = sci_syst_read();
905
906 #if defined(CONFIG_ADIE_SC2723S) ||defined(CONFIG_ADIE_SC2723)
907         FGU_DEBUG("REG_FGU_USER_AREA_STATUS- = 0x%x\n",
908                   sci_adi_read(REG_FGU_USER_AREA_STATUS));
909         if ((FIRST_POWERTON == sprdfgu_poweron_type_read())
910             || (sprdfgu_rtc_reg_read() == 0xFFF) || (sprdfgu_rtc_reg_read() == 0)) {
911                 FGU_DEBUG("FIRST_POWERTON- = 0x%x\n",
912                           sprdfgu_poweron_type_read());
913 /*Remove battery from device when USB cable is connected, insert battery to device, battery voltage
914 is not same as it was before removal of battery.
915 SPRD patch : bug 456607
916 */
917 //#ifdef CONFIG_SPRD_EXT_IC_POWER
918                 if(gpio_get_value(sprdfgu_data.pdata->gpio_vchg_detect)){
919                         uint32_t soft_ocv = sprdfgu_read_vbat_vol() -
920                                                         (sprdfgu_adc2cur_ma
921                                                         (current_raw - CUR_0ma_IDEA_ADC +
922                                                         fgu_cal.cur_offset) * sprdfgu_data.poweron_rint) / 1000;
923
924                         sprdfgu_data.init_cap = sprdfgu_vol2capacity(soft_ocv);
925                         FGU_DEBUG
926                             ("Charger poweron soft_ocv:%d,sprdfgu_data.init_cap:%d\n",
927                              soft_ocv, sprdfgu_data.init_cap);
928                 } else
929 //#endif
930                 {
931                         int poci_raw =
932                             sprdfgu_reg_get(REG_FGU_CLBCNT_QMAXL) << 1;
933                         int poci_curr =
934                             sprdfgu_adc2cur_ma(poci_raw - CUR_0ma_IDEA_ADC +
935                                                fgu_cal.cur_offset);
936                         uint32_t p_ocv =
937                             sprdfgu_adc2vol_mv(pocv_raw) -
938                             (poci_curr * sprdfgu_data.poweron_rint) / 1000;
939                         sprdfgu_data.init_cap = sprdfgu_vol2capacity(p_ocv);
940                         FGU_DEBUG
941                             ("poci_raw:0x%x,poci_current:%d,p_softocv:%d,sprdfgu_data.init_cap:%d\n",
942                              poci_raw, poci_curr, p_ocv, sprdfgu_data.init_cap);
943                 }
944                 sprdfgu_rtc_reg_write(sprdfgu_data.init_cap);
945         } else {
946                 sprdfgu_data.init_cap = sprdfgu_rtc_reg_read();
947                 FGU_DEBUG("NORMAIL_POWERTON-- sprdfgu_data.init_cap= %d\n",
948                           sprdfgu_data.init_cap);
949         }
950         sprdfgu_poweron_type_write(NORMAIL_POWERTON);
951
952 #else
953         {
954                 int cnt = 50000;
955                 while((sprdfgu_read_vbat_vol() < 3000) && --cnt){
956                         FGU_DEBUG("voltage not ready = %d\n", sprdfgu_read_vbat_vol());
957                         udelay(100);
958                 }
959                 if(cnt <= 0) {
960                         printk(KERN_EMERG "sprdfgu: voltage error!!!!");
961                         BUG_ON(1);
962                 }
963         }
964         {
965                 uint32_t soft_ocv = sprdfgu_read_vbat_vol() -
966                     (sprdfgu_adc2cur_ma
967                      (current_raw - CUR_0ma_IDEA_ADC +
968                       fgu_cal.cur_offset) * sprdfgu_data.cur_rint) / 1000;
969                 sprdfgu_data.init_cap = sprdfgu_vol2capacity(soft_ocv);
970         }
971 #endif
972
973         sprdfgu_data.init_clbcnt = poweron_clbcnt =
974             sprdfgu_clbcnt_init(sprdfgu_data.init_cap);
975         sprdfgu_clbcnt_set(poweron_clbcnt);
976 #if  !defined(CONFIG_ADIE_SC2723S) && !defined(CONFIG_ADIE_SC2723)
977         if (!in_calibration()) {
978                 sci_adi_write(REG_FGU_CURT_OFFSET, fgu_cal.cur_offset, ~0);
979         }
980 #endif
981
982         FGU_DEBUG("pocv_raw = 0x%x,pocv_voltage = %d\n", pocv_raw,
983                   sprdfgu_adc2vol_mv(pocv_raw));
984         FGU_DEBUG("current voltage raw_data =  0x%x,cur voltage = %d\n",
985                   cur_vol_raw, sprdfgu_adc2vol_mv(cur_vol_raw));
986         FGU_DEBUG("ocv_raw: 0x%x,ocv voltage = %d\n", ocv_raw,
987                   sprdfgu_adc2vol_mv(ocv_raw));
988         FGU_DEBUG("current_raw: 0x%x,current = %d\n", current_raw,
989                   sprdfgu_adc2cur_ma(current_raw - CUR_0ma_IDEA_ADC));
990         FGU_DEBUG("poweron_clbcnt: 0x%x,cur_cc0x%x\n", poweron_clbcnt,
991                   sprdfgu_clbcnt_get());
992         FGU_DEBUG("sprdfgu_data.poweron_rint = %d\n", sprdfgu_data.poweron_rint);
993
994 }
995
996 int sprdfgu_register_notifier(struct notifier_block *nb)
997 {
998         return blocking_notifier_chain_register(&fgu_chain_head, nb);
999 }
1000
1001 int sprdfgu_unregister_notifier(struct notifier_block *nb)
1002 {
1003         return blocking_notifier_chain_unregister(&fgu_chain_head, nb);
1004 }
1005
1006 static ssize_t sprdfgu_store_attribute(struct device *dev,
1007                                        struct device_attribute *attr,
1008                                        const char *buf, size_t count);
1009 static ssize_t sprdfgu_show_attribute(struct device *dev,
1010                                       struct device_attribute *attr, char *buf);
1011
1012 #define SPRDFGU_ATTR(_name)                         \
1013 {                                       \
1014         .attr = { .name = #_name, .mode = S_IRUGO | S_IWUSR | S_IWGRP, },  \
1015         .show = sprdfgu_show_attribute,                  \
1016         .store = sprdfgu_store_attribute,                              \
1017 }
1018 #define SPRDFGU_ATTR_RO(_name)                         \
1019 {                                       \
1020         .attr = { .name = #_name, .mode = S_IRUGO, },  \
1021         .show = sprdfgu_show_attribute,                  \
1022 }
1023 #define SPRDFGU_ATTR_WO(_name)                         \
1024 {                                       \
1025         .attr = { .name = #_name, .mode = S_IWUSR | S_IWGRP, },  \
1026         .store = sprdfgu_store_attribute,                              \
1027 }
1028
1029 static struct device_attribute sprdfgu_attribute[] = {
1030         SPRDFGU_ATTR_RO(fgu_vol_adc),
1031         SPRDFGU_ATTR_RO(fgu_current_adc),
1032         SPRDFGU_ATTR_RO(fgu_vol),
1033         SPRDFGU_ATTR_RO(fgu_current),
1034         SPRDFGU_ATTR_WO(fgu_log_time),
1035         SPRDFGU_ATTR_RO(fgu_cal_from_type),
1036 };
1037
1038 enum SPRDFGU_ATTRIBUTE {
1039         FGU_VOL_ADC = 0,
1040         FGU_CURRENT_ADC,
1041         FGU_VOL,
1042         FGU_CURRENT,
1043         FGU_LOG_TIME,
1044         FGU_CAL_FROM_TYPE,
1045 };
1046
1047 static ssize_t sprdfgu_store_attribute(struct device *dev,
1048                                        struct device_attribute *attr,
1049                                        const char *buf, size_t count)
1050 {
1051         unsigned long set_value;
1052         const ptrdiff_t off = attr - sprdfgu_attribute;
1053
1054         set_value = simple_strtoul(buf, NULL, 10);
1055         pr_info("sprdfgu_store_attribute %lu %lu\n", off, set_value);
1056
1057         switch (off) {
1058         case FGU_LOG_TIME:
1059                 sprdfgu_debug_log_time = set_value;
1060                 break;
1061         default:
1062                 count = -EINVAL;
1063                 break;
1064         }
1065         return count;
1066 }
1067
1068 static ssize_t sprdfgu_show_attribute(struct device *dev,
1069                                       struct device_attribute *attr, char *buf)
1070 {
1071         int i = 0;
1072         const ptrdiff_t off = attr - sprdfgu_attribute;
1073
1074         switch (off) {
1075         case FGU_VOL_ADC:
1076                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
1077                                sci_adi_read(REG_FGU_VOLT_VAL));
1078                 break;
1079         case FGU_CURRENT_ADC:
1080                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
1081                                sci_adi_read(REG_FGU_CURT_VAL));
1082                 break;
1083         case FGU_VOL:
1084                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
1085                                sprdfgu_read_vbat_vol());
1086                 break;
1087         case FGU_CURRENT:
1088                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
1089                                sprdfgu_read_batcurrent());
1090                 break;
1091         case FGU_CAL_FROM_TYPE:
1092                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
1093                                fgu_cal.cal_type);
1094                 break;
1095
1096         default:
1097                 i = -EINVAL;
1098                 break;
1099         }
1100
1101         return i;
1102 }
1103
1104 static int sprdfgu_creat_attr(struct device *dev)
1105 {
1106         int i, rc;
1107
1108         for (i = 0; i < ARRAY_SIZE(sprdfgu_attribute); i++) {
1109                 rc = device_create_file(dev, &sprdfgu_attribute[i]);
1110                 if (rc)
1111                         goto sprd_attrs_failed;
1112         }
1113         goto sprd_attrs_succeed;
1114
1115 sprd_attrs_failed:
1116         while (i--)
1117                 device_remove_file(dev, &sprdfgu_attribute[i]);
1118
1119 sprd_attrs_succeed:
1120         return rc;
1121 }
1122
1123 static int sprdfgu_power_get_property(struct power_supply *psy,
1124                                       enum power_supply_property psp,
1125                                       union power_supply_propval *val)
1126 {
1127         return -EINVAL;
1128 }
1129
1130 int sprdfgu_init(struct sprd_battery_platform_data *pdata)
1131 {
1132         int ret = 0;
1133         int temp;
1134         //struct sprdbat_drivier_data *data = platform_get_drvdata(pdev);
1135
1136         sprdfgu_data.pdata = pdata;
1137         sprdfgu_data.warning_cap =
1138             sprdfgu_vol2capacity(sprdfgu_data.pdata->alm_vol);
1139         temp = sprdfgu_data.pdata->ocv_tab_size;
1140         sprdfgu_data.shutdown_vol = sprdfgu_data.pdata->ocv_tab[temp - 1].x;
1141
1142         sprdfgu_data.bat_full_vol = sprdfgu_data.pdata->ocv_tab[0].x;
1143         sprdfgu_data.cur_rint = sprdfgu_data.pdata->rint;
1144         sprdfgu_data.poweron_rint = sprdfgu_data.pdata->rint;
1145
1146 /*Remove battery from device when USB cable is connected, insert battery to device, battery voltage
1147 is not same as it was before revomal of battery.
1148 SPRD patch : bug 456607
1149 */
1150 //#ifdef CONFIG_SPRD_EXT_IC_POWER
1151         ret = gpio_request(sprdfgu_data.pdata->gpio_vchg_detect, "chg_vchg_detect");
1152         if (ret) {
1153                 FGU_DEBUG("Already request vchg gpio:%d\n",sprdfgu_data.pdata->gpio_vchg_detect);
1154         }
1155         gpio_direction_input(sprdfgu_data.pdata->gpio_vchg_detect);
1156 //#endif
1157
1158         if (fgu_cal.cal_type == SPRDBAT_FGUADC_CAL_NO) {
1159                 sprdfgu_cal_from_chip();        //try to find cal data from efuse
1160         }
1161         sprdfgu_cal_init();
1162         sprdfgu_hw_init();
1163
1164         sprdfgu_data.sprdfgu.name = "sprdfgu";
1165         sprdfgu_data.sprdfgu.get_property = sprdfgu_power_get_property;
1166         ret = power_supply_register(NULL, &sprdfgu_data.sprdfgu);
1167         if (ret) {
1168                 pr_err("register power supply error!\n");
1169                 return -EFAULT;
1170         }
1171         sprdfgu_creat_attr(sprdfgu_data.sprdfgu.dev);
1172
1173         INIT_DELAYED_WORK(&sprdfgu_debug_work, sprdfgu_debug_works);
1174         mutex_init(&sprdfgu_data.lock);
1175         wake_lock_init(&(sprdfgu_data.low_power_lock), WAKE_LOCK_SUSPEND,
1176                        "sprdfgu_powerlow_lock");
1177         sprdfgu_int_init();
1178         schedule_delayed_work(&sprdfgu_debug_work, sprdfgu_debug_log_time * HZ);
1179         FGU_DEBUG("sprdfgu_init end\n");
1180         return ret;
1181 }
1182
1183 int sprdfgu_reset(void)
1184 {
1185         start_time = sci_syst_read();
1186         sprdfgu_data.init_cap = sprdfgu_vol2capacity(sprdfgu_read_vbat_ocv());
1187 #if defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
1188         sprdfgu_rtc_reg_write(sprdfgu_data.init_cap);
1189 #endif
1190         sprdfgu_data.init_clbcnt = poweron_clbcnt =
1191             sprdfgu_clbcnt_init(sprdfgu_data.init_cap);
1192         sprdfgu_clbcnt_set(poweron_clbcnt);
1193
1194         return 0;
1195 }
1196
1197 void sprdfgu_record_cap(u32 cap)
1198 {
1199 #if defined(CONFIG_ADIE_SC2723S) || defined(CONFIG_ADIE_SC2723)
1200         sprdfgu_rtc_reg_write(cap);
1201 #endif
1202 }