tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc9630 / 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 #if defined(CONFIG_FPGA)
14         return ;
15 #else
16         ANA_REG_OR(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_ADC_EN); //ADC enable
17         ANA_REG_OR(ANA_REG_GLB_ARM_CLK_EN,    BIT_CLK_AUXAD_EN|BIT_CLK_AUXADC_EN); //enable auxad clock
18         ANA_REG_OR(ANA_REG_GLB_XTL_WAIT_CTRL,    BIT_XTL_EN);   //enable clk
19         __raw_writel(__raw_readl(REG_AON_APB_SINDRV_CTRL) |BIT_SINDRV_ENA, REG_AON_APB_SINDRV_CTRL);    //enable ddie to adie clk
20
21         ANA_REG_OR(ADC_CTRL, ADC_EN_BIT);
22         ANA_REG_OR(ADC_CTRL, ADC_MODE_12B);
23 #endif
24 }
25
26 void ADC_SetCs(adc_channel id)
27 {
28 #if defined(CONFIG_FPGA)
29         return ;
30 #else
31     if(id >= ADC_MAX){
32         pr_err("adc limits to 0~%d\n", ADC_MAX);
33         return;
34     }
35
36     ANA_REG_MSK_OR(ADC_CS, id, ADC_CS_BIT_MSK);
37 #endif
38 }
39
40 void ADC_SetScale(bool scale)
41 {
42 #if defined(CONFIG_FPGA)
43     return;
44 #else
45
46     if(ADC_SCALE_1V2 == scale)
47     {
48         ANA_REG_AND(ADC_CS, ~ADC_SCALE_BIT);
49     }
50     else if(ADC_SCALE_3V == scale)
51     {
52         ANA_REG_OR(ADC_CS, ADC_SCALE_BIT);
53     }
54     else
55     {
56         pr_err("adc scale %d not support\n", scale);
57     }
58 #endif
59 }
60
61 int32_t ADC_GetValues(adc_channel id, bool scale, uint8_t num, int32_t *p_buf)
62 {
63 #if defined(CONFIG_FPGA)
64         return 0;
65 #else
66         int32_t count,i;
67
68         /* clear int */
69         ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT);
70
71         /* choose channel */
72         ADC_SetCs(id);
73
74         /* set ADC scale */
75         ADC_SetScale(scale);
76
77         /* set read numbers run ADC soft channel */
78         if (num < 1) {
79                 return -1;
80         }
81         ANA_REG_MSK_OR(ADC_CTRL, BIT_SW_CH_RUN_NUM(num), SW_CH_NUM_MSK);
82         ANA_REG_OR(ADC_CTRL, SW_CH_ON_BIT);
83
84         /* wait adc complete */
85         count = 1000;
86         while(!(ANA_REG_GET(ADC_INT_SRC)&ADC_IRQ_RAW_BIT) && count--) {
87                 for (i =0; i < 0xff; i++);
88         }
89         if (count <= 0) {
90                 pr_warning("WARNING: ADC_GetValue timeout....\n");
91                 return -1;
92         }
93
94         for (count = 0; count < num; count++) {
95                 p_buf[count] = ANA_REG_GET(ADC_DAT) & ADC_DATA_MSK;
96         }
97
98         ANA_REG_AND(ADC_CTRL, ~SW_CH_ON_BIT);                   // turn off adc soft channel
99         ANA_REG_MSK_OR(ADC_CTRL, BIT_SW_CH_RUN_NUM(1), SW_CH_NUM_MSK);
100         ADC_SetCs(TPC_CHANNEL_X);                                               // set tpc channel x back
101         ANA_REG_OR(ADC_INT_CLR, ADC_IRQ_CLR_BIT);               // clear irq of this time
102
103         return 0;
104 #endif
105 }
106 int32_t ADC_GetValue(adc_channel id, bool scale)
107 {
108 #if defined(CONFIG_FPGA)
109         return 0;
110 #else
111         int32_t result;
112
113         if (-1 == ADC_GetValues(id, scale, 1, &result)) {
114                 return -1;
115         }
116
117         return result;
118 #endif /* CONFIG_FPGA */
119 }