tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8825 / 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         uint32_t i;
14         ANA_REG_OR(ANA_APB_ARM_RST, ADC_RST_BIT);
15         for(i = 0; i < 0xff; i++);
16         ANA_REG_AND(ANA_APB_ARM_RST, ~ADC_RST_BIT);
17         ANA_REG_OR(ANA_APB_CLK_EN, ADC_EB | CLK_AUXAD_EN | CLK_AUXADC_EN);
18         ANA_REG_OR(ADC_CTRL, ADC_EN_BIT);
19         ANA_REG_OR(ADC_CTRL, ADC_MODE_12B);
20 }
21
22 void ADC_SetCs(adc_channel id)
23 {
24     if(id >= ADC_MAX){
25         pr_err("adc limits to 0~%d\n", ADC_MAX);
26         return;
27     }
28
29     ANA_REG_MSK_OR(ADC_CS, id, ADC_CS_BIT_MSK);
30 }
31
32 void ADC_SetScale(bool scale)
33 {
34     if(ADC_SCALE_1V2 == scale){
35         ANA_REG_AND(ADC_CS, ~ADC_SCALE_BIT);
36     }else if(ADC_SCALE_3V == scale){
37         ANA_REG_OR(ADC_CS, ADC_SCALE_BIT);
38     }else
39       pr_err("adc scale %d not support\n", scale);
40 }
41
42 int32_t ADC_GetValues(adc_channel id, bool scale, uint8_t num, int32_t *p_buf)
43 {
44         int32_t count;
45         uint8_t i;
46
47         /* clear int */
48         ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT);
49
50         /* choose channel */
51         ADC_SetCs(id);
52
53         /* set ADC scale */
54         ADC_SetScale(scale);
55
56         /* set read numbers run ADC soft channel */
57         if (num < 1) {
58                 return -1;
59         }
60         ANA_REG_MSK_OR(ADC_CTRL, BIT_SW_CH_RUN_NUM(num), SW_CH_NUM_MSK);
61         ANA_REG_OR(ADC_CTRL, SW_CH_ON_BIT);
62
63         /* wait adc complete */
64         count = 1000;
65         while(!(ANA_REG_GET(ADC_INT_SRC)&ADC_IRQ_RAW_BIT) && count--) {
66                 for (i = 0; i < 0xFF; i++);
67         }
68         if (count <= 0) {
69                 pr_warning("WARNING: ADC_GetValue timeout....\n");
70                 return -1;
71         }
72
73         for (i = 0; i < num; i++) {
74                 p_buf[i] = ANA_REG_GET(ADC_DAT) & ADC_DATA_MSK;
75         }
76
77         ANA_REG_AND(ADC_CTRL, ~SW_CH_ON_BIT);                   // turn off adc soft channel
78         return 0;
79 }
80 int32_t ADC_GetValue(adc_channel id, bool scale)
81 {
82         int32_t result;
83
84         if (-1 == ADC_GetValues(id, scale, 1, &result)) {
85                 return -1;
86         }
87
88         return result;
89 }