tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8830 / adc.c
1 #include <common.h>
2 #include <asm/io.h>
3 #include <asm/arch/adc_reg_v3.h>
4 #include <asm/arch/adc_drvapi.h>
5 #include <asm/arch/adi_hal_internal.h>
6 #include <asm/arch/sprd_reg.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_REG_GLB_ARM_MODULE_EN, BIT_ANA_ADC_EN); //ADC enable
14         ANA_REG_OR(ANA_REG_GLB_ARM_CLK_EN,    BIT_CLK_AUXAD_EN|BIT_CLK_AUXADC_EN); //enable auxad clock
15         ANA_REG_OR(ANA_REG_GLB_XTL_WAIT_CTRL,    BIT_XTL_EN);   //enable clk
16         __raw_writel(__raw_readl(REG_AON_APB_SINDRV_CTRL) |BIT_SINDRV_ENA, REG_AON_APB_SINDRV_CTRL);    //enable ddie to adie clk
17
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     {
36         ANA_REG_AND(ADC_CS, ~ADC_SCALE_BIT);
37     }
38     else if(ADC_SCALE_3V == scale)
39     {
40         ANA_REG_OR(ADC_CS, ADC_SCALE_BIT);
41     }
42     else
43     {
44         pr_err("adc scale %d not support\n", scale);
45     }
46 }
47
48 int32_t ADC_GetValues(adc_channel id, bool scale, uint8_t num, int32_t *p_buf)
49 {
50         int32_t count,i;
51
52         /* clear int */
53         ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT);
54
55         /* choose channel */
56         ADC_SetCs(id);
57
58         /* set ADC scale */
59         ADC_SetScale(scale);
60
61         /* set read numbers run ADC soft channel */
62         if (num < 1) {
63                 return -1;
64         }
65         ANA_REG_MSK_OR(ADC_CTRL, BIT_SW_CH_RUN_NUM(num), SW_CH_NUM_MSK);
66         ANA_REG_OR(ADC_CTRL, SW_CH_ON_BIT);
67
68         /* wait adc complete */
69         count = 1000;
70         while(!(ANA_REG_GET(ADC_INT_SRC)&ADC_IRQ_RAW_BIT) && count--) {
71                 for (i =0; i < 0xff; i++);
72         }
73         if (count <= 0) {
74                 pr_warning("WARNING: ADC_GetValue timeout....\n");
75                 return -1;
76         }
77
78         for (count = 0; count < num; count++) {
79                 p_buf[count] = ANA_REG_GET(ADC_DAT) & ADC_DATA_MSK;
80         }
81
82         ANA_REG_AND(ADC_CTRL, ~SW_CH_ON_BIT);                   // turn off adc soft channel
83         ANA_REG_MSK_OR(ADC_CTRL, BIT_SW_CH_RUN_NUM(1), SW_CH_NUM_MSK);
84         ADC_SetCs(TPC_CHANNEL_X);                                               // set tpc channel x back
85         ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT);               // clear irq of this time
86
87         return 0;
88 }
89 int32_t ADC_GetValue(adc_channel id, bool scale)
90 {
91         int32_t result;
92
93         if (-1 == ADC_GetValues(id, scale, 1, &result)) {
94                 return -1;
95         }
96
97         return result;
98 }