diff options
Diffstat (limited to 'firmware/target/arm/pp/adc-pp5020.c')
-rw-r--r-- | firmware/target/arm/pp/adc-pp5020.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/firmware/target/arm/pp/adc-pp5020.c b/firmware/target/arm/pp/adc-pp5020.c new file mode 100644 index 0000000000..2d75a7e25f --- /dev/null +++ b/firmware/target/arm/pp/adc-pp5020.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include "system.h" | ||
24 | #include "kernel.h" | ||
25 | #include "thread.h" | ||
26 | #include "adc.h" | ||
27 | |||
28 | #define ADC_ADDR (*(volatile unsigned long*)(0x7000ad00)) | ||
29 | #define ADC_STATUS (*(volatile unsigned long*)(0x7000ad04)) | ||
30 | #define ADC_DATA_1 (*(volatile unsigned long*)(0x7000ad20)) | ||
31 | #define ADC_DATA_2 (*(volatile unsigned long*)(0x7000ad24)) | ||
32 | #define ADC_INIT (*(volatile unsigned long*)(0x7000ad2c)) | ||
33 | |||
34 | #if defined(PBELL_VIBE500) | ||
35 | #define ADC_UNK (*(volatile unsigned long*)(0x7000002c)) | ||
36 | #endif | ||
37 | |||
38 | static unsigned short adcdata[NUM_ADC_CHANNELS]; | ||
39 | |||
40 | /* Scan ADC so that adcdata[channel] gets updated. */ | ||
41 | unsigned short adc_scan(int channel) | ||
42 | { | ||
43 | unsigned int adc_data_1; | ||
44 | unsigned int adc_data_2; | ||
45 | |||
46 | if (channel >= NUM_ADC_CHANNELS) | ||
47 | return 0; | ||
48 | |||
49 | /* Start conversion */ | ||
50 | ADC_ADDR |= 0x80000000; | ||
51 | |||
52 | /* Wait for conversion to complete */ | ||
53 | while((ADC_STATUS & (0x40<<8*channel))==0); | ||
54 | |||
55 | /* Stop conversion */ | ||
56 | ADC_ADDR &=~ 0x80000000; | ||
57 | |||
58 | /* ADC_DATA_1 and ADC_DATA_2 are both four bytes, one byte per channel. | ||
59 | For each channel, ADC_DATA_1 stores the 8-bit msb, ADC_DATA_2 stores the | ||
60 | 2-bit lsb (in bits 0 and 1). Each channel is 10 bits total. */ | ||
61 | adc_data_1 = ((ADC_DATA_1 >> (8*channel)) & 0xff); | ||
62 | adc_data_2 = ((ADC_DATA_2 >> (8*channel+6)) & 0x3); | ||
63 | |||
64 | adcdata[channel] = (adc_data_1<<2 | adc_data_2); | ||
65 | |||
66 | #if !(defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)) | ||
67 | /* ADC values read low if PLL is enabled */ | ||
68 | if(PLL_CONTROL & 0x80000000){ | ||
69 | adcdata[channel] += 0x14; | ||
70 | if(adcdata[channel] > 0x400) | ||
71 | adcdata[channel] = 0x400; | ||
72 | } | ||
73 | #endif | ||
74 | |||
75 | return adcdata[channel]; | ||
76 | } | ||
77 | |||
78 | /* Read 10-bit channel data */ | ||
79 | unsigned short adc_read(int channel) | ||
80 | { | ||
81 | return adcdata[channel]; | ||
82 | } | ||
83 | |||
84 | static int adc_counter; | ||
85 | |||
86 | static void adc_tick(void) | ||
87 | { | ||
88 | if(++adc_counter == HZ) | ||
89 | { | ||
90 | adc_counter = 0; | ||
91 | adc_scan(0); | ||
92 | adc_scan(1); | ||
93 | adc_scan(2); | ||
94 | adc_scan(3); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* Figured out from how the OF does things */ | ||
99 | void adc_init(void) | ||
100 | { | ||
101 | #if defined(PBELL_VIBE500) | ||
102 | ADC_UNK |= 0x1000; | ||
103 | #endif | ||
104 | |||
105 | #if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) | ||
106 | ADC_INIT = 0; | ||
107 | #else | ||
108 | ADC_INIT |= 1; | ||
109 | ADC_INIT |= 0x40000000; | ||
110 | #endif | ||
111 | udelay(100); | ||
112 | |||
113 | /* Reset ADC */ | ||
114 | DEV_RS2 |= 0x20; | ||
115 | udelay(100); | ||
116 | |||
117 | DEV_RS2 &=~ 0x20; | ||
118 | udelay(100); | ||
119 | |||
120 | /* Enable ADC */ | ||
121 | DEV_EN2 |= 0x20; | ||
122 | udelay(100); | ||
123 | |||
124 | ADC_CLOCK_SRC |= 0x3; | ||
125 | udelay(100); | ||
126 | |||
127 | ADC_ADDR = 0; | ||
128 | ADC_ADDR |= 0x40; | ||
129 | |||
130 | #if !(defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)) | ||
131 | ADC_ADDR |= 0x20000000; | ||
132 | udelay(100); | ||
133 | |||
134 | ADC_INIT; | ||
135 | ADC_INIT = 0; | ||
136 | udelay(100); | ||
137 | #endif | ||
138 | |||
139 | ADC_STATUS = 0; | ||
140 | |||
141 | /* Enable channel 0 (battery) */ | ||
142 | DEV_INIT1 &=~0x3; | ||
143 | ADC_ADDR |= 0x1000000; | ||
144 | ADC_STATUS |= 0x20; | ||
145 | |||
146 | /* Enable channel 1 (unknown) */ | ||
147 | DEV_INIT1 &=~30; | ||
148 | ADC_ADDR |= 0x2000000; | ||
149 | ADC_STATUS |= 0x2000; | ||
150 | |||
151 | #if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || \ | ||
152 | defined(MROBE_100) | ||
153 | /* Enable channel 2 (H10:remote) */ | ||
154 | DEV_INIT1 &=~0x300; | ||
155 | DEV_INIT1 |= 0x100; | ||
156 | ADC_ADDR |= 0x4000000; | ||
157 | ADC_STATUS |= 0x200000; | ||
158 | |||
159 | /* Enable channel 3 (H10:scroll pad) */ | ||
160 | DEV_INIT1 &=~0x3000; | ||
161 | DEV_INIT1 |= 0x1000; | ||
162 | ADC_ADDR |= 0x8000000; | ||
163 | ADC_STATUS |= 0x20000000; | ||
164 | #endif | ||
165 | |||
166 | #if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) | ||
167 | ADC_INIT |= 0x80000000; | ||
168 | udelay(100); | ||
169 | ADC_INIT = 0; | ||
170 | #endif | ||
171 | |||
172 | /* Force a scan of all channels to get initial values */ | ||
173 | adc_scan(0); | ||
174 | adc_scan(1); | ||
175 | adc_scan(2); | ||
176 | adc_scan(3); | ||
177 | |||
178 | tick_add_task(adc_tick); | ||
179 | } | ||