adc_api.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. #include "typedef.h"
  2. #include "asm/clock.h"
  3. #include "asm/adc_api.h"
  4. #include "timer.h"
  5. #include "init.h"
  6. #include "asm/efuse.h"
  7. #include "irq.h"
  8. #include "asm/power/p33.h"
  9. #include "asm/power/p11.h"
  10. #include "asm/power_interface.h"
  11. #include "jiffies.h"
  12. #include "app_config.h"
  13. u32 adc_sample(u32 ch);
  14. static volatile u16 _adc_res;
  15. static volatile u16 cur_ch_value;
  16. static u8 cur_ch = 0;
  17. struct adc_info_t {
  18. u32 ch;
  19. u16 value;
  20. u32 jiffies;
  21. u32 sample_period;
  22. };
  23. #define ENABLE_OCCUPY_MODE 1
  24. static struct adc_info_t adc_queue[ADC_MAX_CH + ENABLE_OCCUPY_MODE];
  25. static u8 adc_sample_flag = 0;
  26. static u16 dtemp_voltage = 0;
  27. #define ADC_SRC_CLK clk_get("adc")
  28. /*config adc clk according to sys_clk*/
  29. static const u32 sys2adc_clk_info[] = {
  30. 128000000L,
  31. 96000000L,
  32. 72000000L,
  33. 48000000L,
  34. 24000000L,
  35. 12000000L,
  36. 6000000L,
  37. 1000000L,
  38. };
  39. u32 adc_add_sample_ch(u32 ch)
  40. {
  41. u32 i = 0;
  42. for (i = 0; i < ADC_MAX_CH; i++) {
  43. printf("%s() %d %x %x\n", __func__, i, ch, adc_queue[i].ch);
  44. if (adc_queue[i].ch == ch) {
  45. break;
  46. } else if (adc_queue[i].ch == -1) {
  47. adc_queue[i].ch = ch;
  48. adc_queue[i].value = 1;
  49. adc_queue[i].jiffies = 0;
  50. adc_queue[i].sample_period = msecs_to_jiffies(0);
  51. printf("add sample ch %x\n", ch);
  52. break;
  53. }
  54. }
  55. return i;
  56. }
  57. u32 adc_set_sample_freq(u32 ch, u32 ms)
  58. {
  59. u32 i;
  60. for (i = 0; i < ADC_MAX_CH; i++) {
  61. if (adc_queue[i].ch == ch) {
  62. adc_queue[i].sample_period = msecs_to_jiffies(ms);
  63. adc_queue[i].jiffies = msecs_to_jiffies(ms) + jiffies;
  64. break;
  65. }
  66. }
  67. return i;
  68. }
  69. u32 adc_remove_sample_ch(u32 ch)
  70. {
  71. u32 i = 0;
  72. for (i = 0; i < ADC_MAX_CH; i++) {
  73. if (adc_queue[i].ch == ch) {
  74. adc_queue[i].ch = -1;
  75. break;
  76. }
  77. }
  78. return i;
  79. }
  80. static u32 adc_get_next_ch(u32 cur_ch)
  81. {
  82. for (int i = cur_ch + 1; i < ADC_MAX_CH; i++) {
  83. if (adc_queue[i].ch != -1) {
  84. return i;
  85. }
  86. }
  87. return 0;
  88. }
  89. #define PMU_CH_SAMPLE_FREQ 500 //ms
  90. #define PMU_CH_VALUE_ARRAY_SIZE (16 + 1)
  91. static u16 vbat_value_array[PMU_CH_VALUE_ARRAY_SIZE];
  92. static u16 vbg_value_array[PMU_CH_VALUE_ARRAY_SIZE];
  93. static void adc_value_push(u16 *array, u16 adc_value)
  94. {
  95. u16 pos = array[0];
  96. pos++;
  97. if (pos >= PMU_CH_VALUE_ARRAY_SIZE) {
  98. pos = 1;
  99. }
  100. array[pos] = adc_value;
  101. array[0] = pos;
  102. }
  103. static u16 adc_value_avg(u16 *array)
  104. {
  105. u32 i, j, sum = 0;
  106. for (i = 1, j = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i++) {
  107. if (array[i]) {
  108. sum += array[i];
  109. j += 1;
  110. }
  111. }
  112. if (sum) {
  113. return (sum / j);
  114. }
  115. return 1;
  116. }
  117. static void adc_value_array_reset(u16 *array)
  118. {
  119. for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i++) {
  120. array[i] = 0;
  121. }
  122. }
  123. u32 adc_get_value(u32 ch)
  124. {
  125. if (ch == AD_CH_VBAT) {
  126. return adc_value_avg(vbat_value_array);
  127. } else if (ch == AD_CH_LDOREF) {
  128. return adc_value_avg(vbg_value_array);
  129. }
  130. for (int i = 0; i < ADC_MAX_CH; i++) {
  131. if (adc_queue[i].ch == ch) {
  132. return adc_queue[i].value;
  133. }
  134. }
  135. return 1;
  136. }
  137. #define VBG_CENTER 801
  138. #define VBG_RES 3
  139. u32 adc_value_to_voltage(u32 adc_vbg, u32 adc_ch_val)
  140. {
  141. u32 adc_res = adc_ch_val;
  142. u32 adc_trim = get_vbg_trim();
  143. u32 tmp, tmp1;
  144. tmp1 = adc_trim & 0x0f;
  145. tmp = (adc_trim & BIT(4)) ? VBG_CENTER - tmp1 * VBG_RES : VBG_CENTER + tmp1 * VBG_RES;
  146. adc_res = adc_res * tmp / adc_vbg;
  147. //printf("adc_res %d mv vbg:%d adc:%d adc_trim:%x\n", adc_res, adc_vbg, adc_ch_val, adc_trim);
  148. return adc_res;
  149. }
  150. u32 adc_get_voltage(u32 ch)
  151. {
  152. #ifdef CONFIG_FPGA_ENABLE
  153. return 1000;
  154. #endif
  155. if (ch == AD_CH_DTEMP) {
  156. return dtemp_voltage;
  157. }
  158. u32 adc_vbg = adc_get_value(AD_CH_LDOREF);
  159. u32 adc_res = adc_get_value(ch);
  160. return adc_value_to_voltage(adc_vbg, adc_res);
  161. }
  162. /*
  163. 1、第一次上电: 电压小于2.4v,不允许切dcdc模式
  164. 2、运行中,当检测到电压小于2.4v,切换为ldo模式
  165. 2、运行中,当检测到电压大于2.4v,切换相应的电源模式
  166. */
  167. void power_set_ldo_for_lowpower(u8 en);
  168. u8 power_set_ldo_for_lowpower_check(u8 init)
  169. {
  170. static u8 ldo_lowpower = 0;
  171. /*
  172. 电池电压小于2.4v时,切换成ldo模式
  173. */
  174. u32 vbat = adc_get_voltage(AD_CH_VBAT) * 4;
  175. if (vbat < 2400) {
  176. if (ldo_lowpower == 0) {
  177. local_irq_disable();
  178. power_set_ldo_for_lowpower(1);
  179. power_set_mode(PWR_LDO15);
  180. ldo_lowpower = 1;
  181. local_irq_enable();
  182. }
  183. } else {
  184. if (ldo_lowpower) {
  185. local_irq_disable();
  186. power_set_ldo_for_lowpower(0);
  187. if (TCFG_LOWPOWER_POWER_SEL == PWR_DCDC15) {
  188. if (get_charge_online_flag()) {
  189. power_set_mode(PWR_DCDC15_FOR_CHARGE);
  190. } else {
  191. power_set_mode(PWR_DCDC15);
  192. }
  193. }
  194. ldo_lowpower = 0;
  195. local_irq_enable();
  196. }
  197. }
  198. }
  199. u32 adc_check_vbat_lowpower()
  200. {
  201. power_set_ldo_for_lowpower_check(0);
  202. return 0;
  203. }
  204. void adc_audio_ch_select(u32 ch)
  205. {
  206. /* SFR(JL_ANA->DAA_CON0, 12, 4, ch); */
  207. }
  208. void adc_close()
  209. {
  210. JL_ADC->CON = 0;
  211. JL_ADC->CON = 0;
  212. }
  213. void adc_suspend()
  214. {
  215. JL_ADC->CON &= ~BIT(4);
  216. }
  217. void adc_resume()
  218. {
  219. JL_ADC->CON |= BIT(4);
  220. }
  221. void adc_enter_occupy_mode(u32 ch)
  222. {
  223. if (JL_ADC->CON & BIT(4)) {
  224. return;
  225. }
  226. adc_queue[ADC_MAX_CH].ch = ch;
  227. cur_ch_value = adc_sample(ch);
  228. }
  229. void adc_exit_occupy_mode()
  230. {
  231. adc_queue[ADC_MAX_CH].ch = -1;
  232. }
  233. u32 adc_occupy_run()
  234. {
  235. if (adc_queue[ADC_MAX_CH].ch != -1) {
  236. while (1) {
  237. asm volatile("idle");//wait isr
  238. if (_adc_res != (u16) - 1) {
  239. break;
  240. }
  241. }
  242. if (_adc_res == 0) {
  243. _adc_res ++;
  244. }
  245. adc_queue[ADC_MAX_CH].value = _adc_res;
  246. _adc_res = cur_ch_value;
  247. return adc_queue[ADC_MAX_CH].value;
  248. }
  249. return 0;
  250. }
  251. u32 adc_get_occupy_value()
  252. {
  253. if (adc_queue[ADC_MAX_CH].ch != -1) {
  254. return adc_queue[ADC_MAX_CH].value;
  255. }
  256. return 0;
  257. }
  258. u32 get_adc_div(u32 src_clk)
  259. {
  260. u32 adc_clk;
  261. u32 adc_clk_idx;
  262. u32 cnt;
  263. adc_clk = src_clk;
  264. cnt = ARRAY_SIZE(sys2adc_clk_info);
  265. for (adc_clk_idx = 0; adc_clk_idx < cnt; adc_clk_idx ++) {
  266. if (adc_clk > sys2adc_clk_info[adc_clk_idx]) {
  267. break;
  268. }
  269. }
  270. if (adc_clk_idx < cnt) {
  271. adc_clk_idx = cnt - adc_clk_idx;
  272. } else {
  273. adc_clk_idx = cnt - 1;
  274. }
  275. return adc_clk_idx;
  276. }
  277. ___interrupt
  278. static void adc_isr()
  279. {
  280. _adc_res = JL_ADC->RES;
  281. /* P33_CON_SET(P3_ANA_CON4, 5, 1, 0); */
  282. local_irq_disable();
  283. JL_ADC->CON = BIT(6);
  284. local_irq_enable();
  285. #if 1
  286. if (adc_sample_flag > 1) {
  287. extern void adc_scan(void *priv);
  288. adc_scan(NULL);
  289. }
  290. #endif
  291. }
  292. u32 adc_sample(u32 ch)
  293. {
  294. const u32 tmp_adc_res = _adc_res;
  295. _adc_res = (u16) - 1;
  296. u32 adc_con = 0;
  297. SFR(adc_con, 0, 3, 0b110);//div 96
  298. adc_con |= (0xf << 12); //启动延时控制,实际启动延时为此数值*8个ADC时钟
  299. adc_con |= BIT(3); //ana en
  300. adc_con |= BIT(6); //en
  301. adc_con |= BIT(5);//ie
  302. SFR(adc_con, 8, 4, ch & 0xf);
  303. if ((ch & 0xffff) == AD_CH_PMU) {
  304. if (adc_sample_flag > 1) {
  305. SFR(adc_con, 0, 3, 0b011);//div 24
  306. adc_con &= ~(0xf << 12);
  307. }
  308. adc_pmu_ch_select(ch >> 16);
  309. }
  310. JL_ADC->CON = adc_con;
  311. JL_ADC->CON |= BIT(4);//en
  312. JL_ADC->CON |= BIT(6);//kistart
  313. return tmp_adc_res;
  314. }
  315. void adc_scan(void *priv)
  316. {
  317. static u16 vbg_adc_res = 0;
  318. static u16 dtemp_adc_res = 0;
  319. if (adc_queue[ADC_MAX_CH].ch != -1) { //occupy mode
  320. return;
  321. }
  322. if (JL_ADC->CON & BIT(4)) {
  323. adc_sample_flag = 0;
  324. return ;
  325. }
  326. if (adc_sample_flag) {
  327. if (adc_sample_flag == 2) {
  328. dtemp_adc_res = _adc_res;
  329. adc_sample_flag = 3;
  330. adc_sample(AD_CH_LDOREF);
  331. return;
  332. } else if (adc_sample_flag == 3) {
  333. vbg_adc_res = _adc_res;
  334. dtemp_voltage = adc_value_to_voltage(vbg_adc_res, dtemp_adc_res);
  335. /* printf("vbg:%d dtemp:%d vol:%dmv\n", vbg_adc_res, dtemp_adc_res, dtemp_voltage); */
  336. } else {
  337. adc_queue[cur_ch].value = _adc_res;
  338. if (adc_queue[cur_ch].ch == AD_CH_VBAT) {
  339. adc_value_push(vbat_value_array, _adc_res);
  340. /* printf("vbat %d",_adc_res); */
  341. } else if (adc_queue[cur_ch].ch == AD_CH_LDOREF) {
  342. adc_value_push(vbg_value_array, _adc_res);
  343. /* printf("vbg %d",_adc_res); */
  344. }
  345. }
  346. adc_sample_flag = 0;
  347. }
  348. u8 next_ch = adc_get_next_ch(cur_ch);
  349. if (adc_queue[next_ch].sample_period) {
  350. if (time_before(adc_queue[next_ch].jiffies, jiffies)) {
  351. if (adc_queue[next_ch].ch == AD_CH_DTEMP) {
  352. adc_sample_flag = 2;
  353. } else {
  354. adc_sample_flag = 1;
  355. }
  356. adc_sample(adc_queue[next_ch].ch);
  357. adc_queue[next_ch].jiffies += adc_queue[next_ch].sample_period;
  358. }
  359. } else {
  360. adc_sample(adc_queue[next_ch].ch);
  361. adc_sample_flag = 1;
  362. }
  363. cur_ch = next_ch;
  364. }
  365. static u16 adc_wait_pnd()
  366. {
  367. while (!(JL_ADC->CON & BIT(7)));
  368. u32 adc_res = JL_ADC->RES;
  369. asm("nop");
  370. JL_ADC->CON |= BIT(6);
  371. return adc_res;
  372. }
  373. void _adc_init(u32 sys_lvd_en)
  374. {
  375. memset(adc_queue, 0xff, sizeof(adc_queue));
  376. memset(vbg_value_array, 0x0, sizeof(vbg_value_array));
  377. memset(vbat_value_array, 0x0, sizeof(vbat_value_array));
  378. JL_ADC->CON = 0;
  379. adc_add_sample_ch(AD_CH_LDOREF);
  380. adc_set_sample_freq(AD_CH_LDOREF, PMU_CH_SAMPLE_FREQ);
  381. adc_add_sample_ch(AD_CH_VBAT);
  382. adc_set_sample_freq(AD_CH_VBAT, PMU_CH_SAMPLE_FREQ);
  383. adc_add_sample_ch(AD_CH_DTEMP);
  384. adc_set_sample_freq(AD_CH_DTEMP, PMU_CH_SAMPLE_FREQ);
  385. u32 sum_ad = 0;
  386. adc_sample(AD_CH_LDOREF);
  387. for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
  388. sum_ad += adc_wait_pnd();
  389. }
  390. sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
  391. adc_value_push(vbg_value_array, sum_ad);
  392. printf("vbg_adc_value = %d\n", adc_value_avg(vbg_value_array));
  393. sum_ad = 0;
  394. adc_sample(AD_CH_VBAT);
  395. for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
  396. sum_ad += adc_wait_pnd();
  397. }
  398. sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
  399. adc_value_push(vbat_value_array, sum_ad);
  400. printf("vbat_adc_value = %d\n", adc_value_avg(vbat_value_array));
  401. printf("vbat = %d mv\n", adc_get_voltage(AD_CH_VBAT) * 4);
  402. sum_ad = 0;
  403. adc_sample(AD_CH_DTEMP);
  404. for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
  405. sum_ad += adc_wait_pnd();
  406. }
  407. sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
  408. dtemp_voltage = adc_value_to_voltage(adc_value_avg(vbg_value_array), sum_ad);
  409. printf("dtemp_adc_value = %d\n", sum_ad);
  410. printf("dtemp = %d mv\n", dtemp_voltage);
  411. request_irq(IRQ_SARADC_IDX, 0, adc_isr, 0);
  412. usr_timer_add(NULL, adc_scan, 5, 0); //2ms
  413. /* sys_timer_add(NULL, adc_scan, 10); //2ms */
  414. /* void adc_test(); */
  415. /* usr_timer_add(NULL, adc_test, 1000, 0); //2ms */
  416. /* extern void wdt_close(); */
  417. /* wdt_close(); */
  418. /* */
  419. /* while(1); */
  420. }
  421. static u32 get_vdd_voltage(u32 ch)
  422. {
  423. u32 vbg_value = 0;
  424. u32 wvdd_value = 0;
  425. adc_sample(AD_CH_LDOREF);
  426. for (int i = 0; i < 10; i++) {
  427. vbg_value += adc_wait_pnd();
  428. }
  429. adc_sample(ch);
  430. for (int i = 0; i < 10; i++) {
  431. wvdd_value += adc_wait_pnd();
  432. }
  433. u32 adc_vbg = vbg_value / 10;
  434. u32 adc_res = wvdd_value / 10;
  435. return adc_value_to_voltage(adc_vbg, adc_res);
  436. }
  437. u8 wvdd_efuse_level[4] = {WVDD_VOL_SEL_065V, WVDD_VOL_SEL_070V, WVDD_VOL_SEL_075V, WVDD_VOL_SEL_080V};
  438. static u8 wvdd_trim(u8 trim)
  439. {
  440. u8 wvdd_lev = 0;
  441. u8 wvdd_efuse_lev = ((p33_rd_page(1) >> 24) & 0x3);
  442. if (trim) {
  443. wvdd_lev = wvdd_efuse_level[wvdd_efuse_lev];
  444. } else {
  445. wvdd_lev = get_wvdd_trim_level();
  446. }
  447. if (wvdd_lev < WVDD_VOL_SEL_065V) {
  448. wvdd_lev = WVDD_VOL_SEL_080V;
  449. }
  450. printf("trim: %d, wvdd_lev: %d\n", trim, wvdd_lev);
  451. M2P_WDVDD = wvdd_lev;
  452. return wvdd_lev;
  453. }
  454. static u8 pvdd_trim(u8 trim)
  455. {
  456. u32 v = 0;
  457. u32 lev = 0xf;
  458. u8 err = 0;
  459. if (trim) {
  460. for (; lev; lev--) {
  461. P33_CON_SET(P3_PVDD1_AUTO, 0, 8, (lev | lev << 4));
  462. delay(2000);//1ms
  463. v = get_vdd_voltage(AD_CH_PVDD);
  464. if (v < (PVDD_VOL_TRIM + PVDD_VOL_STEP)) {
  465. break;
  466. }
  467. }
  468. if (v < PVDD_VOL_TRIM) {
  469. if (lev < PVDD_LEVEL_MAX) {
  470. lev++;
  471. }
  472. }
  473. //update_pvdd_trim_level(lev);
  474. } else {
  475. lev = get_pvdd_trim_level();
  476. }
  477. #if 0
  478. printf("pvdd min: %d, max: %d, def_lev: %d\n", (PVDD_VOL_TRIM - PVDD_VOL_MIN) / PVDD_VOL_STEP - 2, \
  479. (PVDD_VOL_TRIM - PVDD_VOL_MIN) / PVDD_VOL_STEP + 2, \
  480. PVDD_LEVEL_DEFAULT);
  481. #endif
  482. printf("trim: %d, pvdd_lev: %d, pvdd_lev_l: %d\n", trim, lev, lev - PVDD_LEVEL_TRIM_LOW);
  483. if (trim) {
  484. u8 min = (PVDD_VOL_TRIM - PVDD_VOL_MIN) / PVDD_VOL_STEP - 2;
  485. u8 max = (PVDD_VOL_TRIM - PVDD_VOL_MIN) / PVDD_VOL_STEP + 2;
  486. if (!(lev >= min && lev <= max)) {
  487. lev = PVDD_LEVEL_DEFAULT;
  488. err = 1;
  489. }
  490. }
  491. P33_CON_SET(P3_PVDD1_AUTO, 0, 8, (lev | lev << 4));
  492. delay(2000);
  493. P33_CON_SET(P3_PVDD0_AUTO, 0, 8, (7 << 4) | (lev - PVDD_LEVEL_TRIM_LOW));
  494. if (err) {
  495. return PVDD_LEVEL_ERR;
  496. }
  497. return lev;
  498. }
  499. void adc_init()
  500. {
  501. adc_pmu_detect_en(1);
  502. //trim wvdd
  503. u8 trim = check_wvdd_pvdd_trim(0);
  504. u8 wvdd_lev = wvdd_trim(trim);
  505. u8 pvdd_lev = pvdd_trim(trim);
  506. if (trim) {
  507. if ((wvdd_lev != WVDD_LEVEL_ERR) && (pvdd_lev != PVDD_LEVEL_ERR)) {
  508. update_wvdd_pvdd_trim_level(wvdd_lev, pvdd_lev);
  509. }
  510. }
  511. _adc_init(1);
  512. //这个函数之后才能切电源模式
  513. power_set_ldo_for_lowpower_check(1);
  514. }
  515. //late_initcall(adc_init);
  516. void adc_test()
  517. {
  518. /* printf("\n\n%s() chip_id :%x\n", __func__, get_chip_id()); */
  519. /* printf("%s() vbg trim:%x\n", __func__, get_vbg_trim()); */
  520. /* printf("%s() vbat trim:%x\n", __func__, get_vbat_trim()); */
  521. /* printf("\n\nWLA_CON0 %x\n", JL_ANA->WLA_CON0); */
  522. /* printf("WLA_CON9 %x\n", JL_ANA->WLA_CON9); */
  523. /* printf("WLA_CON10 %x\n", JL_ANA->WLA_CON10); */
  524. /* printf("WLA_CON21 %x\n", JL_ANA->WLA_CON21); */
  525. /* printf("ADA_CON %x\n", JL_ANA->ADA_CON3); */
  526. /* printf("PLL_CON1 %x\n", JL_CLOCK->PLL_CON1); */
  527. printf("\n%s() VBAT:%d %d mv\n\n", __func__,
  528. adc_get_value(AD_CH_VBAT), adc_get_voltage(AD_CH_VBAT) * 4);
  529. /* printf("\n%s() pa3:%d %d mv\n\n", __func__, */
  530. /* adc_get_value(AD_CH_PA3), adc_get_voltage(AD_CH_PA3)); */
  531. }
  532. void adc_vbg_init()
  533. {
  534. return ;
  535. }
  536. //__initcall(adc_vbg_init);