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