3 #include <asm/arch/adc_drvapi.h>
4 #include <asm/arch/adi_hal_internal.h>
5 #include <asm/arch/sprd_reg.h>
7 int regulator_default_get(const char con_id[]);
8 void regulator_default_set(const char con_id[], int vol);
9 int regulator_default_set_all(void);
10 u32 regulator_get_calibration_mask(void);
12 typedef void (*pfun)(int);
13 static pfun calibrate_post = NULL;
15 #define REGU_CALI_DEBUG
17 #ifdef REGU_CALI_DEBUG
18 #define regu_debug(fmt, arg...) printf(fmt, ## arg)
20 #define regu_debug(fmt, arg...)
24 #define debug0(format, arg...)
25 #define debug(format, arg...) regu_debug(format, ## arg)
26 #define debug1(format, arg...) regu_debug("\t" format, ## arg)
27 #define debug2(format, arg...) regu_debug("\t\t" format, ## arg)
30 /* abs() handles unsigned and signed longs, ints, shorts and chars. For all input types abs()
31 * returns a signed long.
32 * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64() for those.*/
35 if (sizeof(x) == sizeof(long)) { \
37 ret = (__x < 0) ? -__x : __x; \
40 ret = (__x < 0) ? -__x : __x; \
48 /* On ARMv5 and above those functions can be implemented around the clz instruction for
49 * much better code efficiency. */
51 static inline int fls(int x)
55 asm("clz\t%0, %1": "=r"(ret):"r"(x));
60 #define __fls(x) (fls(x) - 1)
61 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
62 #define __ffs(x) (ffs(x) - 1)
63 #define ffz(x) __ffs( ~(x) )
65 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
67 #define MEASURE_TIMES (15)
69 #define ADC_DROP_CNT ( DIV_ROUND(MEASURE_TIMES, 5) )
71 /*************************************************************************
72 Reg: 0x40038800 + 0x00E4
73 --------------------------------------------
74 BIT | FieldName | Description
75 --------------------------------------------
77 BIT6 BONDOPT6 28nm/40nm dcdccore/dcdcarm default voltage select:
78 0: dcdccore/dcdcarm = 1.1v, vdd25 = 2.5v
79 1: dcdccore/dcdcarm = 0.9v, vdd25 = 1.8v
80 BIT5 BONDOPT5 crystal 32k buffer select:
81 0: new low power 32k buffer output, 1: backup 32k buffer output
82 BIT4 BONDOPT4 dcdcwrf out voltage select: dcdc_wrf_ctl[2]
83 BIT3 BONDOPT3 charge mode option:
84 0: continues charging, 1: dcdc mode charging
85 BIT2 BONDOPT2 dcdcmem option 2: dcdc_mem_ctl[2]
86 BIT1 BONDOPT1 dcdcmem option 1: dcdc_mem_ctl[1]
91 BIT0 BONDOPT0 New power on reset option:
92 0: manual power on without hardware debounce
93 1: auto power on with 1s hardware debounce
94 **************************************************************************/
95 static u16 ana_status;
97 //static volatile int loop = 1;
99 static int __average(int a[], int N)
102 for (i = 0; i < N; i++)
104 return DIV_ROUND(sum, N);
107 static void bubble_sort(int a[], int N)
110 for (i = 0; i < N - 1; i++) {
111 for (j = i + 1; j < N; j++) {
121 static int sci_adc_request(int channel, int scale)
123 int results[MEASURE_TIMES];
125 if (-1 == ADC_GetValues(channel, scale, MEASURE_TIMES, results)) {
129 bubble_sort(results, MEASURE_TIMES);
136 for (i = 0; i < MEASURE_TIMES; i++) {
137 printf("%d ", results[i]);
143 return __average(&results[ADC_DROP_CNT], MEASURE_TIMES - ADC_DROP_CNT * 2);
146 #define RATIO(_n_, _d_) (_n_ << 16 | _d_)
148 static int sci_adc_ratio(int channel, int scale, int mux)
155 return ((ADC_SCALE_3V == scale) ? RATIO(16, 41) : RATIO(1, 1));
159 case 0x06: //charge sense
160 return RATIO(77, 1024);
165 return ((ADC_SCALE_3V == scale) ? RATIO(2, 5) : RATIO(3, 5));
166 case 0x0D: //dcdccore
168 return ((ADC_SCALE_3V == scale) ? RATIO(4, 5) : RATIO(1, 1));
170 return ((ADC_SCALE_3V == scale) ? RATIO(3, 5) : RATIO(4, 5));
174 return ((ADC_SCALE_3V == scale) ? RATIO(4, 5) : RATIO(1, 1));
176 return ((ADC_SCALE_3V == scale) ? RATIO(1, 3) : RATIO(4, 5));
178 case 0x15: //ldo_mux0
179 case 0x17: //ldo_mux2
183 case 0x16: //ldo_mux1
184 if ((mux & 0xFFFF) == BIT(5))
196 static u32 bat_numerators, bat_denominators = 0;
197 extern uint16_t sprdbat_auxadc2vbatvol (uint16_t adcvalue);
199 static int sci_adc_vol_request(int channel, int scale, int mux, int* adc)
201 int chan_adc, chan_vol;
203 if(0 == bat_denominators) {
205 /* FIXME: Update CHGMNG_AdcvalueToVoltage table before setup vbat ratio. */
206 /* ADC_CHANNEL_VBAT is 5 */
207 res = (u32) sci_adc_ratio(5, ADC_SCALE_3V, 0);
208 bat_numerators = res >> 16;
209 bat_denominators = res & 0xffff;
212 chan_adc = sci_adc_request(channel, scale);
217 chan_vol = sprdbat_auxadc2vbatvol(chan_adc);
218 if(ADC_SCALE_3V == scale) {
219 u32 res, chan_numerators, chan_denominators;
220 res = (u32) sci_adc_ratio(channel, scale, mux);
221 chan_numerators = res >> 16;
222 chan_denominators = res & 0xffff;
224 chan_vol *= (bat_numerators * chan_denominators);
225 chan_vol /= (bat_denominators * chan_numerators);
232 /* Simple shorthand for a section definition */
234 # define __section(S) __attribute__ ((__section__(#S)))
237 #define __init0 __section(.rodata.regu_2713s.init0)
238 #define __init1 __section(.rodata.regu_2713s.init1)
239 #define __init2 __section(.rodata.regu_2713s.init2)
241 static const u32 __init0 __init_begin = 0xeeeebbbb;
242 static const u32 __init2 __init_end = 0xddddeeee;
244 struct regulator_regs {
246 u32 pd_set, pd_set_bit;
247 /* at new feature, some LDOs had only set, no rst bits.
248 * and DCDCs voltage and trimming controller is the same register */
249 u32 pd_rst, pd_rst_bit;
250 u32 slp_ctl, slp_ctl_bit;
251 u32 vol_trm, vol_trm_bits;
252 u32 cal_ctl, cal_ctl_bits;
254 u32 vol_ctl, vol_ctl_bits;
255 u32 vol_sel_cnt, vol_sel[];
258 struct regulator_desc {
261 struct regulator_regs *regs;
264 #define REGU_VERIFY_DLY (1000) /*ms */
265 #define SCI_REGU_REG(VDD, TYP, PD_SET, SET_BIT, PD_RST, RST_BIT, SLP_CTL, SLP_CTL_BIT, \
266 VOL_TRM, VOL_TRM_BITS, CAL_CTL, CAL_CTL_BITS, VOL_DEF, \
267 VOL_CTL, VOL_CTL_BITS, VOL_SEL_CNT, ...) \
268 static struct regulator_regs REGS_##VDD = { \
271 .pd_set_bit = SET_BIT, \
273 .pd_rst_bit = RST_BIT, \
274 .slp_ctl = SLP_CTL, \
275 .slp_ctl_bit = SLP_CTL_BIT, \
276 .vol_trm = VOL_TRM, \
277 .vol_trm_bits = VOL_TRM_BITS, \
278 .cal_ctl = CAL_CTL, \
279 .cal_ctl_bits = CAL_CTL_BITS, \
280 .vol_def = VOL_DEF, \
281 .vol_ctl = VOL_CTL, \
282 .vol_ctl_bits = VOL_CTL_BITS, \
283 .vol_sel_cnt = VOL_SEL_CNT, \
284 .vol_sel = {__VA_ARGS__}, \
286 struct regulator_desc __init1 S_DESC_##VDD = { \
289 .regs = ®S_##VDD, \
292 #include <asm/arch/__sc2713s_regulator_map.h>
294 /* standard dcdc ops*/
295 static int dcdc_initial_value(struct regulator_desc *desc)
297 return ((0 == strcmp(desc->name, "vddmem")) ? 0x10 : 0);
300 static int dcdc_get_trimming_step(struct regulator_desc *desc, int to_vol)
302 if ((0 == strcmp(desc->name, "vddmem")) ||
303 (0 == strcmp(desc->name, "vddwrf"))) { /* FIXME: vddmem/vddwrf step 200/32mV */
304 return 1000 * 200 / 32; /*uV */
306 return 1000 * 100 / 32; /*uV */
309 static int __match_vol(struct regulator_desc *desc, u32 vol)
312 int ds, min_ds = 100; /* mV, the max range of small voltage */
313 struct regulator_regs *regs = desc->regs;
315 for (i = 0; i < regs->vol_sel_cnt; i++) {
316 ds = vol - regs->vol_sel[i];
317 if (ds >= 0 && ds < min_ds) {
323 if ((2 == regs->typ) && (j < 0)) {
324 for (i = 0; i < regs->vol_sel_cnt; i++) {
325 ds = abs(vol - regs->vol_sel[i]);
336 static int dcdc_get_voltage(struct regulator_desc *desc)
338 const struct regulator_regs *regs = desc->regs;
340 int cal = 0; /* uV */
341 int i, shft = __ffs(regs->vol_ctl_bits);
343 BUG_ON(regs->vol_sel_cnt > 8);
345 i = (ANA_REG_GET(regs->vol_ctl) & regs->vol_ctl_bits) >> shft;
346 mv = regs->vol_sel[i];
349 cal = (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> __ffs(regs->vol_trm_bits);
350 cal -= dcdc_initial_value(desc);
352 cal *= dcdc_get_trimming_step(desc, 0); /*uV */
355 debug0("%s %d +%dmv\n", desc->name, mv, cal / 1000);
356 return (mv + cal / 1000);
359 static int dcdc_set_voltage(struct regulator_desc *desc, int min_mV, int max_mV)
361 const struct regulator_regs *regs = desc->regs;
364 /* found the closely vol ctrl bits */
365 i = __match_vol(desc, mv);
367 debug2("%s: %s failed to match voltage: %d\n",__func__,desc->name,mv);
371 /* dcdc calibration control bits (default 0) small adjust voltage: 100/32mv ~= 3.125mv */
373 int shft_ctl = __ffs(regs->vol_ctl_bits);
374 int shft_trm = __ffs(regs->vol_trm_bits);
375 int step = dcdc_get_trimming_step(desc, mv);
376 int j = (int)(mv - (int)regs->vol_sel[i]) * 1000 / step;
377 j += dcdc_initial_value(desc);
379 debug2("regu_dcdc %d = %d %+dmv (trim=%d step=%duv);\n",
380 mv, regs->vol_sel[i], mv - regs->vol_sel[i], j, step);
382 if (regs->vol_trm == regs->vol_ctl) {
383 if (j >= 0 && j <= (regs->vol_trm_bits >> shft_trm)) {
384 ANA_REG_MSK_OR(regs->vol_ctl, (j << shft_trm) | (i << shft_ctl),
385 regs->vol_trm_bits | regs->vol_ctl_bits);
388 if (regs->vol_trm) { /* small adjust first */
389 if (j >= 0 && j <= (regs->vol_trm_bits >> shft_trm)) {
390 ANA_REG_MSK_OR(regs->vol_trm, j << shft_trm, regs->vol_trm_bits);
395 ANA_REG_MSK_OR(regs->vol_ctl, i << shft_ctl, regs->vol_ctl_bits);
402 static int dcdc_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
404 //int acc_vol = dcdc_get_trimming_step(desc, to_vol) / 1000;
405 int ctl_vol = (def_vol - (adc_vol - to_vol));
407 return dcdc_set_voltage(desc, ctl_vol, ctl_vol);
410 static int ldo_get_voltage(struct regulator_desc *desc)
412 const struct regulator_regs *regs = desc->regs;
416 BUG_ON(!(regs->vol_ctl || regs->vol_ctl_bits));
418 shft = __ffs(regs->vol_ctl_bits);
419 i = ((ANA_REG_GET(regs->vol_ctl) & regs->vol_ctl_bits) >> shft);
420 vol = regs->vol_sel[i];
422 debug0("%s get voltage %dmv, idx %d\n", desc->name, vol, i);
428 static int ldo_set_voltage(struct regulator_desc *desc, int min_mV, int max_mV)
430 const struct regulator_regs *regs = desc->regs;
432 int shft_ctl = __ffs(regs->vol_ctl_bits);
434 BUG_ON(!regs->vol_ctl || (regs->vol_sel_cnt > 4));
436 /* found the closely vol ctrl bits */
437 i = __match_vol(desc, mv);
439 debug2("%s: %s failed to match voltage: %d\n",__func__,desc->name,mv);
443 ANA_REG_MSK_OR(regs->vol_ctl,
452 /* ldo trimming step about 0.625%, range 90% ~ 109.375%. that all maps as follow.
454 0x1F : +9.375 : 109.375
455 0x1E : +8.750 : 108.750
456 0x1D : +8.125 : 108.125
457 0x1C : +7.500 : 107.500
458 0x1B : +6.875 : 106.875
459 0x1A : +6.250 : 106.250
460 0x19 : +5.625 : 105.625
461 0x18 : +5.000 : 105.000
462 0x17 : +4.375 : 104.375
463 0x16 : +3.750 : 103.750
464 0x15 : +3.125 : 103.125
465 0x14 : +2.500 : 102.500
466 0x13 : +1.875 : 101.875
467 0x12 : +1.250 : 101.250
468 0x11 : +0.625 : 100.625
469 0x10 : +0.000 : 100.000
470 0x0F : -0.625 : 99.375
471 0x0E : -1.250 : 98.750
472 0x0D : -1.875 : 98.125
473 0x0C : -2.500 : 97.500
474 0x0B : -3.125 : 96.875
475 0x0A : -3.750 : 96.250
476 0x09 : -4.375 : 95.625
477 0x08 : -5.000 : 95.000
478 0x07 : -5.625 : 94.375
479 0x06 : -6.250 : 93.750
480 0x05 : -6.875 : 93.125
481 0x04 : -7.500 : 92.500
482 0x03 : -8.125 : 91.875
483 0x02 : -8.750 : 91.250
484 0x01 : -9.375 : 90.625
485 0x00 : -10.000 : 90.000
487 static int ldo_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
489 const struct regulator_regs *regs = desc->regs;
493 /* assert 5 valid trim bits, R = V_IDEAL / V_ADCIN - 1 */
494 int shft_trm = __ffs(regs->vol_trm_bits);
495 u32 trim = DIV_ROUND_UP((to_vol * 100 - adc_vol * 90) * 32, (adc_vol * 20));
497 if (trim > BIT(5) - 1)
500 debug2("regu_ldo %d = %d %+d.%03d%%, trim(0x%02x)\n",
501 to_vol, adc_vol, (int)(trim * 20 - 320) / 32, (int)abs((int)(trim * 20 - 320) * 1000 / 32) % 1000, trim);
503 ANA_REG_MSK_OR(regs->vol_trm,
512 static int DCDC_Cal_One(struct regulator_desc *desc, int is_cal)
514 struct regulator_regs *regs = desc->regs;
515 int def_vol = 0, to_vol = 0;
516 int adc = 0, adc_vol = 0, cal_vol = 0;
517 int ret = -1, adc_chan = regs->cal_ctl_bits >> 16;
518 u16 ldo_cal_sel = regs->cal_ctl_bits & 0xFFFF;
520 if (!adc_chan || !regs->vol_def)
523 /* only verify dcdc calibration */
524 if (!is_cal && (2 != desc->regs->typ))
528 debug("\nCalibrate %s ...\n", desc->name);
530 debug("\nVerify %s ...\n", desc->name);
532 /* Fixme: Config dynamically dcdc/ldo
533 * accoring to bit BONDOPT4 & BONDOPT6 for Reg(0x40038800 + 0x00E4)
537 if ((ana_status >> 6) & 0x1) {
538 if (0 == strcmp(desc->name, "vddcore")) {
539 desc->regs->vol_def = 900;
540 desc->regs->vol_ctl = (u32)ANA_REG_GLB_MP_MISC_CTRL;
541 desc->regs->vol_ctl_bits = BIT(3)|BIT(4)|BIT(5);
542 } else if (0 == strcmp(desc->name, "vddarm")) {
543 desc->regs->vol_def = 900;
544 desc->regs->vol_ctl = (u32)ANA_REG_GLB_MP_MISC_CTRL;
545 desc->regs->vol_ctl_bits = BIT(6)|BIT(7)|BIT(8);
546 } else if (0 == strcmp(desc->name, "vdd25")) {
547 desc->regs->vol_def = 1800;
548 desc->regs->vol_ctl = (u32)ANA_REG_GLB_MP_MISC_CTRL;
549 desc->regs->vol_ctl_bits = BIT(9)|BIT(10);
550 desc->regs->vol_sel[0] = 2500;
551 desc->regs->vol_sel[1] = 2750;
552 desc->regs->vol_sel[2] = 1800;
553 desc->regs->vol_sel[3] = 1900;
556 if (0 == strcmp(desc->name, "vddcore")) {
557 desc->regs->vol_def = 1100;
558 desc->regs->vol_ctl = (u32)ANA_REG_GLB_DCDC_CORE_ADI;
559 desc->regs->vol_ctl_bits = BIT(5)|BIT(6)|BIT(7);
560 } else if (0 == strcmp(desc->name, "vddarm")) {
561 desc->regs->vol_def = 1100;
562 desc->regs->vol_ctl = (u32)ANA_REG_GLB_DCDC_ARM_ADI;
563 desc->regs->vol_ctl_bits = BIT(5)|BIT(6)|BIT(7);
564 } else if (0 == strcmp(desc->name, "vdd25")) {
565 desc->regs->vol_def = 2500;
566 desc->regs->vol_ctl = (u32)ANA_REG_GLB_LDO_V_CTRL0;
567 desc->regs->vol_ctl_bits = BIT(4)|BIT(5);
568 desc->regs->vol_sel[0] = 2500;
569 desc->regs->vol_sel[1] = 2750;
570 desc->regs->vol_sel[2] = 3000;
571 desc->regs->vol_sel[3] = 2900;
576 if ((ana_status >> 4) & 0x1) {
577 if (0 == strcmp(desc->name, "vddwrf")) {
578 desc->regs->vol_def = 2800;
579 desc->regs->vol_sel[0] = 2600;
580 desc->regs->vol_sel[1] = 2700;
581 desc->regs->vol_sel[2] = 2800;
582 desc->regs->vol_sel[3] = 2900;
583 } else if (0 == strcmp(desc->name, "vddrf1")) {
584 desc->regs->vol_def = 2850;
585 desc->regs->vol_ctl = (u32)ANA_REG_GLB_LDO_V_CTRL0;
586 desc->regs->vol_ctl_bits = BIT(8)|BIT(9);
589 if (0 == strcmp(desc->name, "vddwrf")) {
590 desc->regs->vol_def = 1500;
591 desc->regs->vol_sel[0] = 1300;
592 desc->regs->vol_sel[1] = 1400;
593 desc->regs->vol_sel[2] = 1500;
594 desc->regs->vol_sel[3] = 1600;
595 } else if (0 == strcmp(desc->name, "vddrf1")) {
596 desc->regs->vol_def = 1200;
597 desc->regs->vol_ctl = (u32)ANA_REG_GLB_MP_MISC_CTRL;
598 desc->regs->vol_ctl_bits = BIT(11)|BIT(12);
603 ANA_REG_OR(regs->cal_ctl, ldo_cal_sel);
606 * FIXME: force get dcdc&ldo voltage from ana global regs
607 * and get ideal voltage from vol para.
609 if (desc->regs->typ == 2 /*DCDC*/) {
610 def_vol = dcdc_get_voltage(desc);
612 else if (desc->regs->typ == 0 /*LDO*/) {
613 def_vol = ldo_get_voltage(desc);
616 to_vol = regulator_default_get(desc->name);
618 to_vol = regs->vol_def;
620 adc_vol = sci_adc_vol_request(adc_chan, ADC_SCALE_3V, ldo_cal_sel, &adc);
622 debug1("%s default %dmv, adc channel %d, maybe not enable\n", desc->name, def_vol, adc_chan);
626 cal_vol = abs(adc_vol - to_vol);
627 debug1("%s chan[%d] adc %d, default %dmv, from %dmv to %dmv, bias %c%d.%03d%%\n",
628 desc->name, adc_chan, adc, def_vol, adc_vol, to_vol,
629 (adc_vol > to_vol) ? '+' : '-',
630 cal_vol * 100 / to_vol, cal_vol * 100 * 1000 / to_vol % 1000);
632 if (!def_vol || !to_vol || adc_vol <= 0)
634 if (abs(adc_vol - def_vol) >= def_vol / 9) /* adjust limit 9% */
636 else if (cal_vol < to_vol / 100) { /* bias 1% */
641 if (regs->typ == 2 /*VDD_TYP_DCDC*/)
642 ret = dcdc_set_trimming(desc, def_vol, to_vol, adc_vol);
643 else if (regs->typ == 0 /*VDD_TYP_LDO*/)
644 ret = ldo_set_trimming(desc, def_vol, to_vol, adc_vol);
647 regulator_default_set(desc->name, 0);
652 ANA_REG_BIC(regs->cal_ctl, ldo_cal_sel);
657 #ifndef CONFIG_ADIE_SC2713
658 int DCDC_Cal_ArmCore(void)
660 int SC2713S_DCDC_Cal_ArmCore(void)
663 u16 regval_dcdc_store, regval_ldo_store;
664 struct regulator_desc *desc = NULL;
665 struct regulator_desc *desc_end = NULL;
666 u32 cali_mask = regulator_get_calibration_mask(); //0xFFFF0FE2
667 u32 chip_id = ANA_GET_CHIP_ID();
669 int vbat_vol = sci_adc_vol_request(5, ADC_SCALE_3V, 0, &vbat_adc);
671 ana_status = ANA_REG_GET(ANA_REG_GLB_ANA_STATUS);
673 printf("%s; adie chip id: (0x%08x), bond opt: (0x%08x), cali_mask: (0x%08x), VBAT(vol %d, adc %d)\n",
674 __FUNCTION__, chip_id, ana_status, cali_mask, vbat_vol, vbat_adc);
676 cali_mask &= 0x01E00FFF;
678 regval_dcdc_store = ANA_REG_GET(ANA_REG_GLB_LDO_DCDC_PD_RTCSET) & 0xFFFF;
679 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD_RTCSET, (cali_mask >> 16));
681 regval_ldo_store = ANA_REG_GET(ANA_REG_GLB_LDO_PD_CTRL) & 0xFFFF;
682 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, cali_mask & 0xFFFF);
685 /* TODO: calibrate all DCDCs */
686 desc = (struct regulator_desc *)(&__init_begin + 1);
688 printf("%p (%x) -- %p -- %p (%x)\n", &__init_begin, __init_begin,
689 desc, &__init_end, __init_end);
691 desc_end = (struct regulator_desc *)(&__init_end) - 1;
692 while (desc_end >= desc) { /* reverse order */
693 DCDC_Cal_One(desc_end, 1);
698 #if defined(REGU_CALI_DEBUG)
699 /* wait a moment for LDOs ready */
700 udelay(10 * 1000); //delay 10ms
702 /* TODO: verify all DCDCs */
703 desc = (struct regulator_desc *)(&__init_begin + 1);
704 desc_end = (struct regulator_desc *)(&__init_end) - 1;
705 while (desc_end >= desc) { /* reverse order */
706 DCDC_Cal_One(desc_end, 0);
711 /* restore adie dcdc/ldo PD bits */
712 ANA_REG_SET(ANA_REG_GLB_LDO_PD_CTRL, regval_ldo_store);
713 ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD_RTCSET, regval_dcdc_store);
722 int regulator_init(void)
725 * FIXME: turn on all DCDC/LDOs if need
730 struct regulator_desc *regulator_get(void/*struct device*/ *dev, const char *id)
732 struct regulator_desc *desc =
733 (struct regulator_desc *)(&__init_begin + 1);
734 while (desc < (struct regulator_desc *)&__init_end) {
735 if (0 == strcmp(desc->name, id))
742 int regulator_disable_all(void)
744 ANA_REG_OR(ANA_REG_GLB_LDO_PD_CTRL, 0xFFF);
745 ANA_REG_OR(ANA_REG_GLB_LDO_DCDC_PD_RTCSET, 0xFFFF);
746 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD_RTCCLR, 0xFFFF);
750 int regulator_enable_all(void)
752 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD_RTCSET, 0xFFFF);
753 ANA_REG_OR(ANA_REG_GLB_LDO_DCDC_PD_RTCCLR, 0xFFFF);
754 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, 0xFFF);
758 int regulator_disable(const char con_id[])
760 struct regulator_desc *desc = regulator_get(0, con_id);
762 struct regulator_regs *regs = desc->regs;
763 ANA_REG_OR(regs->pd_set, regs->pd_set_bit);
768 int regulator_enable(const char con_id[])
770 struct regulator_desc *desc = regulator_get(0, con_id);
772 struct regulator_regs *regs = desc->regs;
773 ANA_REG_BIC(regs->pd_set, regs->pd_set_bit);
778 int regulator_set_voltage(const char con_id[], int to_vol)
781 struct regulator_desc *desc = regulator_get(0, con_id);
783 struct regulator_regs *regs = desc->regs;
784 if (regs->typ == 2/*VDD_TYP_DCDC*/)
785 ret = dcdc_set_voltage(desc, to_vol, 0);
786 else if (regs->typ == 0/*VDD_TYP_LDO*/)
787 ret = ldo_set_trimming(desc, 0, to_vol, 0);
797 #if defined(CONFIG_FDL2_BUILD)
798 vol_para_t **ppvol_para = 0x50000020;
800 vol_para_t **ppvol_para = 0x50005C20; //0x50003C20
803 static int get_vol_para_num(void)
807 if (!(ppvol_para && *ppvol_para))
810 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
813 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end"))
819 static vol_para_t * match_vol_para(const char* vol_name)
823 BUG_ON(NULL == vol_name);
825 if (!(ppvol_para && *ppvol_para))
828 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
831 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
832 if (0 == strcmp((*ppvol_para)[i].name, vol_name)) {
833 debug0("%s name %s, ideal_vol %d\n", __func__, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
834 return (vol_para_t*)(&(*ppvol_para)[i]);
841 int regulator_default_get(const char con_id[])
843 vol_para_t * pvol_para = match_vol_para(con_id);
845 return (int)(pvol_para ? pvol_para->ideal_vol : 0);
848 void regulator_default_set(const char con_id[], int vol)
850 vol_para_t * pvol_para = match_vol_para(con_id);
853 pvol_para->ideal_vol = vol;
857 int regulator_default_set_all(void)
861 //dump & check all vol para
862 if (!(ppvol_para && *ppvol_para))
865 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
868 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
869 debug("regu: [%d] %s : %d\n", i, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
871 ret |= regulator_set_voltage((*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
877 /********************************************************************
879 * regulator_get_calibration_mask - get dcdc/ldo calibration flag
882 //High 16bit: dcdc ctrl calibration flag
884 * bit[13] ~ bit[15] : reserved
890 * bit[7] : vddemmccore
900 //Low 16bit: ldo ctrl calibration flag
902 * bit[12] ~ bit[15] : reserved
915 ********************************************************************/
916 u32 regulator_get_calibration_mask(void)
918 int len = get_vol_para_num();
919 volatile vol_para_t *pvol_para = (volatile vol_para_t *)(*ppvol_para);
920 volatile u32* pdebug_flag = (u32*)(&pvol_para[len-1]);
923 printf("%s, vol_para_tbl_len %d, ldo_pd_mask 0x%08x; \n", __func__, len, *pdebug_flag);
924 return (*pdebug_flag);
930 /* register callback function after dcdc/ldo calibration */
931 int calibrate_register_callback(void* callback_fun)
934 calibrate_post = (pfun)callback_fun;