tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / arm926ejs / sc8800g / adc.c
1 #include <common.h>
2 #include <asm/arch/adc_reg_v3.h>
3 #include <asm/arch/regs_adi.h>
4 #include <asm/arch/regs_ana.h>
5 #include <asm/arch/adc_drvapi.h>
6 #include <asm/arch/adi_hal_internal.h>
7
8 #define pr_err(fmt...) printf(fmt)
9 #define pr_warning(fmt...) printf(fmt)
10
11 void ADC_Init(void)
12 {
13     ANA_REG_OR(ANA_AGEN, AGEN_ADC_EN);
14     ANA_REG_OR(ANA_CLK_CTL, ACLK_CTL_AUXAD_EN | ACLK_CTL_AUXADC_EN);
15     ANA_REG_OR(ADC_CTRL, ADC_EN_BIT);
16 }
17
18 void ADC_SetCs(adc_channel id)
19 {
20     if(id >= ADC_MAX){
21         pr_err("adc limits to 0~%d\n", ADC_MAX);
22         return;
23     }
24
25     ANA_REG_MSK_OR(ADC_CS, id, ADC_CS_BIT_MSK);
26 }
27
28 void ADC_SetScale(bool scale)
29 {
30     if(ADC_SCALE_1V2 == scale){
31         ANA_REG_AND(ADC_CS, ~ADC_SCALE_BIT);
32     }else if(ADC_SCALE_3V == scale){
33         ANA_REG_OR(ADC_CS, ADC_SCALE_BIT);
34     }else
35       pr_err("adc scale %d not support\n", scale);
36 }
37
38 void ADC_ConfigTPC(uint8_t x, uint8_t y)
39 {
40     if(x > ADC_MAX || y > ADC_MAX){
41         pr_err("tpc x and y channel should be in 0~%d\n", ADC_MAX);
42         return;
43     }
44
45     ANA_REG_MSK_OR(ADC_TPC_CH_CTRL, x|y<<ADC_TPC_Y_CH_OFFSET, ADC_TPC_X_CH_MSK|ADC_TPC_Y_CH_MSK);
46 }
47
48 int32_t ADC_GetValue(adc_channel id, bool scale)
49 {
50     uint32_t result;
51     unsigned long irq_flag;
52     uint32_t count;
53
54     // clear int 
55     ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT);
56
57     //choose channel
58     ADC_SetCs(id);
59
60     //set ADC scale
61     ADC_SetScale(scale);
62
63     //run ADC soft channel
64     ANA_REG_OR(ADC_CTRL, SW_CH_ON_BIT);
65
66     count = 12;
67
68     //wait adc complete
69     while(!(ANA_REG_GET(ADC_INT_SRC)&ADC_IRQ_RAW_BIT) && count){
70         udelay(50);
71         count--;
72     }
73     if (count == 0) {
74         pr_warning("WARNING: ADC_GetValue timeout....\n");
75         return -1;
76     }
77
78     result = ANA_REG_GET(ADC_DAT) & ADC_DATA_MSK; // get adc value
79     ANA_REG_AND(ADC_CTRL, ~SW_CH_ON_BIT); // turn off adc soft channel
80     ADC_SetCs(TPC_CHANNEL_X);             // set tpc channel x back
81     ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT); // clear irq of this time
82
83     return result;
84 }