summaryrefslogtreecommitdiff
path: root/firmware/target/arm/olympus/mrobe-100/adc-mr100.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/olympus/mrobe-100/adc-mr100.c')
-rw-r--r--firmware/target/arm/olympus/mrobe-100/adc-mr100.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/firmware/target/arm/olympus/mrobe-100/adc-mr100.c b/firmware/target/arm/olympus/mrobe-100/adc-mr100.c
new file mode 100644
index 0000000000..f63e8b8013
--- /dev/null
+++ b/firmware/target/arm/olympus/mrobe-100/adc-mr100.c
@@ -0,0 +1,141 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Barry Wardell
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "config.h"
20#include "cpu.h"
21#include "system.h"
22#include "kernel.h"
23#include "thread.h"
24#include "adc.h"
25
26static unsigned short adcdata[NUM_ADC_CHANNELS];
27
28/* Scan ADC so that adcdata[channel] gets updated. */
29unsigned short adc_scan(int channel)
30{
31 unsigned int adc_data_1;
32 unsigned int adc_data_2;
33
34 /* Start conversion */
35 ADC_ADDR |= 0x80000000;
36
37 /* Wait for conversion to complete */
38 while((ADC_STATUS & (0x40<<8*channel))==0);
39
40 /* Stop conversion */
41 ADC_ADDR &=~ 0x80000000;
42
43 /* ADC_DATA_1 and ADC_DATA_2 are both four bytes, one byte per channel.
44 For each channel, ADC_DATA_1 stores the 8-bit msb, ADC_DATA_2 stores the
45 2-bit lsb (in bits 0 and 1). Each channel is 10 bits total. */
46 adc_data_1 = ((ADC_DATA_1 >> (8*channel)) & 0xff);
47 adc_data_2 = ((ADC_DATA_2 >> (8*channel+6)) & 0x3);
48
49 adcdata[channel] = (adc_data_1<<2 | adc_data_2);
50
51 /* ADC values read low if PLL is enabled */
52 if(PLL_CONTROL & 0x80000000){
53 adcdata[channel] += 0x14;
54 if(adcdata[channel] > 0x400)
55 adcdata[channel] = 0x400;
56 }
57
58 return adcdata[channel];
59}
60
61/* Read 10-bit channel data */
62unsigned short adc_read(int channel)
63{
64 return adcdata[channel];
65}
66
67static int adc_counter;
68
69static void adc_tick(void)
70{
71 if(++adc_counter == HZ)
72 {
73 adc_counter = 0;
74 adc_scan(ADC_BATTERY);
75 adc_scan(ADC_UNKNOWN_1);
76 adc_scan(ADC_REMOTE);
77 adc_scan(ADC_SCROLLPAD);
78 }
79}
80
81/* Figured out from how the OF does things */
82void adc_init(void)
83{
84 ADC_INIT |= 1;
85 ADC_INIT |= 0x40000000;
86 udelay(100);
87
88 /* Reset ADC */
89 DEV_RS2 |= 0x20;
90 udelay(100);
91
92 DEV_RS2 &=~ 0x20;
93 udelay(100);
94
95 /* Enable ADC */
96 DEV_EN2 |= 0x20;
97 udelay(100);
98
99 ADC_CLOCK_SRC |= 0x3;
100 udelay(100);
101
102 ADC_ADDR |= 0x40;
103 ADC_ADDR |= 0x20000000;
104 udelay(100);
105
106 ADC_INIT;
107 ADC_INIT = 0;
108 udelay(100);
109
110 ADC_STATUS = 0;
111
112 /* Enable channel 0 (battery) */
113 DEV_INIT1 &=~0x3;
114 ADC_ADDR |= 0x1000000;
115 ADC_STATUS |= 0x20;
116
117 /* Enable channel 1 (unknown, temperature?) */
118 DEV_INIT1 &=~30;
119 ADC_ADDR |= 0x2000000;
120 ADC_STATUS |= 0x2000;
121
122 /* Enable channel 2 (remote) */
123 DEV_INIT1 &=~0x300;
124 DEV_INIT1 |= 0x100;
125 ADC_ADDR |= 0x4000000;
126 ADC_STATUS |= 0x200000;
127
128 /* Enable channel 3 (scroll pad) */
129 DEV_INIT1 &=~0x3000;
130 DEV_INIT1 |= 0x1000;
131 ADC_ADDR |= 0x8000000;
132 ADC_STATUS |= 0x20000000;
133
134 /* Force a scan of all channels to get initial values */
135 adc_scan(ADC_BATTERY);
136 adc_scan(ADC_UNKNOWN_1);
137 adc_scan(ADC_REMOTE);
138 adc_scan(ADC_SCROLLPAD);
139
140 tick_add_task(adc_tick);
141}