diff options
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/codec-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/codec-jz4740.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c new file mode 100644 index 0000000000..6c3ed8cf2a --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Maurus Cuelenaere | ||
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 | |||
22 | #include "config.h" | ||
23 | #include "jz4740.h" | ||
24 | |||
25 | static unsigned short codec_volume; | ||
26 | static unsigned short codec_base_gain; | ||
27 | static unsigned short codec_mic_gain; | ||
28 | static bool HP_on_off_flag; | ||
29 | static int HP_register_value; | ||
30 | static int IS_WRITE_PCM; | ||
31 | |||
32 | static void i2s_codec_clear(void) | ||
33 | { | ||
34 | REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | | ||
35 | ICDC_CDCCR1_VRCGH | ICDC_CDCCR1_HPOV0 | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP | | ||
36 | ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); | ||
37 | } | ||
38 | |||
39 | static void i2s_codec_init(void) | ||
40 | { | ||
41 | __aic_select_i2s(); | ||
42 | __i2s_internal_codec(); | ||
43 | |||
44 | __aic_enable(); | ||
45 | |||
46 | __i2s_set_oss_sample_size(16); | ||
47 | |||
48 | REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | | ||
49 | ICDC_CDCCR1_VRCGH | ICDC_CDCCR1_HPOV0 | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP | | ||
50 | ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); /* reset */ | ||
51 | udelay(10); | ||
52 | REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL | | ||
53 | ICDC_CDCCR1_VRCGH | ICDC_CDCCR1_HPOV0 | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP | | ||
54 | ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); | ||
55 | //REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | | ||
56 | REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | | ||
57 | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_6)); | ||
58 | HP_on_off_flag = 0; /* HP is off */ | ||
59 | } | ||
60 | |||
61 | static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */ | ||
62 | { | ||
63 | v = v & 0xff; | ||
64 | if(v < 0) | ||
65 | v = 0; | ||
66 | if(v > 100) | ||
67 | v = 100; | ||
68 | codec_mic_gain = 31 * v/100; | ||
69 | |||
70 | REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x1f << 16)) | (codec_mic_gain << 16)); | ||
71 | } | ||
72 | |||
73 | static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */ | ||
74 | { | ||
75 | v = v & 0xff; | ||
76 | if(v < 0) | ||
77 | v = 0; | ||
78 | if(v > 100) | ||
79 | v = 100; | ||
80 | |||
81 | if(v < 25) | ||
82 | codec_base_gain = 0; | ||
83 | if(v >= 25 && v < 50) | ||
84 | codec_base_gain = 1; | ||
85 | if(v >= 50 && v < 75) | ||
86 | codec_base_gain = 2; | ||
87 | if(v >= 75 && v <= 100) | ||
88 | codec_base_gain = 3; | ||
89 | |||
90 | REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x3 << 4)) | (codec_base_gain << 4)); | ||
91 | } | ||
92 | |||
93 | static void i2s_codec_set_volume(unsigned short v) /* 0 <= v <= 100 */ | ||
94 | { | ||
95 | v = v & 0xff; | ||
96 | if(v < 0) | ||
97 | v = 0; | ||
98 | if(v > 100) | ||
99 | v = 100; | ||
100 | |||
101 | if(v < 25) | ||
102 | codec_volume = 0; | ||
103 | if(v >= 25 && v < 50) | ||
104 | codec_volume = 1; | ||
105 | if(v >= 50 && v < 75) | ||
106 | codec_volume = 2; | ||
107 | if(v >= 75 && v <= 100) | ||
108 | codec_volume = 3; | ||
109 | |||
110 | REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x3)) | codec_volume); | ||
111 | } | ||
112 | |||
113 | static unsigned short i2s_codec_get_bass(void) | ||
114 | { | ||
115 | unsigned short val; | ||
116 | int ret; | ||
117 | if(codec_base_gain == 0) | ||
118 | val = 0; | ||
119 | if(codec_base_gain == 1) | ||
120 | val = 25; | ||
121 | if(codec_base_gain == 2) | ||
122 | val = 50; | ||
123 | if(codec_base_gain == 3) | ||
124 | val = 75; | ||
125 | |||
126 | ret = val << 8; | ||
127 | val = val | ret; | ||
128 | } | ||
129 | |||
130 | static unsigned short i2s_codec_get_mic(void) | ||
131 | { | ||
132 | unsigned short val; | ||
133 | int ret; | ||
134 | val = 100 * codec_mic_gain / 31; | ||
135 | ret = val << 8; | ||
136 | val = val | ret; | ||
137 | } | ||
138 | |||
139 | static unsigned short i2s_codec_get_volume(void) | ||
140 | { | ||
141 | unsigned short val; | ||
142 | int ret; | ||
143 | |||
144 | if(codec_volume == 0) | ||
145 | val = 0; | ||
146 | if(codec_volume == 1) | ||
147 | val = 25; | ||
148 | if(codec_volume == 2) | ||
149 | val = 50; | ||
150 | if(codec_volume == 3) | ||
151 | val = 75; | ||
152 | |||
153 | ret = val << 8; | ||
154 | val = val | ret; | ||
155 | return val; | ||
156 | } | ||
157 | |||
158 | static void i2s_codec_set_samplerate(unsigned short rate) | ||
159 | { | ||
160 | unsigned short speed = 0; | ||
161 | unsigned short val = 0; | ||
162 | |||
163 | switch (rate) | ||
164 | { | ||
165 | case 8000: | ||
166 | speed = 0; | ||
167 | break; | ||
168 | case 11025: | ||
169 | speed = 1; | ||
170 | break; | ||
171 | case 12000: | ||
172 | speed = 2; | ||
173 | break; | ||
174 | case 16000: | ||
175 | speed = 3; | ||
176 | break; | ||
177 | case 22050: | ||
178 | speed = 4; | ||
179 | break; | ||
180 | case 24000: | ||
181 | speed = 5; | ||
182 | break; | ||
183 | case 32000: | ||
184 | speed = 6; | ||
185 | break; | ||
186 | case 44100: | ||
187 | speed = 7; | ||
188 | break; | ||
189 | case 48000: | ||
190 | speed = 8; | ||
191 | break; | ||
192 | default: | ||
193 | break; | ||
194 | } | ||
195 | REG_ICDC_CDCCR2 |= 0x00000f00; | ||
196 | speed = speed << 8; | ||
197 | |||
198 | speed |= 0xfffff0ff; | ||
199 | REG_ICDC_CDCCR2 &= speed; | ||
200 | } | ||
201 | |||
202 | static void HP_turn_on(void) | ||
203 | { | ||
204 | //see 1.3.4.1 | ||
205 | |||
206 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); //set suspend 0 | ||
207 | |||
208 | mdelay(15); | ||
209 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVR | ICDC_CDCCR1_VRCGL | ICDC_CDCCR1_VRCGH); | ||
210 | REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG); | ||
211 | |||
212 | mdelay(600); | ||
213 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_HPCG | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP); | ||
214 | |||
215 | mdelay(2); | ||
216 | HP_register_value = REG_ICDC_CDCCR1; | ||
217 | |||
218 | //see 1.3.4.2 | ||
219 | /*REG_ICDC_CDCCR1 &= 0xfffffffc; | ||
220 | mdelay(7); | ||
221 | REG_ICDC_CDCCR1 |= 0x00040400; | ||
222 | mdelay(15); | ||
223 | REG_ICDC_CDCCR1 &= 0xfffbfbff; | ||
224 | udelay(500); | ||
225 | REG_ICDC_CDCCR1 &= 0xffe5fcff; | ||
226 | REG_ICDC_CDCCR1 |= 0x01000000; | ||
227 | mdelay(400); | ||
228 | REG_ICDC_CDCCR1 &= 0xfffeffff; | ||
229 | mdelay(7); | ||
230 | HP_register_value = REG_ICDC_CDCCR1;*/ | ||
231 | |||
232 | //see 1.3.4.3 | ||
233 | |||
234 | } | ||
235 | |||
236 | |||
237 | static void HP_turn_off(void) | ||
238 | { | ||
239 | //see 1.3.4.1 | ||
240 | mdelay(2); | ||
241 | REG_ICDC_CDCCR1 = HP_register_value; | ||
242 | REG_ICDC_CDCCR1 |= 0x001b0300; | ||
243 | REG_ICDC_CDCCR1 &= 0xfeffffff; | ||
244 | |||
245 | mdelay(15); | ||
246 | REG_ICDC_CDCCR1 |= 0x00000002;//set suspend 1 | ||
247 | |||
248 | //see 1.3.4.2 | ||
249 | /*mdelay(4); | ||
250 | REG_ICDC_CDCCR1 = HP_register_value; | ||
251 | REG_ICDC_CDCCR1 |= 0x001b0300; | ||
252 | REG_ICDC_CDCCR1 &= 0xfeffffff; | ||
253 | mdelay(4); | ||
254 | REG_ICDC_CDCCR1 |= 0x00000400; | ||
255 | mdelay(15); | ||
256 | REG_ICDC_CDCCR1 &= 0xfffffdff; | ||
257 | mdelay(7); | ||
258 | REG_ICDC_CDCCR1 |= 0x00000002;*/ | ||
259 | |||
260 | //see 1.3.4.3 | ||
261 | |||
262 | } | ||
263 | |||
264 | void audiohw_mute(bool mute) | ||
265 | { | ||
266 | if(mute) | ||
267 | REG_ICDC_CDCCR1 |= ICDC_CDCCR1_HPMUTE; | ||
268 | else | ||
269 | REG_ICDC_CDCCR1 &= ~ICDC_CDCCR1_HPMUTE; | ||
270 | } | ||
271 | |||
272 | void audiohw_preinit(void) | ||
273 | { | ||
274 | i2s_reset(); | ||
275 | } | ||
276 | |||
277 | void audiohw_postinit(void) | ||
278 | { | ||
279 | audiohw_mute(false); | ||
280 | } | ||