summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/adc-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/adc-imx31.c103
1 files changed, 81 insertions, 22 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c b/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c
index 1fd2247ef1..b1b79a7989 100644
--- a/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2006 by Wade Brown 10 * Copyright (C) 2008 by Michael Sevakis
11 * 11 *
12 * All files in this archive are subject to the GNU General Public License. 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. 13 * See the file COPYING in the source tree root for full license agreement.
@@ -16,37 +16,96 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#include "cpu.h" 19#include "config.h"
20#include "system.h"
21#include "mc13783.h"
20#include "adc-target.h" 22#include "adc-target.h"
21#include "kernel.h" 23#include "kernel.h"
22 24
23/* prototypes */ 25/* Do this so we may read all channels in a single SPI message */
24static unsigned short __adc_read(int channel); 26static const unsigned char reg_array[NUM_ADC_CHANNELS/2] =
25static void adc_tick(void);
26
27void adc_init(void)
28{ 27{
29} 28 MC13783_ADC2,
29 MC13783_ADC2,
30 MC13783_ADC2,
31 MC13783_ADC2,
32 MC13783_ADC2,
33 MC13783_ADC2,
34 MC13783_ADC2,
35 MC13783_ADC2,
36};
30 37
31/* Called to get the recent ADC reading */ 38static uint32_t channels[2][NUM_ADC_CHANNELS/2];
32inline unsigned short adc_read(int channel) 39static struct wakeup adc_wake;
40static struct mutex adc_mtx;
41static long last_adc_read[2]; /* One for each input group */
42
43/* Read 10-bit ADC channel */
44unsigned short adc_read(int channel)
33{ 45{
34 (void)channel; 46 uint32_t data;
35 return 0; 47 int input_select;
48
49 if ((unsigned)channel >= NUM_ADC_CHANNELS)
50 return ADC_READ_ERROR;
51
52 mutex_lock(&adc_mtx);
53
54 input_select = channel >> 3;
55
56 /* Limit the traffic through here */
57 if (TIME_AFTER(current_tick, last_adc_read[input_select]))
58 {
59 /* Keep enable, start conversion, increment from channel 0,
60 * increment from channel 4 */
61 uint32_t adc1 = MC13783_ADEN | MC13783_ASC | MC13783_ADA1w(0) |
62 MC13783_ADA2w(4);
63
64 if (input_select == 1)
65 adc1 |= MC13783_ADSEL; /* 2nd set of inputs */
66
67 /* Start conversion */
68 mc13783_write(MC13783_ADC1, adc1);
69
70 /* Wait for done signal */
71 wakeup_wait(&adc_wake, TIMEOUT_BLOCK);
72
73 /* Read all 8 channels that are converted - two channels in each
74 * word. */
75 mc13783_read_regset(reg_array, channels[input_select],
76 NUM_ADC_CHANNELS/2);
77
78 last_adc_read[input_select] = current_tick;
79 }
80
81 data = channels[input_select][channel & 7];
82
83 mutex_unlock(&adc_mtx);
84
85 /* Extract the bitfield depending on even or odd channel number */
86 return (channel & 1) ? MC13783_ADD2r(data) : MC13783_ADD1r(data);
36} 87}
37 88
38/** 89/* Called when conversion is complete */
39 * Read the ADC by polling 90void adc_done(void)
40 * @param channel The ADC channel to read
41 * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout
42 */
43static unsigned short __adc_read(int channel)
44{ 91{
45 (void)channel; 92 wakeup_signal(&adc_wake);
46 return 0;
47} 93}
48 94
49/* add this to the tick so that the ADC converts are done in the background */ 95void adc_init(void)
50static void adc_tick(void)
51{ 96{
97 wakeup_init(&adc_wake);
98 mutex_init(&adc_mtx);
99
100 /* Init so first reads get data */
101 last_adc_read[0] = last_adc_read[1] = current_tick-1;
102
103 /* Enable increment-by-read, thermistor */
104 mc13783_write(MC13783_ADC0, MC13783_ADINC2 | MC13783_ADINC1 |
105 MC13783_RTHEN);
106 /* Enable ADC, set multi-channel mode */
107 mc13783_write(MC13783_ADC1, MC13783_ADEN);
108 /* Enable the ADCDONE interrupt - notifications are dispatched by
109 * event handler. */
110 mc13783_clear(MC13783_INTERRUPT_MASK0, MC13783_ADCDONE);
52} 111}