diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2010-04-09 01:21:53 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2010-04-09 01:21:53 +0000 |
commit | 7abf2b53a462612808d46d6d77a7f35261a0e5a3 (patch) | |
tree | 241304f7cd2b5d1c2a9e091fe56a33d2d2f8e816 /firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c | |
parent | 43304b87b0662d1619ac60e5297a1694aa580310 (diff) | |
download | rockbox-7abf2b53a462612808d46d6d77a7f35261a0e5a3.tar.gz rockbox-7abf2b53a462612808d46d6d77a7f35261a0e5a3.zip |
Gigabeat S/i.MX31: Sort files in the /target tree into things that are SoC-generic (into /imx31) and player-specific (into /gigabeat-s, based upon current appearances). Move i2s clock init into the appropriate file. Housekeeping only-- no functional changes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25547 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c new file mode 100644 index 0000000000..52293228f8 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Michael Sevakis | ||
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 "system.h" | ||
23 | #include "mc13783.h" | ||
24 | #include "adc.h" | ||
25 | #include "adc-target.h" | ||
26 | #include "kernel.h" | ||
27 | |||
28 | /* Do this so we may read all channels in a single SPI message */ | ||
29 | static const unsigned char reg_array[4] = | ||
30 | { | ||
31 | MC13783_ADC2, | ||
32 | MC13783_ADC2, | ||
33 | MC13783_ADC2, | ||
34 | MC13783_ADC2, | ||
35 | }; | ||
36 | |||
37 | static uint32_t channels[2][4]; | ||
38 | static struct wakeup adc_wake; | ||
39 | static struct mutex adc_mtx; | ||
40 | static long last_adc_read[2]; /* One for each input group */ | ||
41 | |||
42 | /* Read 10-bit ADC channel */ | ||
43 | unsigned short adc_read(int channel) | ||
44 | { | ||
45 | uint32_t data; | ||
46 | int input_select; | ||
47 | |||
48 | if ((unsigned)channel >= NUM_ADC_CHANNELS) | ||
49 | return ADC_READ_ERROR; | ||
50 | |||
51 | input_select = channel >> 3; | ||
52 | |||
53 | mutex_lock(&adc_mtx); | ||
54 | |||
55 | /* Limit the traffic through here */ | ||
56 | if (current_tick != last_adc_read[input_select]) | ||
57 | { | ||
58 | /* Keep enable, start conversion, increment from channel 0, | ||
59 | * increment from channel 4 */ | ||
60 | uint32_t adc1 = MC13783_ADEN | MC13783_ASC | | ||
61 | (0 << MC13783_ADA1_POS) | (4 << MC13783_ADA2_POS); | ||
62 | |||
63 | if (input_select == 1) | ||
64 | adc1 |= MC13783_ADSEL; /* 2nd set of inputs */ | ||
65 | |||
66 | /* Start conversion */ | ||
67 | mc13783_write(MC13783_ADC1, adc1); | ||
68 | |||
69 | /* Wait for done signal */ | ||
70 | wakeup_wait(&adc_wake, TIMEOUT_BLOCK); | ||
71 | |||
72 | /* Read all 8 channels that are converted - two channels in each | ||
73 | * word. */ | ||
74 | mc13783_read_regset(reg_array, channels[input_select], 4); | ||
75 | |||
76 | last_adc_read[input_select] = current_tick; | ||
77 | } | ||
78 | |||
79 | data = channels[input_select][channel & 3]; | ||
80 | |||
81 | mutex_unlock(&adc_mtx); | ||
82 | |||
83 | /* Channels 0-3/8-11 in ADD1, 4-7/12-15 in ADD2 */ | ||
84 | return (channel & 4) ? | ||
85 | ((data & MC13783_ADD2) >> MC13783_ADD2_POS) : | ||
86 | ((data & MC13783_ADD1) >> MC13783_ADD1_POS); | ||
87 | } | ||
88 | |||
89 | bool adc_enable_channel(int channel, bool enable) | ||
90 | { | ||
91 | uint32_t bit, mask; | ||
92 | |||
93 | switch (channel) | ||
94 | { | ||
95 | case ADC_CHARGER_CURRENT: | ||
96 | mask = MC13783_CHRGICON; | ||
97 | break; | ||
98 | |||
99 | case ADC_BATTERY_TEMP: | ||
100 | mask = MC13783_RTHEN; | ||
101 | break; | ||
102 | |||
103 | default: | ||
104 | return false; | ||
105 | } | ||
106 | |||
107 | bit = enable ? mask : 0; | ||
108 | |||
109 | return mc13783_write_masked(MC13783_ADC0, bit, mask) | ||
110 | != MC13783_DATA_ERROR; | ||
111 | } | ||
112 | |||
113 | /* Called by mc13783 interrupt thread when conversion is complete */ | ||
114 | void adc_done(void) | ||
115 | { | ||
116 | wakeup_signal(&adc_wake); | ||
117 | } | ||
118 | |||
119 | void adc_init(void) | ||
120 | { | ||
121 | wakeup_init(&adc_wake); | ||
122 | mutex_init(&adc_mtx); | ||
123 | |||
124 | /* Init so first reads get data */ | ||
125 | last_adc_read[0] = last_adc_read[1] = current_tick-1; | ||
126 | |||
127 | /* Enable increment-by-read, turn off extra conversions. */ | ||
128 | mc13783_write(MC13783_ADC0, MC13783_ADINC2 | MC13783_ADINC1); | ||
129 | |||
130 | /* Enable ADC, set multi-channel mode */ | ||
131 | mc13783_write(MC13783_ADC1, MC13783_ADEN); | ||
132 | |||
133 | /* Enable ADCDONE event */ | ||
134 | mc13783_write(MC13783_INTERRUPT_STATUS0, MC13783_ADCDONEI); | ||
135 | mc13783_enable_event(MC13783_ADCDONE_EVENT); | ||
136 | } | ||