tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8825 / ldo.c
1 /******************************************************************************
2  ** File Name:      ldo_drv.c                                             *
3  ** Author:         Yi.Qiu                                                 *
4  ** DATE:           01/09/2009                                                *
5  ** Copyright:      2007 Spreatrum, Incoporated. All Rights Reserved.         *
6  ** Description:    This file defines the basic function for ldo management.  *
7  ******************************************************************************/
8
9 /******************************************************************************
10  **                        Edit History                                       *
11  ** ------------------------------------------------------------------------- *
12  ** DATE           NAME             DESCRIPTION                               *
13  ** 01/09/2009     Yi.Qiu        Create.                                   *
14  ******************************************************************************/
15
16 /**---------------------------------------------------------------------------*
17  **                         Dependencies                                      *
18  **---------------------------------------------------------------------------*/
19 #include <common.h>
20 #include <asm/io.h>
21
22 #include <asm/arch/regs_global.h>
23 #include <asm/arch/bits.h>
24 #include <asm/arch/ldo.h>
25 #include <asm/arch/regs_ana.h>
26
27 #define LDO_INVALID_REG 0xFFFFFFFF
28 #define LDO_INVALID_BIT         0xFFFFFFFF
29
30
31 #define CURRENT_STATUS_INIT     0x00000001
32 #define CURRENT_STATUS_ON       0x00000002
33 #define CURRENT_STATUS_OFF      0x00000004
34
35 #define LDO_INVALID_REG_ADDR            (0x1)
36
37 #define CHIP_REG_OR(reg_addr, value)    (*(volatile unsigned int *)(reg_addr) |= (unsigned int)(value))
38 #define CHIP_REG_AND(reg_addr, value)   (*(volatile unsigned int *)(reg_addr) &= (unsigned int)(value))
39 #define CHIP_REG_GET(reg_addr)          (*(volatile unsigned int *)(reg_addr))
40 #define CHIP_REG_SET(reg_addr, value)   (*(volatile unsigned int *)(reg_addr)  = (unsigned int)(value))
41  
42 #define SCI_PASSERT(condition, format...)  \
43         do {            \
44                 if(!(condition)) { \
45                         printf("function :%s\r\n", __FUNCTION__);\
46                         BUG();  \
47                 } \
48         }while(0)
49
50 struct ldo_ctl_info {
51 /**
52         need config area
53 */
54         LDO_ID_E id;
55         unsigned int bp_reg;
56         unsigned int bp_bits;
57         unsigned int bp_rst_reg;
58         unsigned int bp_rst;//bits
59
60         unsigned int level_reg_b0;
61         unsigned int b0;
62         unsigned int b0_rst;
63
64         unsigned int level_reg_b1;
65         unsigned int b1;
66         unsigned int b1_rst;
67
68         unsigned int init_level;
69 /**
70         not need config area
71 */
72         int ref;
73         int current_status;
74         int current_volt_level;
75 };
76
77 struct ldo_sleep_ctl_info {
78         SLP_LDO_E id;
79         unsigned int ldo_sleep_reg;
80         unsigned int mask;
81         unsigned  int value;
82 };
83
84
85 static struct ldo_ctl_info ldo_ctl_data[] =
86 {
87         {
88                 .id = LDO_DCDCARM,
89                 .bp_reg = ANA_LDO_PD_SET,
90                 .bp_bits = BIT_9,
91                 .bp_rst_reg = ANA_LDO_PD_RST,
92                 .bp_rst = BIT_9,
93                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
94                 .b0 = 0,
95                 .b0_rst = 0,
96                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
97                 .b1 = 0,
98                 .b1_rst = 0,
99                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
100         },
101         {
102                 .id = LDO_LDO_VDD25,
103                 .bp_reg = ANA_LDO_PD_SET,
104                 .bp_bits = BIT_8,
105                 .bp_rst_reg = ANA_LDO_PD_RST,
106                 .bp_rst = BIT_8,
107                 .level_reg_b0 = ANA_LDO_VCTL3,
108                 .b0 = BIT_8,
109                 .b0_rst = BIT_9,
110                 .level_reg_b1 = ANA_LDO_VCTL3,
111                 .b1 = BIT_10,
112                 .b1_rst = BIT_11,
113                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
114         },
115         {
116                 .id = LDO_LDO_VDD18,
117                 .bp_reg = ANA_LDO_PD_SET,
118                 .bp_bits = BIT_7,
119                 .bp_rst_reg = ANA_LDO_PD_RST,
120                 .bp_rst = BIT_7,
121                 .level_reg_b0 = ANA_LDO_VCTL3,
122                 .b0 = BIT_4,
123                 .b0_rst = BIT_5,
124                 .level_reg_b1 = ANA_LDO_VCTL3,
125                 .b1 = BIT_6,
126                 .b1_rst = BIT_7,
127                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
128         },
129         {
130                 .id = LDO_LDO_VDD28,
131                 .bp_reg = ANA_LDO_PD_SET,
132                 .bp_bits = BIT_6,
133                 .bp_rst_reg = ANA_LDO_PD_RST,
134                 .bp_rst = BIT_6,
135                 .level_reg_b0 = ANA_LDO_VCTL3,
136                 .b0 = BIT_0,
137                 .b0_rst = BIT_1,
138                 .level_reg_b1 = ANA_LDO_VCTL3,
139                 .b1 = BIT_2,
140                 .b1_rst = BIT_3,
141                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
142         },
143         {
144                 .id = LDO_LDO_ABB,
145                 .bp_reg = ANA_LDO_PD_SET,
146                 .bp_bits = BIT_5,
147                 .bp_rst_reg = ANA_LDO_PD_RST,
148                 .bp_rst = BIT_5,
149                 .level_reg_b0 = ANA_LDO_VCTL0,
150                 .b0 = BIT_12,
151                 .b0_rst = BIT_13,
152                 .level_reg_b1 = ANA_LDO_VCTL0,
153                 .b1 = BIT_14,
154                 .b1_rst = BIT_15,
155                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
156         },
157         {
158                 .id = LDO_LDO_RF0,
159                 .bp_reg = ANA_LDO_PD_SET,
160                 .bp_bits = BIT_3,
161                 .bp_rst_reg = ANA_LDO_PD_RST,
162                 .bp_rst = BIT_3,
163                 .level_reg_b0 = ANA_LDO_VCTL0,
164                 .b0 = BIT_4,
165                 .b0_rst = BIT_5,
166                 .level_reg_b1 = ANA_LDO_VCTL0,
167                 .b1 = BIT_6,
168                 .b1_rst = BIT_7,
169                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
170         },
171         {
172                 .id = LDO_LDO_RF1,
173                 .bp_reg = ANA_LDO_PD_SET,
174                 .bp_bits = BIT_4,
175                 .bp_rst_reg = ANA_LDO_PD_RST,
176                 .bp_rst = BIT_4,
177                 .level_reg_b0 = ANA_LDO_VCTL0,
178                 .b0 = BIT_8,
179                 .b0_rst = BIT_9,
180                 .level_reg_b1 = ANA_LDO_VCTL0,
181                 .b1 = BIT_10,
182                 .b1_rst = BIT_11,
183                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
184         },
185         {
186                 .id = LDO_LDO_MEM,
187                 .bp_reg = ANA_LDO_PD_SET,
188                 .bp_bits = BIT_2,
189                 .bp_rst_reg = ANA_LDO_PD_RST,
190                 .bp_rst = BIT_2,
191                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
192                 .b0 = 0,
193                 .b0_rst = 0,
194                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
195                 .b1 = 0,
196                 .b1_rst = 0,
197                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
198         },
199         {
200                 .id = LDO_DCDC,
201                 .bp_reg = ANA_LDO_PD_SET,
202                 .bp_bits = BIT_1,
203                 .bp_rst_reg = ANA_LDO_PD_RST,
204                 .bp_rst = BIT_1,
205                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
206                 .b0 = 0,
207                 .b0_rst = 0,
208                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
209                 .b1 = 0,
210                 .b1_rst = 0,
211                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
212         },
213         {
214                 .id = LDO_LDO_BG,
215                 .bp_reg = ANA_LDO_PD_SET,
216                 .bp_bits = BIT_0,
217                 .bp_rst_reg = ANA_LDO_PD_RST,
218                 .bp_rst = BIT_0,
219                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
220                 .b0 = 0,
221                 .b0_rst = 0,
222                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
223                 .b1 = 0,
224                 .b1_rst = 0,
225                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
226         },
227         {
228                 .id = LDO_LDO_AVB,
229                 .bp_reg = ANA_LDO_PD_CTL0,
230                 .bp_bits = BIT_14,
231                 .bp_rst_reg = ANA_LDO_PD_CTL0,
232                 .bp_rst = BIT_15,
233                 .level_reg_b0 = ANA_LDO_VCTL1,
234                 .b0 = BIT_8,
235                 .b0_rst = BIT_9,
236                 .level_reg_b1 = ANA_LDO_VCTL1,
237                 .b1 = BIT_10,
238                 .b1_rst = BIT_11,
239                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
240         },
241         {
242                 .id = LDO_LDO_CAMA,
243                 .bp_reg = ANA_LDO_PD_CTL0,
244                 .bp_bits = BIT_12,
245                 .bp_rst_reg = ANA_LDO_PD_CTL0,
246                 .bp_rst = BIT_13,
247                 .level_reg_b0 = ANA_LDO_VCTL2,
248                 .b0 = BIT_8,
249                 .b0_rst = BIT_9,
250                 .level_reg_b1 = ANA_LDO_VCTL2,
251                 .b1 = BIT_10,
252                 .b1_rst = BIT_11,
253                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
254         },
255         {
256                 .id = LDO_LDO_CAMD1,
257                 .bp_reg = ANA_LDO_PD_CTL0,
258                 .bp_bits = BIT_10,
259                 .bp_rst_reg = ANA_LDO_PD_CTL0,
260                 .bp_rst = BIT_11,
261                 .level_reg_b0 = ANA_LDO_VCTL2,
262                 .b0 = BIT_4,
263                 .b0_rst = BIT_5,
264                 .level_reg_b1 = ANA_LDO_VCTL2,
265                 .b1 = BIT_6,
266                 .b1_rst = BIT_7,
267                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
268         },
269         {
270                 .id = LDO_LDO_CAMD0,
271                 .bp_reg = ANA_LDO_PD_CTL0,
272                 .bp_bits = BIT_8,
273                 .bp_rst_reg = ANA_LDO_PD_CTL0,
274                 .bp_rst = BIT_9,
275                 .level_reg_b0 = ANA_LDO_VCTL2,
276                 .b0 = BIT_0,
277                 .b0_rst = BIT_1,
278                 .level_reg_b1 = ANA_LDO_VCTL2,
279                 .b1 = BIT_2,
280                 .b1_rst = BIT_3,
281                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
282         },
283         {
284                 .id = LDO_LDO_SIM1,
285                 .bp_reg = ANA_LDO_PD_CTL0,
286                 .bp_bits = BIT_6,
287                 .bp_rst_reg = ANA_LDO_PD_CTL0,
288                 .bp_rst = BIT_7,
289                 .level_reg_b0 = ANA_LDO_VCTL1,
290                 .b0 = BIT_4,
291                 .b0_rst = BIT_5,
292                 .level_reg_b1 = ANA_LDO_VCTL1,
293                 .b1 = BIT_6,
294                 .b1_rst = BIT_7,
295                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
296         },
297         {
298                 .id = LDO_LDO_SIM0,
299                 .bp_reg = ANA_LDO_PD_CTL0,
300                 .bp_bits = BIT_4,
301                 .bp_rst_reg = ANA_LDO_PD_CTL0,
302                 .bp_rst = BIT_5,
303                 .level_reg_b0 = ANA_LDO_VCTL1,
304                 .b0 = BIT_0,
305                 .b0_rst = BIT_1,
306                 .level_reg_b1 = ANA_LDO_VCTL1,
307                 .b1 = BIT_2,
308                 .b1_rst = BIT_3,
309                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
310         },
311         {
312                 .id = LDO_LDO_SDIO0,
313                 .bp_reg = ANA_LDO_PD_CTL0,
314                 .bp_bits = BIT_2,
315                 .bp_rst_reg = ANA_LDO_PD_CTL0,
316                 .bp_rst = BIT_3,
317                 .level_reg_b0 = ANA_LDO_VCTL1,
318                 .b0 = BIT_12,
319                 .b0_rst = BIT_13,
320                 .level_reg_b1 = ANA_LDO_VCTL1,
321                 .b1 = BIT_14,
322                 .b1_rst = BIT_15,
323                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
324         },
325         {
326                 .id = LDO_LDO_USB,
327                 .bp_reg = ANA_LDO_PD_CTL0,
328                 .bp_bits = BIT_0,
329                 .bp_rst_reg = ANA_LDO_PD_CTL0,
330                 .bp_rst = BIT_1,
331                 .level_reg_b0 = ANA_LDO_VCTL2,
332                 .b0 = BIT_12,
333                 .b0_rst = BIT_13,
334                 .level_reg_b1 = ANA_LDO_VCTL2,
335                 .b1 = BIT_14,
336                 .b1_rst = BIT_15,
337                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
338         },
339         {
340                 .id = LDO_LDO_SIM3,
341                 .bp_reg = ANA_LDO_PD_CTL1,
342                 .bp_bits = BIT_8,
343                 .bp_rst_reg = ANA_LDO_PD_CTL1,
344                 .bp_rst = BIT_9,
345                 .level_reg_b0 = ANA_LDO_VCTL4,
346                 .b0 = BIT_12,
347                 .b0_rst = BIT_13,
348                 .level_reg_b1 = ANA_LDO_VCTL4,
349                 .b1 = BIT_14,
350                 .b1_rst = BIT_15,
351                 .init_level = LDO_VOLT_LEVEL3,  //CMMB 1.2V
352         },
353         {
354                 .id = LDO_LDO_SIM2,
355                 .bp_reg = ANA_LDO_PD_CTL1,
356                 .bp_bits = BIT_6,
357                 .bp_rst_reg = ANA_LDO_PD_CTL1,
358                 .bp_rst = BIT_7,
359                 .level_reg_b0 = ANA_LDO_VCTL4,
360                 .b0 = BIT_8,
361                 .b0_rst = BIT_9,
362                 .level_reg_b1 = ANA_LDO_VCTL4,
363                 .b1 = BIT_10,
364                 .b1_rst = BIT_11,
365                 .init_level = LDO_VOLT_LEVEL1,  //E-NAND 3.0V
366         },
367         {
368                 .id = LDO_LDO_WIF1,
369                 .bp_reg = ANA_LDO_PD_CTL1,
370                 .bp_bits = BIT_4,
371                 .bp_rst_reg = ANA_LDO_PD_CTL1,
372                 .bp_rst = BIT_5,
373                 .level_reg_b0 = ANA_LDO_VCTL4,
374                 .b0 = BIT_4,
375                 .b0_rst = BIT_5,
376                 .level_reg_b1 = ANA_LDO_VCTL4,
377                 .b1 = BIT_6,
378                 .b1_rst = BIT_7,
379                 .init_level = LDO_VOLT_LEVEL2,  //WIFI 1.8V
380         },
381         {
382                 .id = LDO_LDO_WIF0,
383                 .bp_reg = ANA_LDO_PD_CTL1,
384                 .bp_bits = BIT_2,
385                 .bp_rst_reg = ANA_LDO_PD_CTL1,
386                 .bp_rst = BIT_3,
387                 .level_reg_b0 = ANA_LDO_VCTL4,
388                 .b0 = BIT_0,
389                 .b0_rst = BIT_1,
390                 .level_reg_b1 = ANA_LDO_VCTL4,
391                 .b1 = BIT_2,
392                 .b1_rst = BIT_3,
393                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
394         },
395         {
396                 .id = LDO_LDO_SDIO1,
397                 .bp_reg = ANA_LDO_PD_CTL1,
398                 .bp_bits = BIT_0,
399                 .bp_rst_reg = ANA_LDO_PD_CTL1,
400                 .bp_rst = BIT_1,
401                 .level_reg_b0 = ANA_LDO_VCTL3,
402                 .b0 = BIT_12,
403                 .b0_rst = BIT_13,
404                 .level_reg_b1 = ANA_LDO_VCTL3,
405                 .b1 = BIT_14,
406                 .b1_rst = BIT_15,
407                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
408         },
409         {
410                 .id = LDO_LDO_RTC,
411                 .bp_reg = LDO_INVALID_REG_ADDR,
412                 .bp_bits = 0,
413                 .bp_rst_reg = LDO_INVALID_REG_ADDR,
414                 .bp_rst = 0,
415                 .level_reg_b0 = ANA_LDO_VCTL0,
416                 .b0 = 0,
417                 .b0_rst = 1,
418                 .level_reg_b1 = ANA_LDO_VCTL0,
419                 .b1 = 2,
420                 .b1_rst = 3,
421                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
422         },
423         {
424                 .id = LDO_LDO_USBD,
425                 .bp_reg = LDO_INVALID_REG_ADDR,
426                 .bp_bits = 0,
427                 .bp_rst_reg = LDO_INVALID_REG_ADDR,
428                 .bp_rst = 0,
429                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
430                 .b0 = 0,
431                 .b0_rst = 0,
432                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
433                 .b1 = 0,
434                 .b1_rst = 0,
435                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
436         },
437         {
438                 .id = LDO_LDO_SDIO3,
439                 .bp_reg = ANA_LDO_PD_CTL1,
440                 .bp_bits = BIT_4,
441                 .bp_rst_reg = ANA_LDO_PD_CTL1,
442                 .bp_rst = BIT_5,
443                 .level_reg_b0 = ANA_LDO_VCTL4,
444                 .b0 = BIT_4,
445                 .b0_rst = BIT_5,
446                 .level_reg_b1 = ANA_LDO_VCTL4,
447                 .b1_rst = BIT_6,
448                 .b1 = BIT_7,
449                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
450         },
451         {
452                 .id = LDO_LDO_VDD30,
453                 .bp_reg = ANA_LDO_PD_CTL1,
454                 .bp_bits = BIT_6,
455                 .bp_rst_reg = ANA_LDO_PD_CTL1,
456                 .bp_rst = BIT_7,
457                 .level_reg_b0 = ANA_LDO_VCTL1,
458                 .b0 = BIT_8,
459                 .b0_rst = BIT_9,
460                 .level_reg_b1 = ANA_LDO_VCTL1,
461                 .b1 = BIT_10,
462                 .b1_rst = BIT_11,
463                 .init_level = LDO_VOLT_LEVEL_FAULT_MAX,
464         },
465 };
466
467 static struct ldo_sleep_ctl_info slp_ldo_ctl_data[] = {
468     {SLP_LDO_SDIO1,    ANA_LDO_SLP_CTL0,    BIT_14, 0},
469     {SLP_LDO_VDD25,     ANA_LDO_SLP_CTL0,    BIT_13, 1},
470     {SLP_LDO_VDD18,     ANA_LDO_SLP_CTL0,    BIT_12, 0},
471     {SLP_LDO_VDD28,     ANA_LDO_SLP_CTL0,    BIT_11, 0},
472     {SLP_LDO_AVDDBB,       ANA_LDO_SLP_CTL0,    BIT_10, 1},
473     {SLP_LDO_SDIO0,      ANA_LDO_SLP_CTL0,    BIT_9,  1},
474     {SLP_LDO_VB,       ANA_LDO_SLP_CTL0,    BIT_8,  0},
475     {SLP_LDO_CAMA,      ANA_LDO_SLP_CTL0,    BIT_7,  1},
476     {SLP_LDO_CAMD1,     ANA_LDO_SLP_CTL0,    BIT_6,  1},
477     {SLP_LDO_CAMD0,     ANA_LDO_SLP_CTL0,    BIT_5,  1},
478     {SLP_LDO_USBH,       ANA_LDO_SLP_CTL0,    BIT_4,  1},
479     {SLP_LDO_SIM1,      ANA_LDO_SLP_CTL0,    BIT_3,  1},
480     {SLP_LDO_SIM0,      ANA_LDO_SLP_CTL0,    BIT_2,  0},
481     {SLP_LDO_RF1,       ANA_LDO_SLP_CTL0,    BIT_1,  1},
482     {SLP_LDO_RF0,       ANA_LDO_SLP_CTL0,    BIT_0,  1},
483 };
484
485  /**---------------------------------------------------------------------------*
486  **                         Function Declaration                              *
487  **---------------------------------------------------------------------------*/
488 static struct ldo_ctl_info* LDO_GetLdoCtl(LDO_ID_E ldo_id)
489 {
490         int i = 0;
491         struct ldo_ctl_info* ctl = NULL;
492
493         for ( i = 0; i < ARRAY_SIZE(ldo_ctl_data); ++i) {
494                 if (ldo_ctl_data[i].id == ldo_id) {
495                         ctl = &ldo_ctl_data[i];
496                         break;
497                 }
498         }
499
500         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
501         return ctl;
502 }
503
504 LDO_ERR_E LDO_TurnOnLDO(LDO_ID_E ldo_id)
505 {
506         struct ldo_ctl_info* ctl = NULL;
507
508         ctl = LDO_GetLdoCtl(ldo_id);
509         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
510
511         if ((ctl->ref++) == 0) {
512                 if(ctl->bp_reg == LDO_INVALID_REG_ADDR) {
513                         if (LDO_LDO_USBD == ldo_id)
514                                 CHIP_REG_AND((~LDO_USB_PD), GR_CLK_GEN5);
515
516                 } else {
517                         if (ctl->bp_reg == ctl->bp_rst_reg) {
518                                 REG_SETCLRBIT(ctl->bp_rst_reg, ctl->bp_rst, ctl->bp_bits);
519                         }
520                         else {
521                                 ANA_REG_BIC(ctl->bp_reg, ctl->bp_bits);
522                                 ANA_REG_OR(ctl->bp_rst_reg, ctl->bp_rst);//high priority
523                         }
524                 }
525                 ctl->current_status = CURRENT_STATUS_ON;
526         }
527
528         return LDO_ERR_OK;
529 }
530
531
532  LDO_ERR_E LDO_TurnOffLDO(LDO_ID_E ldo_id)
533 {
534         struct ldo_ctl_info* ctl = NULL;
535         unsigned long flags;
536
537         ctl = LDO_GetLdoCtl(ldo_id);
538         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
539
540         local_irq_save(flags);
541         
542         if ((--ctl->ref) == 0) {
543                 if(ctl->bp_reg == LDO_INVALID_REG_ADDR) {
544                         if (LDO_LDO_USBD == ldo_id)
545                                 CHIP_REG_OR((LDO_USB_PD), GR_CLK_GEN5);
546                 } else {
547                         if (ctl->bp_reg == ctl->bp_rst_reg) {
548                                 REG_SETCLRBIT(ctl->bp_reg, ctl->bp_bits, ctl->bp_rst);
549                         }
550                         else {
551                                 ANA_REG_BIC(ctl->bp_rst_reg, ctl->bp_rst);//high priority
552                                 ANA_REG_OR(ctl->bp_reg, ctl->bp_bits);
553                         }
554                 }
555                 ctl->current_status = CURRENT_STATUS_OFF;
556         }
557
558         local_irq_restore(flags);
559
560         return LDO_ERR_OK;
561 }
562
563  int LDO_IsLDOOn(LDO_ID_E ldo_id)
564 {
565         unsigned int  masked_val = 0;
566         struct ldo_ctl_info* ctl = NULL;
567
568         ctl = LDO_GetLdoCtl(ldo_id);
569         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
570
571         if (ctl->current_status == CURRENT_STATUS_INIT)
572                 masked_val = (LDO_REG_GET(ctl->bp_reg) & ctl->bp_bits);
573         else
574                 return (ctl->current_status == CURRENT_STATUS_OFF ? 0 : 1);
575
576         return (masked_val ? 0 : 1);
577 }
578
579  LDO_ERR_E LDO_SetVoltLevel(LDO_ID_E ldo_id, LDO_VOLT_LEVEL_E volt_level)
580 {
581         unsigned int b0_mask,b1_mask;
582         struct ldo_ctl_info* ctl = NULL;
583
584         b0_mask = (volt_level & BIT_0)?~0:0;
585         b1_mask = (volt_level & BIT_1)?~0:0;
586
587         ctl = LDO_GetLdoCtl(ldo_id);
588         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
589
590         if(ctl->level_reg_b0 == ctl->level_reg_b1) {
591                 if (ctl->level_reg_b0 == LDO_INVALID_REG_ADDR)
592                         goto Err_Exit;
593                 else
594                         SET_LEVEL(ctl->level_reg_b0, b0_mask, b1_mask, ctl->b0, ctl->b0_rst, ctl->b1, ctl->b1_rst);
595         } else {
596                 if (ctl->level_reg_b0 == LDO_INVALID_REG_ADDR || ctl->level_reg_b1 == LDO_INVALID_REG_ADDR) {
597                         goto Err_Exit;
598                 } else {
599                         SET_LEVELBIT(ctl->level_reg_b0, b0_mask, ctl->b0, ctl->b0_rst);
600                         SET_LEVELBIT(ctl->level_reg_b1, b1_mask, ctl->b1, ctl->b1_rst);
601                 }
602         }
603
604         ctl->current_volt_level = volt_level;
605         return LDO_ERR_OK;
606 Err_Exit:
607         return LDO_ERR_ERR;
608 }
609
610
611  LDO_VOLT_LEVEL_E LDO_GetVoltLevel(LDO_ID_E ldo_id)
612 {
613         unsigned int level_ret = 0;
614         struct ldo_ctl_info* ctl = NULL;
615
616         ctl = LDO_GetLdoCtl(ldo_id);
617         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
618
619         if (ctl->current_volt_level == LDO_VOLT_LEVEL_FAULT_MAX) {
620                 if(ctl->level_reg_b0 == ctl->level_reg_b1) {
621                         GET_LEVEL(ctl->level_reg_b0, ctl->b0, ctl->b1, level_ret);
622                 } else {
623                         GET_LEVELBIT(ctl->level_reg_b0, ctl->b0, BIT_0, level_ret);
624                         GET_LEVELBIT(ctl->level_reg_b1, ctl->b1, BIT_1, level_ret);
625                 }
626         }
627         else
628         {
629                 level_ret = ctl->current_volt_level;
630         }
631
632         return level_ret;
633 }
634
635 void LDO_DeepSleepInit(void)
636 {
637         int i;
638         unsigned int aux;
639
640         for ( i = 0; i < ARRAY_SIZE(slp_ldo_ctl_data); ++i) {
641                 aux = ANA_REG_GET(slp_ldo_ctl_data[i].ldo_sleep_reg);
642                 aux &= ~slp_ldo_ctl_data[i].mask;
643                 aux |= slp_ldo_ctl_data[i].value;
644                 ANA_REG_SET(slp_ldo_ctl_data[i].ldo_sleep_reg, aux);
645         }
646
647 }
648
649 int LDO_Init(void)
650 {
651         int i;
652         for ( i = 0; i < ARRAY_SIZE(ldo_ctl_data); ++i) {
653                 if( ldo_ctl_data[i].init_level != LDO_VOLT_LEVEL_FAULT_MAX) {
654                         LDO_SetVoltLevel(ldo_ctl_data[i].id, ldo_ctl_data[i].init_level);
655                 }
656                 ldo_ctl_data[i].ref = 0;
657                 ldo_ctl_data[i].current_status = CURRENT_STATUS_INIT;
658                 ldo_ctl_data[i].current_volt_level = ldo_ctl_data[i].init_level;
659         }
660
661         LDO_DeepSleepInit();
662
663         return LDO_ERR_OK;
664 }
665
666 static void LDO_TurnOffCoreLDO(void)
667 {
668         ANA_REG_SET (ANA_LDO_PD_RST, 0);
669         ANA_REG_SET (ANA_LDO_PD_SET, ANA_LDO_PD_SET_MSK);/// turn off system core ldo
670 }
671
672 static void LDO_TurnOffAllModuleLDO(void)
673 {
674         //ANA_REG_OR(ANA_AUDIO_PA_CTL1, PA_LDO_EN_RST);///PA poweroff
675         ANA_REG_SET (ANA_LDO_PD_CTL1, ANA_LDO_PD_CTL_MSK);
676         ANA_REG_SET (ANA_LDO_PD_CTL0, ANA_LDO_PD_CTL_MSK);
677 }
678
679 void LDO_TurnOffAllLDO(void)
680 {
681         LDO_TurnOffAllModuleLDO();
682         LDO_TurnOffCoreLDO();
683 }