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