1*8acfcfc3SJia-Ju Bai #include "mixer.h"
2*8acfcfc3SJia-Ju Bai
3*8acfcfc3SJia-Ju Bai #ifdef MIXER_AK4531
4*8acfcfc3SJia-Ju Bai u8_t mixer_value[] = {
5*8acfcfc3SJia-Ju Bai 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
6*8acfcfc3SJia-Ju Bai 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
7*8acfcfc3SJia-Ju Bai 0x7e, 0x3d, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00,
8*8acfcfc3SJia-Ju Bai 0x00, 0x01
9*8acfcfc3SJia-Ju Bai };
get_set_volume(u32_t * base,struct volume_level * level,int flag)10*8acfcfc3SJia-Ju Bai int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
11*8acfcfc3SJia-Ju Bai int max_level, cmd_left, cmd_right;
12*8acfcfc3SJia-Ju Bai
13*8acfcfc3SJia-Ju Bai max_level = 0x1f;
14*8acfcfc3SJia-Ju Bai /* Check device */
15*8acfcfc3SJia-Ju Bai switch (level->device) {
16*8acfcfc3SJia-Ju Bai case Master:
17*8acfcfc3SJia-Ju Bai cmd_left = MASTER_VOLUME_LCH;
18*8acfcfc3SJia-Ju Bai cmd_right = MASTER_VOLUME_RCH;
19*8acfcfc3SJia-Ju Bai break;
20*8acfcfc3SJia-Ju Bai case Dac:
21*8acfcfc3SJia-Ju Bai return EINVAL;
22*8acfcfc3SJia-Ju Bai case Fm:
23*8acfcfc3SJia-Ju Bai cmd_left = FM_VOLUME_LCH;
24*8acfcfc3SJia-Ju Bai cmd_right = FM_VOLUME_RCH;
25*8acfcfc3SJia-Ju Bai break;
26*8acfcfc3SJia-Ju Bai case Cd:
27*8acfcfc3SJia-Ju Bai cmd_left = CD_AUDIO_VOLUME_LCH;
28*8acfcfc3SJia-Ju Bai cmd_right = CD_AUDIO_VOLUME_RCH;
29*8acfcfc3SJia-Ju Bai break;
30*8acfcfc3SJia-Ju Bai case Line:
31*8acfcfc3SJia-Ju Bai cmd_left = LINE_VOLUME_LCH;
32*8acfcfc3SJia-Ju Bai cmd_right = LINE_VOLUME_RCH;
33*8acfcfc3SJia-Ju Bai break;
34*8acfcfc3SJia-Ju Bai case Mic:
35*8acfcfc3SJia-Ju Bai cmd_left = cmd_right = MIC_VOLUME;
36*8acfcfc3SJia-Ju Bai break;
37*8acfcfc3SJia-Ju Bai case Speaker:
38*8acfcfc3SJia-Ju Bai cmd_left = cmd_right = MONO_OUT_VOLUME;
39*8acfcfc3SJia-Ju Bai max_level = 0x03;
40*8acfcfc3SJia-Ju Bai break;
41*8acfcfc3SJia-Ju Bai case Treble:
42*8acfcfc3SJia-Ju Bai return EINVAL;
43*8acfcfc3SJia-Ju Bai case Bass:
44*8acfcfc3SJia-Ju Bai return EINVAL;
45*8acfcfc3SJia-Ju Bai default:
46*8acfcfc3SJia-Ju Bai return EINVAL;
47*8acfcfc3SJia-Ju Bai }
48*8acfcfc3SJia-Ju Bai /* Set volume */
49*8acfcfc3SJia-Ju Bai if (flag) {
50*8acfcfc3SJia-Ju Bai if (level->right < 0)
51*8acfcfc3SJia-Ju Bai level->right = 0;
52*8acfcfc3SJia-Ju Bai else if (level->right > max_level)
53*8acfcfc3SJia-Ju Bai level->right = max_level;
54*8acfcfc3SJia-Ju Bai if (level->left < 0)
55*8acfcfc3SJia-Ju Bai level->left = 0;
56*8acfcfc3SJia-Ju Bai else if (level->left > max_level)
57*8acfcfc3SJia-Ju Bai level->left = max_level;
58*8acfcfc3SJia-Ju Bai /* ### WRITE_MIXER_REG ### */
59*8acfcfc3SJia-Ju Bai dev_mixer_write(base, cmd_left, 0x1f - level->left);
60*8acfcfc3SJia-Ju Bai /* ### WRITE_MIXER_REG ### */
61*8acfcfc3SJia-Ju Bai dev_mixer_write(base, cmd_right, 0x1f - level->right);
62*8acfcfc3SJia-Ju Bai mixer_value[cmd_left] = 0x1f - level->left;
63*8acfcfc3SJia-Ju Bai mixer_value[cmd_right] = 0x1f - level->right;
64*8acfcfc3SJia-Ju Bai }
65*8acfcfc3SJia-Ju Bai /* Get volume (mixer register can not be read in ak4531 codec) */
66*8acfcfc3SJia-Ju Bai else {
67*8acfcfc3SJia-Ju Bai /* ### READ_MIXER_REG ### */
68*8acfcfc3SJia-Ju Bai dev_mixer_read(base, cmd_left);
69*8acfcfc3SJia-Ju Bai /* ### READ_MIXER_REG ### */
70*8acfcfc3SJia-Ju Bai dev_mixer_read(base, cmd_right);
71*8acfcfc3SJia-Ju Bai level->left = 0x1f - mixer_value[cmd_left];
72*8acfcfc3SJia-Ju Bai level->right = 0x1f - mixer_value[cmd_right];
73*8acfcfc3SJia-Ju Bai }
74*8acfcfc3SJia-Ju Bai return OK;
75*8acfcfc3SJia-Ju Bai }
76*8acfcfc3SJia-Ju Bai #endif
77*8acfcfc3SJia-Ju Bai
78*8acfcfc3SJia-Ju Bai #ifdef MIXER_SB16
get_set_volume(u32_t * base,struct volume_level * level,int flag)79*8acfcfc3SJia-Ju Bai int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
80*8acfcfc3SJia-Ju Bai int max_level, shift, cmd_left, cmd_right;
81*8acfcfc3SJia-Ju Bai
82*8acfcfc3SJia-Ju Bai max_level = 0x0f;
83*8acfcfc3SJia-Ju Bai shift = 4;
84*8acfcfc3SJia-Ju Bai /* Check device */
85*8acfcfc3SJia-Ju Bai switch (level->device) {
86*8acfcfc3SJia-Ju Bai case Master:
87*8acfcfc3SJia-Ju Bai cmd_left = SB16_MASTER_LEFT;
88*8acfcfc3SJia-Ju Bai cmd_right = SB16_MASTER_RIGHT;
89*8acfcfc3SJia-Ju Bai break;
90*8acfcfc3SJia-Ju Bai case Dac:
91*8acfcfc3SJia-Ju Bai cmd_left = SB16_DAC_LEFT;
92*8acfcfc3SJia-Ju Bai cmd_right = SB16_DAC_RIGHT;
93*8acfcfc3SJia-Ju Bai break;
94*8acfcfc3SJia-Ju Bai case Fm:
95*8acfcfc3SJia-Ju Bai cmd_left = SB16_FM_LEFT;
96*8acfcfc3SJia-Ju Bai cmd_right = SB16_FM_RIGHT;
97*8acfcfc3SJia-Ju Bai break;
98*8acfcfc3SJia-Ju Bai case Cd:
99*8acfcfc3SJia-Ju Bai cmd_left = SB16_CD_LEFT;
100*8acfcfc3SJia-Ju Bai cmd_right = SB16_CD_RIGHT;
101*8acfcfc3SJia-Ju Bai break;
102*8acfcfc3SJia-Ju Bai case Line:
103*8acfcfc3SJia-Ju Bai cmd_left = SB16_LINE_LEFT;
104*8acfcfc3SJia-Ju Bai cmd_left = SB16_LINE_RIGHT;
105*8acfcfc3SJia-Ju Bai break;
106*8acfcfc3SJia-Ju Bai case Mic:
107*8acfcfc3SJia-Ju Bai cmd_left = cmd_right = SB16_MIC_LEVEL;
108*8acfcfc3SJia-Ju Bai break;
109*8acfcfc3SJia-Ju Bai case Speaker:
110*8acfcfc3SJia-Ju Bai cmd_left = cmd_right = SB16_PC_LEVEL;
111*8acfcfc3SJia-Ju Bai shift = 6;
112*8acfcfc3SJia-Ju Bai max_level = 0x03;
113*8acfcfc3SJia-Ju Bai break;
114*8acfcfc3SJia-Ju Bai case Treble:
115*8acfcfc3SJia-Ju Bai cmd_left = SB16_TREBLE_LEFT;
116*8acfcfc3SJia-Ju Bai cmd_right = SB16_TREBLE_RIGHT;
117*8acfcfc3SJia-Ju Bai shift = 4;
118*8acfcfc3SJia-Ju Bai max_level = 0x0f;
119*8acfcfc3SJia-Ju Bai break;
120*8acfcfc3SJia-Ju Bai case Bass:
121*8acfcfc3SJia-Ju Bai cmd_left = SB16_BASS_LEFT;
122*8acfcfc3SJia-Ju Bai cmd_right = SB16_BASS_RIGHT;
123*8acfcfc3SJia-Ju Bai shift = 4;
124*8acfcfc3SJia-Ju Bai max_level = 0x0f;
125*8acfcfc3SJia-Ju Bai break;
126*8acfcfc3SJia-Ju Bai default:
127*8acfcfc3SJia-Ju Bai return EINVAL;
128*8acfcfc3SJia-Ju Bai }
129*8acfcfc3SJia-Ju Bai /* Set volume */
130*8acfcfc3SJia-Ju Bai if (flag) {
131*8acfcfc3SJia-Ju Bai if (level->right < 0)
132*8acfcfc3SJia-Ju Bai level->right = 0;
133*8acfcfc3SJia-Ju Bai else if (level->right > max_level)
134*8acfcfc3SJia-Ju Bai level->right = max_level;
135*8acfcfc3SJia-Ju Bai if (level->left < 0)
136*8acfcfc3SJia-Ju Bai level->left = 0;
137*8acfcfc3SJia-Ju Bai else if (level->left > max_level)
138*8acfcfc3SJia-Ju Bai level->left = max_level;
139*8acfcfc3SJia-Ju Bai /* ### WRITE_MIXER_REG ### */
140*8acfcfc3SJia-Ju Bai dev_mixer_write(base, cmd_left, level->left << shift);
141*8acfcfc3SJia-Ju Bai /* ### WRITE_MIXER_REG ### */
142*8acfcfc3SJia-Ju Bai dev_mixer_write(base, cmd_right, level->right << shift);
143*8acfcfc3SJia-Ju Bai }
144*8acfcfc3SJia-Ju Bai /* Get volume */
145*8acfcfc3SJia-Ju Bai else {
146*8acfcfc3SJia-Ju Bai /* ### READ_MIXER_REG ### */
147*8acfcfc3SJia-Ju Bai level->left = dev_mixer_read(base, cmd_left);
148*8acfcfc3SJia-Ju Bai /* ### READ_MIXER_REG ### */
149*8acfcfc3SJia-Ju Bai level->right = dev_mixer_read(base, cmd_right);
150*8acfcfc3SJia-Ju Bai level->left >>= shift;
151*8acfcfc3SJia-Ju Bai level->right >>= shift;
152*8acfcfc3SJia-Ju Bai }
153*8acfcfc3SJia-Ju Bai return OK;
154*8acfcfc3SJia-Ju Bai }
155*8acfcfc3SJia-Ju Bai #endif
156*8acfcfc3SJia-Ju Bai
157*8acfcfc3SJia-Ju Bai #ifdef MIXER_AC97
get_set_volume(u32_t * base,struct volume_level * level,int flag)158*8acfcfc3SJia-Ju Bai int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
159*8acfcfc3SJia-Ju Bai int max_level, cmd, data;
160*8acfcfc3SJia-Ju Bai
161*8acfcfc3SJia-Ju Bai max_level = 0x1f;
162*8acfcfc3SJia-Ju Bai /* Check device */
163*8acfcfc3SJia-Ju Bai switch (level->device) {
164*8acfcfc3SJia-Ju Bai case Master:
165*8acfcfc3SJia-Ju Bai cmd = AC97_MASTER_VOLUME;
166*8acfcfc3SJia-Ju Bai break;
167*8acfcfc3SJia-Ju Bai case Dac:
168*8acfcfc3SJia-Ju Bai return EINVAL;
169*8acfcfc3SJia-Ju Bai case Fm:
170*8acfcfc3SJia-Ju Bai cmd = AC97_PCM_OUT_VOLUME;
171*8acfcfc3SJia-Ju Bai break;
172*8acfcfc3SJia-Ju Bai case Cd:
173*8acfcfc3SJia-Ju Bai cmd = AC97_CD_VOLUME;
174*8acfcfc3SJia-Ju Bai break;
175*8acfcfc3SJia-Ju Bai case Line:
176*8acfcfc3SJia-Ju Bai cmd = AC97_LINE_IN_VOLUME;
177*8acfcfc3SJia-Ju Bai break;
178*8acfcfc3SJia-Ju Bai case Mic:
179*8acfcfc3SJia-Ju Bai cmd = AC97_MIC_VOLUME;
180*8acfcfc3SJia-Ju Bai break;
181*8acfcfc3SJia-Ju Bai case Speaker:
182*8acfcfc3SJia-Ju Bai return EINVAL;
183*8acfcfc3SJia-Ju Bai case Treble:
184*8acfcfc3SJia-Ju Bai return EINVAL;
185*8acfcfc3SJia-Ju Bai case Bass:
186*8acfcfc3SJia-Ju Bai return EINVAL;
187*8acfcfc3SJia-Ju Bai default:
188*8acfcfc3SJia-Ju Bai return EINVAL;
189*8acfcfc3SJia-Ju Bai }
190*8acfcfc3SJia-Ju Bai /* Set volume */
191*8acfcfc3SJia-Ju Bai if (flag) {
192*8acfcfc3SJia-Ju Bai if (level->right < 0)
193*8acfcfc3SJia-Ju Bai level->right = 0;
194*8acfcfc3SJia-Ju Bai else if (level->right > max_level)
195*8acfcfc3SJia-Ju Bai level->right = max_level;
196*8acfcfc3SJia-Ju Bai if (level->left < 0)
197*8acfcfc3SJia-Ju Bai level->left = 0;
198*8acfcfc3SJia-Ju Bai else if (level->left > max_level)
199*8acfcfc3SJia-Ju Bai level->left = max_level;
200*8acfcfc3SJia-Ju Bai data = (max_level - level->left) << 8 | (max_level - level->right);
201*8acfcfc3SJia-Ju Bai /* ### WRITE_MIXER_REG ### */
202*8acfcfc3SJia-Ju Bai dev_mixer_write(base, cmd, data);
203*8acfcfc3SJia-Ju Bai }
204*8acfcfc3SJia-Ju Bai /* Get volume */
205*8acfcfc3SJia-Ju Bai else {
206*8acfcfc3SJia-Ju Bai /* ### READ_MIXER_REG ### */
207*8acfcfc3SJia-Ju Bai data = dev_mixer_read(base, cmd);
208*8acfcfc3SJia-Ju Bai level->left = (u16_t)(data >> 8);
209*8acfcfc3SJia-Ju Bai level->right = (u16_t)(data & 0xff);
210*8acfcfc3SJia-Ju Bai if (level->right < 0)
211*8acfcfc3SJia-Ju Bai level->right = 0;
212*8acfcfc3SJia-Ju Bai else if (level->right > max_level)
213*8acfcfc3SJia-Ju Bai level->right = max_level;
214*8acfcfc3SJia-Ju Bai if (level->left < 0)
215*8acfcfc3SJia-Ju Bai level->left = 0;
216*8acfcfc3SJia-Ju Bai else if (level->left > max_level)
217*8acfcfc3SJia-Ju Bai level->left = max_level;
218*8acfcfc3SJia-Ju Bai level->left = max_level - level->left;
219*8acfcfc3SJia-Ju Bai level->right = max_level - level->right;
220*8acfcfc3SJia-Ju Bai }
221*8acfcfc3SJia-Ju Bai return OK;
222*8acfcfc3SJia-Ju Bai }
223*8acfcfc3SJia-Ju Bai #endif
224*8acfcfc3SJia-Ju Bai
225*8acfcfc3SJia-Ju Bai /* Set default mixer volume */
dev_set_default_volume(u32_t * base)226*8acfcfc3SJia-Ju Bai void dev_set_default_volume(u32_t *base) {
227*8acfcfc3SJia-Ju Bai int i;
228*8acfcfc3SJia-Ju Bai #ifdef MIXER_AK4531
229*8acfcfc3SJia-Ju Bai for (i = 0; i <= 0x19; i++)
230*8acfcfc3SJia-Ju Bai dev_mixer_write(base, i, mixer_value[i]);
231*8acfcfc3SJia-Ju Bai #endif
232*8acfcfc3SJia-Ju Bai #ifdef MIXER_SB16
233*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_MASTER_LEFT, 0x18 << 3);
234*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_MASTER_RIGHT, 0x18 << 3);
235*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_DAC_LEFT, 0x0f << 4);
236*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_DAC_RIGHT, 0x0f << 4);
237*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_FM_LEFT, 0x08 << 4);
238*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_FM_RIGHT, 0x08 << 4);
239*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_CD_LEFT, 0x08 << 4);
240*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_CD_RIGHT, 0x08 << 4);
241*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_LINE_LEFT, 0x08 << 4);
242*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_LINE_RIGHT, 0x08 << 4);
243*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_MIC_LEVEL, 0x0f << 4);
244*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_PC_LEVEL, 0x02 << 6);
245*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_TREBLE_LEFT, 0x08 << 4);
246*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_TREBLE_RIGHT, 0x08 << 4);
247*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_BASS_LEFT, 0x08 << 4);
248*8acfcfc3SJia-Ju Bai dev_mixer_write(base, SB16_BASS_RIGHT, 0x08 << 4);
249*8acfcfc3SJia-Ju Bai #endif
250*8acfcfc3SJia-Ju Bai
251*8acfcfc3SJia-Ju Bai #ifdef MIXER_AC97
252*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_POWERDOWN, 0x0000);
253*8acfcfc3SJia-Ju Bai for (i = 0; i < 50000; i++) {
254*8acfcfc3SJia-Ju Bai if (dev_mixer_read(base, AC97_POWERDOWN) & 0x03)
255*8acfcfc3SJia-Ju Bai break;
256*8acfcfc3SJia-Ju Bai micro_delay(100);
257*8acfcfc3SJia-Ju Bai }
258*8acfcfc3SJia-Ju Bai if (i == 50000)
259*8acfcfc3SJia-Ju Bai printf("SDR: AC97 is not ready\n");
260*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_MASTER_VOLUME, 0x0000);
261*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_MONO_VOLUME, 0x8000);
262*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_PHONE_VOLUME, 0x8008);
263*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_MIC_VOLUME, 0x0000);
264*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_LINE_IN_VOLUME, 0x0303);
265*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_CD_VOLUME, 0x0808);
266*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_AUX_IN_VOLUME, 0x0808);
267*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_PCM_OUT_VOLUME, 0x0808);
268*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_RECORD_GAIN_VOLUME, 0x0000);
269*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_RECORD_SELECT, 0x0000);
270*8acfcfc3SJia-Ju Bai dev_mixer_write(base, AC97_GENERAL_PURPOSE, 0x0000);
271*8acfcfc3SJia-Ju Bai #endif
272*8acfcfc3SJia-Ju Bai }
273