summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/codec-jz4740.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/codec-jz4740.c280
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
25static unsigned short codec_volume;
26static unsigned short codec_base_gain;
27static unsigned short codec_mic_gain;
28static bool HP_on_off_flag;
29static int HP_register_value;
30static int IS_WRITE_PCM;
31
32static 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
39static 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
61static 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
73static 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
93static 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
113static 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
130static 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
139static 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
158static 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
202static 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
237static 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
264void 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
272void audiohw_preinit(void)
273{
274 i2s_reset();
275}
276
277void audiohw_postinit(void)
278{
279 audiohw_mute(false);
280}