Tweaking iPod Video battery configuration. Dangerous battery level is latest reached...
[kugel-rb.git] / firmware / target / arm / s3c2440 / adc-s3c2440.c
blobf42a3d2b6a14308b5af968585ecf53c0c7d7b2f1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 by Wade Brown
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "cpu.h"
22 #include "system.h"
23 #include "adc.h"
24 #include "adc-target.h"
25 #include "kernel.h"
27 #ifdef MINI2440
28 #include "touchscreen-target.h"
29 #endif
31 static unsigned short adc_readings[NUM_ADC_CHANNELS];
33 /* prototypes */
34 static unsigned short __adc_read(int channel);
35 static void adc_tick(void);
37 void adc_init(void)
39 int i;
41 /* Turn on the ADC PCLK */
42 s3c_regset32(&CLKCON, 1<<15);
44 /* Set channel 0, normal mode, disable "start by read" */
45 ADCCON &= ~(0x3F);
47 /* No start delay. Use normal conversion mode. */
48 ADCDLY = 0x1;
50 /* Set and enable the prescaler */
51 ADCCON = (ADCCON & ~(0xff<<6)) | (0x19<<6);
52 ADCCON |= (1<<14);
54 /* prefill the adc channels */
55 for (i = 0; i < NUM_ADC_CHANNELS; i++)
57 adc_readings[i] = __adc_read(i);
60 /* start at zero so when the tick starts it is at zero */
61 adc_readings[0] = __adc_read(0);
63 /* attach the adc reading to the tick */
64 tick_add_task(adc_tick);
67 /* Called to get the recent ADC reading */
68 inline unsigned short adc_read(int channel)
70 return adc_readings[channel];
73 /**
74 * Read the ADC by polling
75 * @param channel The ADC channel to read
76 * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout
78 static unsigned short __adc_read(int channel)
80 int i;
82 /* Set the channel */
83 ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3);
85 /* Start the conversion process */
86 ADCCON |= 0x1;
88 /* Wait for a low Enable_start */
89 for (i = 20000;;)
91 if(0 == (ADCCON & 0x1))
93 break;
95 else
97 i--;
98 if (0 == i)
100 /* Ran out of time */
101 return ADC_READ_ERROR;
106 /* Wait for high End_of_Conversion */
107 for(i = 20000;;)
109 if(ADCCON & (1<<15))
111 break;
113 else
115 i--;
116 if(0 == i)
118 /* Ran out of time */
119 return ADC_READ_ERROR;
123 return (ADCDAT0 & 0x3ff);
126 /* add this to the tick so that the ADC converts are done in the background */
127 static void adc_tick(void)
129 static unsigned channel=0;
131 /* Check if the End Of Conversion is set */
132 if (ADCCON & (1<<15))
134 adc_readings[channel] = (ADCDAT0 & 0x3FF);
135 if (++channel >= NUM_ADC_CHANNELS)
137 channel = 0;
139 #ifdef MINI2440
140 /* interleave a touchscreen read if neccessary */
141 touchscreen_scan_device();
142 #endif
143 /* setup the next conversion and start it*/
144 ADCCON = (ADCCON & ~(0x7<<3)) | (channel<<3) | 0x01;