etc/services - sync with NetBSD-8
[minix.git] / minix / drivers / audio / als4000 / mixer.c
blobc07d1f2b2a2dadc083a002ab8f7a9e3e2b619280
1 #include "mixer.h"
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;
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;
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;
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];
74 return OK;
76 #endif
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;
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;
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);
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;
153 return OK;
155 #endif
157 #ifdef MIXER_AC97
158 int get_set_volume(u32_t *base, struct volume_level *level, int flag) {
159 int max_level, cmd, data;
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;
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);
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;
221 return OK;
223 #endif
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
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);
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