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