681 lines
16 KiB
C
681 lines
16 KiB
C
#include "typedef.h"
|
|
#include "asm/clock.h"
|
|
#include "asm/adc_api.h"
|
|
#include "timer.h"
|
|
#include "init.h"
|
|
#include "asm/efuse.h"
|
|
#include "irq.h"
|
|
#include "asm/power/p33.h"
|
|
#include "asm/power/p11.h"
|
|
#include "asm/power_interface.h"
|
|
#include "jiffies.h"
|
|
|
|
u32 adc_sample(u32 ch);
|
|
static volatile u16 _adc_res;
|
|
static volatile u16 cur_ch_value;
|
|
static u8 cur_ch = 0;
|
|
struct adc_info_t {
|
|
u32 ch;
|
|
u16 value;
|
|
u32 jiffies;
|
|
u32 sample_period;
|
|
};
|
|
|
|
#define ENABLE_OCCUPY_MODE 1
|
|
|
|
static struct adc_info_t adc_queue[ADC_MAX_CH + ENABLE_OCCUPY_MODE];
|
|
|
|
|
|
static u8 adc_sample_flag = 0;
|
|
|
|
static u16 dtemp_voltage = 0;
|
|
|
|
|
|
#define ADC_SRC_CLK clk_get("adc")
|
|
|
|
/*config adc clk according to sys_clk*/
|
|
static const u32 sys2adc_clk_info[] = {
|
|
128000000L,
|
|
96000000L,
|
|
72000000L,
|
|
48000000L,
|
|
24000000L,
|
|
12000000L,
|
|
6000000L,
|
|
1000000L,
|
|
};
|
|
|
|
u32 adc_add_sample_ch(u32 ch)
|
|
{
|
|
u32 i = 0;
|
|
for (i = 0; i < ADC_MAX_CH; i++) {
|
|
/* printf("%s() %d %x %x\n", __func__, i, ch, adc_queue[i].ch); */
|
|
if (adc_queue[i].ch == ch) {
|
|
break;
|
|
} else if (adc_queue[i].ch == -1) {
|
|
adc_queue[i].ch = ch;
|
|
adc_queue[i].value = 1;
|
|
adc_queue[i].jiffies = 0;
|
|
adc_queue[i].sample_period = msecs_to_jiffies(0);
|
|
printf("add sample ch %x\n", ch);
|
|
break;
|
|
}
|
|
}
|
|
return i;
|
|
}
|
|
|
|
u32 adc_set_sample_freq(u32 ch, u32 ms)
|
|
{
|
|
u32 i;
|
|
for (i = 0; i < ADC_MAX_CH; i++) {
|
|
if (adc_queue[i].ch == ch) {
|
|
adc_queue[i].sample_period = msecs_to_jiffies(ms);
|
|
adc_queue[i].jiffies = msecs_to_jiffies(ms) + jiffies;
|
|
break;
|
|
}
|
|
}
|
|
return i;
|
|
}
|
|
|
|
u32 adc_remove_sample_ch(u32 ch)
|
|
{
|
|
u32 i = 0;
|
|
for (i = 0; i < ADC_MAX_CH; i++) {
|
|
if (adc_queue[i].ch == ch) {
|
|
adc_queue[i].ch = -1;
|
|
break;
|
|
}
|
|
}
|
|
return i;
|
|
}
|
|
static u32 adc_get_next_ch(u32 cur_ch)
|
|
{
|
|
for (int i = cur_ch + 1; i < ADC_MAX_CH; i++) {
|
|
if (adc_queue[i].ch != -1) {
|
|
return i;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
#define PMU_CH_SAMPLE_FREQ 500 //ms
|
|
|
|
#define PMU_CH_VALUE_ARRAY_SIZE (16 + 1)
|
|
|
|
static u16 vbat_value_array[PMU_CH_VALUE_ARRAY_SIZE];
|
|
static u16 vbg_value_array[PMU_CH_VALUE_ARRAY_SIZE];
|
|
|
|
static void adc_value_push(u16 *array, u16 adc_value)
|
|
{
|
|
u16 pos = array[0];
|
|
pos++;
|
|
if (pos >= PMU_CH_VALUE_ARRAY_SIZE) {
|
|
pos = 1;
|
|
}
|
|
array[pos] = adc_value;
|
|
array[0] = pos;
|
|
}
|
|
|
|
static u16 adc_value_avg(u16 *array)
|
|
{
|
|
u32 i, j, sum = 0;
|
|
for (i = 1, j = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i++) {
|
|
if (array[i]) {
|
|
sum += array[i];
|
|
j += 1;
|
|
}
|
|
}
|
|
if (sum) {
|
|
return (sum / j);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void adc_value_array_reset(u16 *array)
|
|
{
|
|
for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i++) {
|
|
array[i] = 0;
|
|
}
|
|
}
|
|
|
|
u32 adc_get_value(u32 ch)
|
|
{
|
|
if (ch == AD_CH_VBAT) {
|
|
return adc_value_avg(vbat_value_array);
|
|
} else if (ch == AD_CH_LDOREF) {
|
|
return adc_value_avg(vbg_value_array);
|
|
}
|
|
|
|
for (int i = 0; i < ADC_MAX_CH; i++) {
|
|
if (adc_queue[i].ch == ch) {
|
|
return adc_queue[i].value;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
#define VBG_CENTER 801
|
|
#define VBG_RES 3
|
|
u32 adc_value_to_voltage(u32 adc_vbg, u32 adc_ch_val)
|
|
{
|
|
u32 adc_res = adc_ch_val;
|
|
u32 adc_trim = get_vbg_trim();
|
|
u32 tmp, tmp1;
|
|
|
|
tmp1 = adc_trim & 0x0f;
|
|
tmp = (adc_trim & BIT(4)) ? VBG_CENTER - tmp1 * VBG_RES : VBG_CENTER + tmp1 * VBG_RES;
|
|
/* printf("adc_res %d mv vbg:%d adc:%d adc_trim:%x\n", adc_res, adc_vbg, adc_ch_val, adc_trim); */
|
|
|
|
if (adc_vbg == 0) {
|
|
adc_vbg = 1; //防止div0异常
|
|
}
|
|
adc_res = adc_res * tmp / adc_vbg;
|
|
return adc_res;
|
|
}
|
|
|
|
u32 adc_get_voltage(u32 ch)
|
|
{
|
|
#ifdef CONFIG_FPGA_ENABLE
|
|
return 1000;
|
|
#endif
|
|
|
|
if (ch == AD_CH_DTEMP) {
|
|
return dtemp_voltage;
|
|
}
|
|
|
|
u32 adc_vbg = adc_get_value(AD_CH_LDOREF);
|
|
u32 adc_res = adc_get_value(ch);
|
|
return adc_value_to_voltage(adc_vbg, adc_res);
|
|
}
|
|
u32 adc_check_vbat_lowpower()
|
|
{
|
|
return 0;
|
|
}
|
|
void adc_audio_ch_select(u32 ch)
|
|
{
|
|
SFR(JL_ADDA->ADDA_CON1, 1, 1, 1);
|
|
SFR(JL_ADDA->ADDA_CON0, 0, 12, 0);
|
|
|
|
switch (ch << 16) {
|
|
case AD_AUDIO_VADADC:
|
|
SFR(JL_ADDA->ADDA_CON0, 12, 1, 1);
|
|
break;
|
|
case AD_AUDIO_VCM:
|
|
SFR(JL_ADDA->ADDA_CON0, 11, 1, 1);
|
|
break;
|
|
case AD_AUDIO_VBGLDO:
|
|
SFR(JL_ADDA->ADDA_CON0, 10, 1, 1);
|
|
break;
|
|
case AD_AUDIO_HPVDD:
|
|
SFR(JL_ADDA->ADDA_CON0, 9, 1, 1);
|
|
break;
|
|
case AD_AUDIO_RN:
|
|
SFR(JL_ADDA->ADDA_CON0, 4, 1, 1);
|
|
break;
|
|
case AD_AUDIO_RP:
|
|
SFR(JL_ADDA->ADDA_CON0, 3, 1, 1);
|
|
break;
|
|
case AD_AUDIO_LN:
|
|
SFR(JL_ADDA->ADDA_CON0, 2, 1, 1);
|
|
break;
|
|
case AD_AUDIO_LP:
|
|
SFR(JL_ADDA->ADDA_CON0, 1, 1, 1);
|
|
break;
|
|
case AD_AUDIO_DACVDD:
|
|
SFR(JL_ADDA->ADDA_CON0, 0, 1, 1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void adc_close()
|
|
{
|
|
JL_ADC->CON = 0;
|
|
JL_ADC->CON = 0;
|
|
}
|
|
void adc_suspend()
|
|
{
|
|
JL_ADC->CON &= ~BIT(4);
|
|
}
|
|
void adc_resume()
|
|
{
|
|
JL_ADC->CON |= BIT(4);
|
|
}
|
|
|
|
void adc_enter_occupy_mode(u32 ch)
|
|
{
|
|
if (JL_ADC->CON & BIT(4)) {
|
|
return;
|
|
}
|
|
adc_queue[ADC_MAX_CH].ch = ch;
|
|
cur_ch_value = adc_sample(ch);
|
|
}
|
|
void adc_exit_occupy_mode()
|
|
{
|
|
adc_queue[ADC_MAX_CH].ch = -1;
|
|
}
|
|
u32 adc_occupy_run()
|
|
{
|
|
if (adc_queue[ADC_MAX_CH].ch != -1) {
|
|
while (1) {
|
|
asm volatile("idle");//wait isr
|
|
if (_adc_res != (u16) - 1) {
|
|
break;
|
|
}
|
|
}
|
|
if (_adc_res == 0) {
|
|
_adc_res ++;
|
|
}
|
|
adc_queue[ADC_MAX_CH].value = _adc_res;
|
|
_adc_res = cur_ch_value;
|
|
return adc_queue[ADC_MAX_CH].value;
|
|
}
|
|
return 0;
|
|
}
|
|
u32 adc_get_occupy_value()
|
|
{
|
|
if (adc_queue[ADC_MAX_CH].ch != -1) {
|
|
return adc_queue[ADC_MAX_CH].value;
|
|
}
|
|
return 0;
|
|
}
|
|
u32 get_adc_div(u32 src_clk)
|
|
{
|
|
u32 adc_clk;
|
|
u32 adc_clk_idx;
|
|
u32 cnt;
|
|
adc_clk = src_clk;
|
|
cnt = ARRAY_SIZE(sys2adc_clk_info);
|
|
for (adc_clk_idx = 0; adc_clk_idx < cnt; adc_clk_idx ++) {
|
|
if (adc_clk > sys2adc_clk_info[adc_clk_idx]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (adc_clk_idx < cnt) {
|
|
adc_clk_idx = cnt - adc_clk_idx;
|
|
} else {
|
|
adc_clk_idx = cnt - 1;
|
|
}
|
|
return adc_clk_idx;
|
|
}
|
|
|
|
___interrupt
|
|
static void adc_isr()
|
|
{
|
|
_adc_res = JL_ADC->RES;
|
|
|
|
local_irq_disable();
|
|
JL_ADC->CON = BIT(6);
|
|
local_irq_enable();
|
|
|
|
#if 1
|
|
if (adc_sample_flag > 1) {
|
|
extern void adc_scan(void *priv);
|
|
adc_scan((void *)&adc_sample_flag);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
u32 adc_sample(u32 ch)
|
|
{
|
|
const u32 tmp_adc_res = _adc_res;
|
|
_adc_res = (u16) - 1;
|
|
|
|
u32 adc_con = 0;
|
|
SFR(adc_con, 0, 3, 0b110);//div 96
|
|
|
|
|
|
adc_con |= (0xf << 12); //启动延时控制,实际启动延时为此数值*8个ADC时钟
|
|
adc_con |= BIT(3); //ana en
|
|
adc_con |= BIT(6); //clr pend
|
|
adc_con |= BIT(5);//ie
|
|
adc_con |= BIT(17);//clk en
|
|
/* adc_con |= BIT(18)|BIT(19);//clk en */
|
|
|
|
SFR(adc_con, 21, 3, 0b010);
|
|
switch (ch & 0xff) {
|
|
case AD_CH_BT:
|
|
SFR(adc_con, 18, 3, AD_CH_BT & 0xf);
|
|
break;
|
|
case AD_CH_PMU:
|
|
if (adc_sample_flag > 1) {
|
|
SFR(adc_con, 0, 3, 0b011);//div 24
|
|
adc_con &= ~(0xf << 12);
|
|
}
|
|
SFR(adc_con, 18, 3, AD_CH_PMU & 0xf);
|
|
adc_pmu_ch_select(ch >> 16);
|
|
break;
|
|
|
|
case AD_CH_AUDIO:
|
|
SFR(adc_con, 18, 3, AD_CH_AUDIO & 0xf);
|
|
adc_audio_ch_select(ch >> 16);
|
|
break;
|
|
|
|
case AD_CH_LPCTM:
|
|
SFR(adc_con, 18, 3, AD_CH_LPCTM & 0xf);
|
|
break;
|
|
|
|
case AD_CH_X32K:
|
|
SFR(adc_con, 18, 3, AD_CH_X32K & 0xf);
|
|
break;
|
|
case AD_CH_PLL1:
|
|
SFR(adc_con, 18, 3, AD_CH_PLL1 & 0xf);
|
|
break;
|
|
default:
|
|
SFR(adc_con, 21, 3, 0b001);
|
|
SFR(adc_con, 8, 4, ch & 0xf);
|
|
break;
|
|
}
|
|
|
|
JL_ADC->CON = adc_con;
|
|
JL_ADC->CON |= BIT(4);//en
|
|
|
|
/* printf("ch %x %x %x %x",ch,ch >> 16,JL_ADC->CON,P3_ANA_CON4); */
|
|
|
|
JL_ADC->CON |= BIT(6);//kistart
|
|
|
|
return tmp_adc_res;
|
|
}
|
|
|
|
void adc_scan(void *priv)
|
|
{
|
|
static u16 vbg_adc_res = 0;
|
|
static u16 dtemp_adc_res = 0;
|
|
|
|
if ((priv == NULL) && (adc_sample_flag > 1)) {
|
|
return;
|
|
}
|
|
|
|
if (adc_queue[ADC_MAX_CH].ch != -1) { //occupy mode
|
|
return;
|
|
}
|
|
|
|
if (JL_ADC->CON & BIT(4)) {
|
|
adc_sample_flag = 0;
|
|
return ;
|
|
}
|
|
|
|
if (_adc_res == 0xffff) {
|
|
adc_sample_flag = 0;
|
|
}
|
|
|
|
if (adc_sample_flag) {
|
|
if (adc_sample_flag == 2) {
|
|
dtemp_adc_res = _adc_res;
|
|
adc_sample_flag = 3;
|
|
adc_sample(AD_CH_LDOREF);
|
|
return;
|
|
} else if (adc_sample_flag == 3) {
|
|
vbg_adc_res = _adc_res;
|
|
dtemp_voltage = adc_value_to_voltage(vbg_adc_res, dtemp_adc_res);
|
|
/* printf("vbg:%d dtemp:%d vol:%dmv\n", vbg_adc_res, dtemp_adc_res, dtemp_voltage); */
|
|
} else {
|
|
adc_queue[cur_ch].value = _adc_res;
|
|
if (adc_queue[cur_ch].ch == AD_CH_VBAT) {
|
|
adc_value_push(vbat_value_array, _adc_res);
|
|
/* printf("vbat %d",_adc_res); */
|
|
} else if (adc_queue[cur_ch].ch == AD_CH_LDOREF) {
|
|
adc_value_push(vbg_value_array, _adc_res);
|
|
/* printf("vbg %d",_adc_res); */
|
|
}
|
|
}
|
|
adc_sample_flag = 0;
|
|
}
|
|
|
|
u8 next_ch = adc_get_next_ch(cur_ch);
|
|
|
|
if (adc_queue[next_ch].sample_period) {
|
|
if (time_before(adc_queue[next_ch].jiffies, jiffies)) {
|
|
if (adc_queue[next_ch].ch == AD_CH_DTEMP) {
|
|
adc_sample_flag = 2;
|
|
} else {
|
|
adc_sample_flag = 1;
|
|
}
|
|
adc_sample(adc_queue[next_ch].ch);
|
|
adc_queue[next_ch].jiffies += adc_queue[next_ch].sample_period;
|
|
}
|
|
} else {
|
|
adc_sample(adc_queue[next_ch].ch);
|
|
adc_sample_flag = 1;
|
|
}
|
|
|
|
cur_ch = next_ch;
|
|
}
|
|
|
|
static u16 adc_wait_pnd()
|
|
{
|
|
while (!(JL_ADC->CON & BIT(7)));
|
|
u32 adc_res = JL_ADC->RES;
|
|
/* printf("adc_res =%d\n",adc_res); */
|
|
asm("nop");
|
|
JL_ADC->CON |= BIT(6);
|
|
return adc_res;
|
|
}
|
|
|
|
static int hpvdd_voltage = 0;
|
|
static void read_hpvdd_voltage(void)
|
|
{
|
|
int hpvdd_adc_value = 0;
|
|
int tvalue = 0;
|
|
adc_sample(AD_CH_AUDIO_HPVDD);
|
|
for (int i = 0; i < 10; i++) {
|
|
tvalue = adc_wait_pnd();
|
|
hpvdd_adc_value += tvalue;
|
|
}
|
|
hpvdd_adc_value /= 10;
|
|
|
|
u32 adc_vbg = adc_get_value(AD_CH_LDOREF);
|
|
hpvdd_voltage = adc_value_to_voltage(adc_vbg, hpvdd_adc_value);
|
|
printf("hpvdd = %d mV\n", hpvdd_voltage);
|
|
SFR(JL_ADDA->ADDA_CON0, 9, 1, 0);
|
|
}
|
|
|
|
int get_hpvdd_voltage(void)
|
|
{
|
|
return hpvdd_voltage;
|
|
}
|
|
|
|
void adc_reset(void)
|
|
{
|
|
int i, j;
|
|
local_irq_disable();
|
|
JL_ADC->CON = 0;
|
|
|
|
memset(vbg_value_array, 0x0, sizeof(vbg_value_array));
|
|
memset(vbat_value_array, 0x0, sizeof(vbat_value_array));
|
|
|
|
u32 sum_ad = 0;
|
|
adc_sample(AD_CH_LDOREF);
|
|
for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
|
|
sum_ad += adc_wait_pnd();
|
|
}
|
|
sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
|
|
adc_value_push(vbg_value_array, sum_ad);
|
|
printf("vbg_adc_value = %d\n", adc_value_avg(vbg_value_array));
|
|
|
|
sum_ad = 0;
|
|
adc_sample(AD_CH_VBAT);
|
|
for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
|
|
sum_ad += adc_wait_pnd();
|
|
}
|
|
sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
|
|
adc_value_push(vbat_value_array, sum_ad);
|
|
printf("vbat_adc_value = %d\n", adc_value_avg(vbat_value_array));
|
|
printf("vbat = %d mv\n", adc_get_voltage(AD_CH_VBAT) * 4);
|
|
|
|
JL_ADC->CON = BIT(6);
|
|
cur_ch = 0;
|
|
adc_sample_flag = 0;
|
|
local_irq_enable();
|
|
}
|
|
|
|
void _adc_init(u32 sys_lvd_en)
|
|
{
|
|
memset(adc_queue, 0xff, sizeof(adc_queue));
|
|
memset(vbg_value_array, 0x0, sizeof(vbg_value_array));
|
|
memset(vbat_value_array, 0x0, sizeof(vbat_value_array));
|
|
|
|
JL_ADC->CON = 0;
|
|
JL_ADC->CON = 0;
|
|
|
|
adc_add_sample_ch(AD_CH_LDOREF);
|
|
adc_set_sample_freq(AD_CH_LDOREF, PMU_CH_SAMPLE_FREQ);
|
|
|
|
adc_add_sample_ch(AD_CH_VBAT);
|
|
adc_set_sample_freq(AD_CH_VBAT, PMU_CH_SAMPLE_FREQ);
|
|
|
|
adc_add_sample_ch(AD_CH_DTEMP);
|
|
adc_set_sample_freq(AD_CH_DTEMP, PMU_CH_SAMPLE_FREQ);
|
|
|
|
u32 sum_ad = 0;
|
|
adc_sample(AD_CH_LDOREF);
|
|
for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
|
|
sum_ad += adc_wait_pnd();
|
|
}
|
|
sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
|
|
adc_value_push(vbg_value_array, sum_ad);
|
|
printf("vbg_adc_value = %d\n", adc_value_avg(vbg_value_array));
|
|
|
|
sum_ad = 0;
|
|
adc_sample(AD_CH_VBAT);
|
|
for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
|
|
sum_ad += adc_wait_pnd();
|
|
}
|
|
sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
|
|
adc_value_push(vbat_value_array, sum_ad);
|
|
printf("vbat_adc_value = %d\n", adc_value_avg(vbat_value_array));
|
|
printf("vbat = %d mv\n", adc_get_voltage(AD_CH_VBAT) * 4);
|
|
|
|
sum_ad = 0;
|
|
adc_sample(AD_CH_DTEMP);
|
|
for (int i = 0; i < PMU_CH_VALUE_ARRAY_SIZE; i ++) {
|
|
sum_ad += adc_wait_pnd();
|
|
}
|
|
sum_ad /= PMU_CH_VALUE_ARRAY_SIZE;
|
|
dtemp_voltage = adc_value_to_voltage(adc_value_avg(vbg_value_array), sum_ad);
|
|
printf("dtemp_adc_value = %d\n", sum_ad);
|
|
printf("dtemp = %d mv\n", dtemp_voltage);
|
|
|
|
read_hpvdd_voltage();
|
|
|
|
request_irq(IRQ_GPADC_IDX, 0, adc_isr, 0);
|
|
|
|
usr_timer_add(NULL, adc_scan, 5, 0); //2ms
|
|
|
|
/* void btosc_fast_boot_test(void); */
|
|
/* btosc_fast_boot_test(); */
|
|
/* sys_timer_add(NULL, adc_scan, 10); //2ms */
|
|
|
|
/* void adc_test(); */
|
|
/* usr_timer_add(NULL, adc_test, 1000, 0); //2ms */
|
|
|
|
/* extern void wdt_close(); */
|
|
/* wdt_close(); */
|
|
/* */
|
|
/* while(1); */
|
|
}
|
|
u32 get_vdd_voltage(u32 ch)
|
|
{
|
|
u32 vbg_value = 0;
|
|
u32 wvdd_value = 0;
|
|
|
|
adc_sample(AD_CH_LDOREF);
|
|
for (int i = 0; i < 10; i++) {
|
|
vbg_value += adc_wait_pnd();
|
|
}
|
|
|
|
adc_sample(ch);
|
|
for (int i = 0; i < 10; i++) {
|
|
wvdd_value += adc_wait_pnd();
|
|
}
|
|
|
|
u32 adc_vbg = vbg_value / 10;
|
|
u32 adc_res = wvdd_value / 10;
|
|
|
|
return adc_value_to_voltage(adc_vbg, adc_res);
|
|
}
|
|
|
|
|
|
#define ADC_SCAN_NUM 16
|
|
__attribute__((noinline))
|
|
AT(.volatile_ram_code)
|
|
u32 get_vddio_voltage()
|
|
{
|
|
|
|
u32 vbg_value = 0;
|
|
u32 vddio_value = 0;
|
|
u32 min = -1;
|
|
u32 max = 0;
|
|
adc_pmu_detect_en(0);
|
|
adc_sample(AD_CH_LDOREF);
|
|
for (int i = 0; i < ADC_SCAN_NUM; i++) {
|
|
while (!(JL_ADC->CON & BIT(7))) { //wait pending
|
|
}
|
|
|
|
u32 adc_res = JL_ADC->RES;
|
|
vbg_value += adc_res;
|
|
JL_ADC->CON |= BIT(6);
|
|
if (max < adc_res) {
|
|
max = adc_res;
|
|
}
|
|
if (min > adc_res) {
|
|
min = adc_res;
|
|
}
|
|
}
|
|
|
|
|
|
u32 adc_vbg = (vbg_value - max - min) / (ADC_SCAN_NUM - 2);
|
|
|
|
u32 adc_trim = get_vbg_trim();
|
|
|
|
u32 vbg_voltage, tmp1;
|
|
|
|
tmp1 = adc_trim & 0x0f;
|
|
vbg_voltage = (adc_trim & BIT(4)) ? VBG_CENTER - tmp1 * VBG_RES : VBG_CENTER + tmp1 * VBG_RES;
|
|
u32 vddio_voltage = vbg_voltage * 1023 / adc_vbg;
|
|
return vddio_voltage;
|
|
}
|
|
|
|
void adc_init()
|
|
{
|
|
adc_pmu_detect_en(1);
|
|
|
|
volatage_trim_init();
|
|
|
|
_adc_init(1);
|
|
}
|
|
//late_initcall(adc_init);
|
|
|
|
void adc_test()
|
|
{
|
|
/* void efuse_test(); */
|
|
/* efuse_test(); */
|
|
/* printf("\n\n%s() chip_id :%x\n", __func__, get_chip_id()); */
|
|
/* printf("%s() vbg trim:%x\n", __func__, get_vbg_trim()); */
|
|
/* printf("%s() vbat trim:%x\n", __func__, get_vbat_trim()); */
|
|
|
|
/* printf("\n\nWLA_CON0 %x\n", JL_ANA->WLA_CON0); */
|
|
/* printf("WLA_CON9 %x\n", JL_ANA->WLA_CON9); */
|
|
/* printf("WLA_CON10 %x\n", JL_ANA->WLA_CON10); */
|
|
/* printf("WLA_CON21 %x\n", JL_ANA->WLA_CON21); */
|
|
|
|
/* printf("ADA_CON %x\n", JL_ANA->ADA_CON3); */
|
|
/* printf("PLL_CON1 %x\n", JL_CLOCK->PLL_CON1); */
|
|
|
|
printf("\n%s() VBAT:%d %d mv\n\n", __func__,
|
|
adc_get_value(AD_CH_VBAT), adc_get_voltage(AD_CH_VBAT) * 4);
|
|
|
|
/* printf("\n%s() pa3:%d %d mv\n\n", __func__, */
|
|
/* adc_get_value(AD_CH_PA3), adc_get_voltage(AD_CH_PA3)); */
|
|
|
|
|
|
}
|
|
void adc_vbg_init()
|
|
{
|
|
return ;
|
|
}
|
|
//__initcall(adc_vbg_init);
|