1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
4 | * Universal interface for Audio Codec '97 |
5 | * |
6 | * For more details look to AC '97 component specification revision 2.2 |
7 | * by Intel Corporation (http://developer.intel.com) and to datasheets |
8 | * for specific codecs. |
9 | */ |
10 | |
11 | #include <linux/delay.h> |
12 | #include <linux/init.h> |
13 | #include <linux/slab.h> |
14 | #include <linux/mutex.h> |
15 | #include <linux/export.h> |
16 | |
17 | #include <sound/core.h> |
18 | #include <sound/pcm.h> |
19 | #include <sound/control.h> |
20 | #include <sound/ac97_codec.h> |
21 | #include <sound/asoundef.h> |
22 | #include "ac97_id.h" |
23 | #include "ac97_local.h" |
24 | |
25 | /* |
26 | * PCM support |
27 | */ |
28 | |
29 | static const unsigned char rate_reg_tables[2][4][9] = { |
30 | { |
31 | /* standard rates */ |
32 | { |
33 | /* 3&4 front, 7&8 rear, 6&9 center/lfe */ |
34 | AC97_PCM_FRONT_DAC_RATE, /* slot 3 */ |
35 | AC97_PCM_FRONT_DAC_RATE, /* slot 4 */ |
36 | 0xff, /* slot 5 */ |
37 | AC97_PCM_LFE_DAC_RATE, /* slot 6 */ |
38 | AC97_PCM_SURR_DAC_RATE, /* slot 7 */ |
39 | AC97_PCM_SURR_DAC_RATE, /* slot 8 */ |
40 | AC97_PCM_LFE_DAC_RATE, /* slot 9 */ |
41 | 0xff, /* slot 10 */ |
42 | 0xff, /* slot 11 */ |
43 | }, |
44 | { |
45 | /* 7&8 front, 6&9 rear, 10&11 center/lfe */ |
46 | 0xff, /* slot 3 */ |
47 | 0xff, /* slot 4 */ |
48 | 0xff, /* slot 5 */ |
49 | AC97_PCM_SURR_DAC_RATE, /* slot 6 */ |
50 | AC97_PCM_FRONT_DAC_RATE, /* slot 7 */ |
51 | AC97_PCM_FRONT_DAC_RATE, /* slot 8 */ |
52 | AC97_PCM_SURR_DAC_RATE, /* slot 9 */ |
53 | AC97_PCM_LFE_DAC_RATE, /* slot 10 */ |
54 | AC97_PCM_LFE_DAC_RATE, /* slot 11 */ |
55 | }, |
56 | { |
57 | /* 6&9 front, 10&11 rear, 3&4 center/lfe */ |
58 | AC97_PCM_LFE_DAC_RATE, /* slot 3 */ |
59 | AC97_PCM_LFE_DAC_RATE, /* slot 4 */ |
60 | 0xff, /* slot 5 */ |
61 | AC97_PCM_FRONT_DAC_RATE, /* slot 6 */ |
62 | 0xff, /* slot 7 */ |
63 | 0xff, /* slot 8 */ |
64 | AC97_PCM_FRONT_DAC_RATE, /* slot 9 */ |
65 | AC97_PCM_SURR_DAC_RATE, /* slot 10 */ |
66 | AC97_PCM_SURR_DAC_RATE, /* slot 11 */ |
67 | }, |
68 | { |
69 | /* 10&11 front, 3&4 rear, 7&8 center/lfe */ |
70 | AC97_PCM_SURR_DAC_RATE, /* slot 3 */ |
71 | AC97_PCM_SURR_DAC_RATE, /* slot 4 */ |
72 | 0xff, /* slot 5 */ |
73 | 0xff, /* slot 6 */ |
74 | AC97_PCM_LFE_DAC_RATE, /* slot 7 */ |
75 | AC97_PCM_LFE_DAC_RATE, /* slot 8 */ |
76 | 0xff, /* slot 9 */ |
77 | AC97_PCM_FRONT_DAC_RATE, /* slot 10 */ |
78 | AC97_PCM_FRONT_DAC_RATE, /* slot 11 */ |
79 | }, |
80 | }, |
81 | { |
82 | /* double rates */ |
83 | { |
84 | /* 3&4 front, 7&8 front (t+1) */ |
85 | AC97_PCM_FRONT_DAC_RATE, /* slot 3 */ |
86 | AC97_PCM_FRONT_DAC_RATE, /* slot 4 */ |
87 | 0xff, /* slot 5 */ |
88 | 0xff, /* slot 6 */ |
89 | AC97_PCM_FRONT_DAC_RATE, /* slot 7 */ |
90 | AC97_PCM_FRONT_DAC_RATE, /* slot 8 */ |
91 | 0xff, /* slot 9 */ |
92 | 0xff, /* slot 10 */ |
93 | 0xff, /* slot 11 */ |
94 | }, |
95 | { |
96 | /* not specified in the specification */ |
97 | 0xff, /* slot 3 */ |
98 | 0xff, /* slot 4 */ |
99 | 0xff, /* slot 5 */ |
100 | 0xff, /* slot 6 */ |
101 | 0xff, /* slot 7 */ |
102 | 0xff, /* slot 8 */ |
103 | 0xff, /* slot 9 */ |
104 | 0xff, /* slot 10 */ |
105 | 0xff, /* slot 11 */ |
106 | }, |
107 | { |
108 | 0xff, /* slot 3 */ |
109 | 0xff, /* slot 4 */ |
110 | 0xff, /* slot 5 */ |
111 | 0xff, /* slot 6 */ |
112 | 0xff, /* slot 7 */ |
113 | 0xff, /* slot 8 */ |
114 | 0xff, /* slot 9 */ |
115 | 0xff, /* slot 10 */ |
116 | 0xff, /* slot 11 */ |
117 | }, |
118 | { |
119 | 0xff, /* slot 3 */ |
120 | 0xff, /* slot 4 */ |
121 | 0xff, /* slot 5 */ |
122 | 0xff, /* slot 6 */ |
123 | 0xff, /* slot 7 */ |
124 | 0xff, /* slot 8 */ |
125 | 0xff, /* slot 9 */ |
126 | 0xff, /* slot 10 */ |
127 | 0xff, /* slot 11 */ |
128 | } |
129 | }}; |
130 | |
131 | /* FIXME: more various mappings for ADC? */ |
132 | static const unsigned char rate_cregs[9] = { |
133 | AC97_PCM_LR_ADC_RATE, /* 3 */ |
134 | AC97_PCM_LR_ADC_RATE, /* 4 */ |
135 | 0xff, /* 5 */ |
136 | AC97_PCM_MIC_ADC_RATE, /* 6 */ |
137 | 0xff, /* 7 */ |
138 | 0xff, /* 8 */ |
139 | 0xff, /* 9 */ |
140 | 0xff, /* 10 */ |
141 | 0xff, /* 11 */ |
142 | }; |
143 | |
144 | static unsigned char get_slot_reg(struct ac97_pcm *pcm, unsigned short cidx, |
145 | unsigned short slot, int dbl) |
146 | { |
147 | if (slot < 3) |
148 | return 0xff; |
149 | if (slot > 11) |
150 | return 0xff; |
151 | if (pcm->spdif) |
152 | return AC97_SPDIF; /* pseudo register */ |
153 | if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) |
154 | return rate_reg_tables[dbl][pcm->r[dbl].rate_table[cidx]][slot - 3]; |
155 | else |
156 | return rate_cregs[slot - 3]; |
157 | } |
158 | |
159 | static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) |
160 | { |
161 | unsigned short old, bits, reg, mask; |
162 | unsigned int sbits; |
163 | |
164 | if (! (ac97->ext_id & AC97_EI_SPDIF)) |
165 | return -ENODEV; |
166 | |
167 | /* TODO: double rate support */ |
168 | if (ac97->flags & AC97_CS_SPDIF) { |
169 | switch (rate) { |
170 | case 48000: bits = 0; break; |
171 | case 44100: bits = 1 << AC97_SC_SPSR_SHIFT; break; |
172 | default: /* invalid - disable output */ |
173 | snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, value: 0); |
174 | return -EINVAL; |
175 | } |
176 | reg = AC97_CSR_SPDIF; |
177 | mask = 1 << AC97_SC_SPSR_SHIFT; |
178 | } else { |
179 | if (ac97->id == AC97_ID_CM9739 && rate != 48000) { |
180 | snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, value: 0); |
181 | return -EINVAL; |
182 | } |
183 | switch (rate) { |
184 | case 44100: bits = AC97_SC_SPSR_44K; break; |
185 | case 48000: bits = AC97_SC_SPSR_48K; break; |
186 | case 32000: bits = AC97_SC_SPSR_32K; break; |
187 | default: /* invalid - disable output */ |
188 | snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, value: 0); |
189 | return -EINVAL; |
190 | } |
191 | reg = AC97_SPDIF; |
192 | mask = AC97_SC_SPSR_MASK; |
193 | } |
194 | |
195 | mutex_lock(&ac97->reg_mutex); |
196 | old = snd_ac97_read(ac97, reg) & mask; |
197 | if (old != bits) { |
198 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, value: 0); |
199 | snd_ac97_update_bits_nolock(ac97, reg, mask, value: bits); |
200 | /* update the internal spdif bits */ |
201 | sbits = ac97->spdif_status; |
202 | if (sbits & IEC958_AES0_PROFESSIONAL) { |
203 | sbits &= ~IEC958_AES0_PRO_FS; |
204 | switch (rate) { |
205 | case 44100: sbits |= IEC958_AES0_PRO_FS_44100; break; |
206 | case 48000: sbits |= IEC958_AES0_PRO_FS_48000; break; |
207 | case 32000: sbits |= IEC958_AES0_PRO_FS_32000; break; |
208 | } |
209 | } else { |
210 | sbits &= ~(IEC958_AES3_CON_FS << 24); |
211 | switch (rate) { |
212 | case 44100: sbits |= IEC958_AES3_CON_FS_44100<<24; break; |
213 | case 48000: sbits |= IEC958_AES3_CON_FS_48000<<24; break; |
214 | case 32000: sbits |= IEC958_AES3_CON_FS_32000<<24; break; |
215 | } |
216 | } |
217 | ac97->spdif_status = sbits; |
218 | } |
219 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); |
220 | mutex_unlock(lock: &ac97->reg_mutex); |
221 | return 0; |
222 | } |
223 | |
224 | /** |
225 | * snd_ac97_set_rate - change the rate of the given input/output. |
226 | * @ac97: the ac97 instance |
227 | * @reg: the register to change |
228 | * @rate: the sample rate to set |
229 | * |
230 | * Changes the rate of the given input/output on the codec. |
231 | * If the codec doesn't support VAR, the rate must be 48000 (except |
232 | * for SPDIF). |
233 | * |
234 | * The valid registers are AC97_PCM_MIC_ADC_RATE, |
235 | * AC97_PCM_FRONT_DAC_RATE, AC97_PCM_LR_ADC_RATE. |
236 | * AC97_PCM_SURR_DAC_RATE and AC97_PCM_LFE_DAC_RATE are accepted |
237 | * if the codec supports them. |
238 | * AC97_SPDIF is accepted as a pseudo register to modify the SPDIF |
239 | * status bits. |
240 | * |
241 | * Return: Zero if successful, or a negative error code on failure. |
242 | */ |
243 | int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate) |
244 | { |
245 | int dbl; |
246 | unsigned int tmp; |
247 | |
248 | dbl = rate > 48000; |
249 | if (dbl) { |
250 | if (!(ac97->flags & AC97_DOUBLE_RATE)) |
251 | return -EINVAL; |
252 | if (reg != AC97_PCM_FRONT_DAC_RATE) |
253 | return -EINVAL; |
254 | } |
255 | |
256 | snd_ac97_update_power(ac97, reg, powerup: 1); |
257 | switch (reg) { |
258 | case AC97_PCM_MIC_ADC_RATE: |
259 | if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRM) == 0) /* MIC VRA */ |
260 | if (rate != 48000) |
261 | return -EINVAL; |
262 | break; |
263 | case AC97_PCM_FRONT_DAC_RATE: |
264 | case AC97_PCM_LR_ADC_RATE: |
265 | if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0) /* VRA */ |
266 | if (rate != 48000 && rate != 96000) |
267 | return -EINVAL; |
268 | break; |
269 | case AC97_PCM_SURR_DAC_RATE: |
270 | if (! (ac97->scaps & AC97_SCAP_SURROUND_DAC)) |
271 | return -EINVAL; |
272 | break; |
273 | case AC97_PCM_LFE_DAC_RATE: |
274 | if (! (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)) |
275 | return -EINVAL; |
276 | break; |
277 | case AC97_SPDIF: |
278 | /* special case */ |
279 | return set_spdif_rate(ac97, rate); |
280 | default: |
281 | return -EINVAL; |
282 | } |
283 | if (dbl) |
284 | rate /= 2; |
285 | tmp = (rate * ac97->bus->clock) / 48000; |
286 | if (tmp > 65535) |
287 | return -EINVAL; |
288 | if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) |
289 | snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, |
290 | AC97_EA_DRA, value: dbl ? AC97_EA_DRA : 0); |
291 | snd_ac97_update(ac97, reg, value: tmp & 0xffff); |
292 | snd_ac97_read(ac97, reg); |
293 | if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) { |
294 | /* Intel controllers require double rate data to be put in |
295 | * slots 7+8 |
296 | */ |
297 | snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, |
298 | AC97_GP_DRSS_MASK, |
299 | value: dbl ? AC97_GP_DRSS_78 : 0); |
300 | snd_ac97_read(ac97, AC97_GENERAL_PURPOSE); |
301 | } |
302 | return 0; |
303 | } |
304 | |
305 | EXPORT_SYMBOL(snd_ac97_set_rate); |
306 | |
307 | static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots) |
308 | { |
309 | if (!ac97_is_audio(ac97)) |
310 | return 0; |
311 | if (ac97_is_rev22(ac97) || ac97_can_amap(ac97)) { |
312 | unsigned short slots = 0; |
313 | if (ac97_is_rev22(ac97)) { |
314 | /* Note: it's simply emulation of AMAP behaviour */ |
315 | u16 es; |
316 | es = ac97->regs[AC97_EXTENDED_ID] &= ~AC97_EI_DACS_SLOT_MASK; |
317 | switch (ac97->addr) { |
318 | case 1: |
319 | case 2: es |= (1<<AC97_EI_DACS_SLOT_SHIFT); break; |
320 | case 3: es |= (2<<AC97_EI_DACS_SLOT_SHIFT); break; |
321 | } |
322 | snd_ac97_write_cache(ac97, AC97_EXTENDED_ID, value: es); |
323 | } |
324 | switch (ac97->addr) { |
325 | case 0: |
326 | slots |= (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT); |
327 | if (ac97->scaps & AC97_SCAP_SURROUND_DAC) |
328 | slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT); |
329 | if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) |
330 | slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE); |
331 | if (ac97->ext_id & AC97_EI_SPDIF) { |
332 | if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC)) |
333 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT)|(1<<AC97_SLOT_SPDIF_RIGHT); |
334 | else if (!(ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)) |
335 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1); |
336 | else |
337 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2); |
338 | } |
339 | *rate_table = 0; |
340 | break; |
341 | case 1: |
342 | case 2: |
343 | slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT); |
344 | if (ac97->scaps & AC97_SCAP_SURROUND_DAC) |
345 | slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE); |
346 | if (ac97->ext_id & AC97_EI_SPDIF) { |
347 | if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC)) |
348 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1); |
349 | else |
350 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2); |
351 | } |
352 | *rate_table = 1; |
353 | break; |
354 | case 3: |
355 | slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE); |
356 | if (ac97->ext_id & AC97_EI_SPDIF) |
357 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2); |
358 | *rate_table = 2; |
359 | break; |
360 | } |
361 | return slots; |
362 | } else { |
363 | unsigned short slots; |
364 | slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT); |
365 | if (ac97->scaps & AC97_SCAP_SURROUND_DAC) |
366 | slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT); |
367 | if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) |
368 | slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE); |
369 | if (ac97->ext_id & AC97_EI_SPDIF) { |
370 | if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC)) |
371 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT)|(1<<AC97_SLOT_SPDIF_RIGHT); |
372 | else if (!(ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)) |
373 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1); |
374 | else |
375 | *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2); |
376 | } |
377 | *rate_table = 0; |
378 | return slots; |
379 | } |
380 | } |
381 | |
382 | static unsigned short get_cslots(struct snd_ac97 *ac97) |
383 | { |
384 | unsigned short slots; |
385 | |
386 | if (!ac97_is_audio(ac97)) |
387 | return 0; |
388 | slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT); |
389 | slots |= (1<<AC97_SLOT_MIC); |
390 | return slots; |
391 | } |
392 | |
393 | static unsigned int get_rates(struct ac97_pcm *pcm, unsigned int cidx, unsigned short slots, int dbl) |
394 | { |
395 | int i, idx; |
396 | unsigned int rates = ~0; |
397 | unsigned char reg; |
398 | |
399 | for (i = 3; i < 12; i++) { |
400 | if (!(slots & (1 << i))) |
401 | continue; |
402 | reg = get_slot_reg(pcm, cidx, slot: i, dbl); |
403 | switch (reg) { |
404 | case AC97_PCM_FRONT_DAC_RATE: idx = AC97_RATES_FRONT_DAC; break; |
405 | case AC97_PCM_SURR_DAC_RATE: idx = AC97_RATES_SURR_DAC; break; |
406 | case AC97_PCM_LFE_DAC_RATE: idx = AC97_RATES_LFE_DAC; break; |
407 | case AC97_PCM_LR_ADC_RATE: idx = AC97_RATES_ADC; break; |
408 | case AC97_PCM_MIC_ADC_RATE: idx = AC97_RATES_MIC_ADC; break; |
409 | default: idx = AC97_RATES_SPDIF; break; |
410 | } |
411 | rates &= pcm->r[dbl].codec[cidx]->rates[idx]; |
412 | } |
413 | if (!dbl) |
414 | rates &= ~(SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | |
415 | SNDRV_PCM_RATE_96000); |
416 | return rates; |
417 | } |
418 | |
419 | /** |
420 | * snd_ac97_pcm_assign - assign AC97 slots to given PCM streams |
421 | * @bus: the ac97 bus instance |
422 | * @pcms_count: count of PCMs to be assigned |
423 | * @pcms: PCMs to be assigned |
424 | * |
425 | * It assigns available AC97 slots for given PCMs. If none or only |
426 | * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members |
427 | * are reduced and might be zero. |
428 | * |
429 | * Return: Zero if successful, or a negative error code on failure. |
430 | */ |
431 | int snd_ac97_pcm_assign(struct snd_ac97_bus *bus, |
432 | unsigned short pcms_count, |
433 | const struct ac97_pcm *pcms) |
434 | { |
435 | int i, j, k; |
436 | const struct ac97_pcm *pcm; |
437 | struct ac97_pcm *rpcms, *rpcm; |
438 | unsigned short avail_slots[2][4]; |
439 | unsigned char rate_table[2][4]; |
440 | unsigned short tmp, slots; |
441 | unsigned short spdif_slots[4]; |
442 | unsigned int rates; |
443 | struct snd_ac97 *codec; |
444 | |
445 | rpcms = kcalloc(n: pcms_count, size: sizeof(struct ac97_pcm), GFP_KERNEL); |
446 | if (rpcms == NULL) |
447 | return -ENOMEM; |
448 | memset(avail_slots, 0, sizeof(avail_slots)); |
449 | memset(rate_table, 0, sizeof(rate_table)); |
450 | memset(spdif_slots, 0, sizeof(spdif_slots)); |
451 | for (i = 0; i < 4; i++) { |
452 | codec = bus->codec[i]; |
453 | if (!codec) |
454 | continue; |
455 | avail_slots[0][i] = get_pslots(ac97: codec, rate_table: &rate_table[0][i], spdif_slots: &spdif_slots[i]); |
456 | avail_slots[1][i] = get_cslots(ac97: codec); |
457 | if (!(codec->scaps & AC97_SCAP_INDEP_SDIN)) { |
458 | for (j = 0; j < i; j++) { |
459 | if (bus->codec[j]) |
460 | avail_slots[1][i] &= ~avail_slots[1][j]; |
461 | } |
462 | } |
463 | } |
464 | /* first step - exclusive devices */ |
465 | for (i = 0; i < pcms_count; i++) { |
466 | pcm = &pcms[i]; |
467 | rpcm = &rpcms[i]; |
468 | /* low-level driver thinks that it's more clever */ |
469 | if (pcm->copy_flag) { |
470 | *rpcm = *pcm; |
471 | continue; |
472 | } |
473 | rpcm->stream = pcm->stream; |
474 | rpcm->exclusive = pcm->exclusive; |
475 | rpcm->spdif = pcm->spdif; |
476 | rpcm->private_value = pcm->private_value; |
477 | rpcm->bus = bus; |
478 | rpcm->rates = ~0; |
479 | slots = pcm->r[0].slots; |
480 | for (j = 0; j < 4 && slots; j++) { |
481 | if (!bus->codec[j]) |
482 | continue; |
483 | rates = ~0; |
484 | if (pcm->spdif && pcm->stream == 0) |
485 | tmp = spdif_slots[j]; |
486 | else |
487 | tmp = avail_slots[pcm->stream][j]; |
488 | if (pcm->exclusive) { |
489 | /* exclusive access */ |
490 | tmp &= slots; |
491 | for (k = 0; k < i; k++) { |
492 | if (rpcm->stream == rpcms[k].stream) |
493 | tmp &= ~rpcms[k].r[0].rslots[j]; |
494 | } |
495 | } else { |
496 | /* non-exclusive access */ |
497 | tmp &= pcm->r[0].slots; |
498 | } |
499 | if (tmp) { |
500 | rpcm->r[0].rslots[j] = tmp; |
501 | rpcm->r[0].codec[j] = bus->codec[j]; |
502 | rpcm->r[0].rate_table[j] = rate_table[pcm->stream][j]; |
503 | if (bus->no_vra) |
504 | rates = SNDRV_PCM_RATE_48000; |
505 | else |
506 | rates = get_rates(pcm: rpcm, cidx: j, slots: tmp, dbl: 0); |
507 | if (pcm->exclusive) |
508 | avail_slots[pcm->stream][j] &= ~tmp; |
509 | } |
510 | slots &= ~tmp; |
511 | rpcm->r[0].slots |= tmp; |
512 | rpcm->rates &= rates; |
513 | } |
514 | /* for double rate, we check the first codec only */ |
515 | if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK && |
516 | bus->codec[0] && (bus->codec[0]->flags & AC97_DOUBLE_RATE) && |
517 | rate_table[pcm->stream][0] == 0) { |
518 | tmp = (1<<AC97_SLOT_PCM_LEFT) | (1<<AC97_SLOT_PCM_RIGHT) | |
519 | (1<<AC97_SLOT_PCM_LEFT_0) | (1<<AC97_SLOT_PCM_RIGHT_0); |
520 | if ((tmp & pcm->r[1].slots) == tmp) { |
521 | rpcm->r[1].slots = tmp; |
522 | rpcm->r[1].rslots[0] = tmp; |
523 | rpcm->r[1].rate_table[0] = 0; |
524 | rpcm->r[1].codec[0] = bus->codec[0]; |
525 | if (pcm->exclusive) |
526 | avail_slots[pcm->stream][0] &= ~tmp; |
527 | if (bus->no_vra) |
528 | rates = SNDRV_PCM_RATE_96000; |
529 | else |
530 | rates = get_rates(pcm: rpcm, cidx: 0, slots: tmp, dbl: 1); |
531 | rpcm->rates |= rates; |
532 | } |
533 | } |
534 | if (rpcm->rates == ~0) |
535 | rpcm->rates = 0; /* not used */ |
536 | } |
537 | bus->pcms_count = pcms_count; |
538 | bus->pcms = rpcms; |
539 | return 0; |
540 | } |
541 | |
542 | EXPORT_SYMBOL(snd_ac97_pcm_assign); |
543 | |
544 | /** |
545 | * snd_ac97_pcm_open - opens the given AC97 pcm |
546 | * @pcm: the ac97 pcm instance |
547 | * @rate: rate in Hz, if codec does not support VRA, this value must be 48000Hz |
548 | * @cfg: output stream characteristics |
549 | * @slots: a subset of allocated slots (snd_ac97_pcm_assign) for this pcm |
550 | * |
551 | * It locks the specified slots and sets the given rate to AC97 registers. |
552 | * |
553 | * Return: Zero if successful, or a negative error code on failure. |
554 | */ |
555 | int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate, |
556 | enum ac97_pcm_cfg cfg, unsigned short slots) |
557 | { |
558 | struct snd_ac97_bus *bus; |
559 | int i, cidx, r, ok_flag; |
560 | unsigned int reg_ok[4] = {0,0,0,0}; |
561 | unsigned char reg; |
562 | int err = 0; |
563 | |
564 | r = rate > 48000; |
565 | bus = pcm->bus; |
566 | if (cfg == AC97_PCM_CFG_SPDIF) { |
567 | for (cidx = 0; cidx < 4; cidx++) |
568 | if (bus->codec[cidx] && (bus->codec[cidx]->ext_id & AC97_EI_SPDIF)) { |
569 | err = set_spdif_rate(ac97: bus->codec[cidx], rate); |
570 | if (err < 0) |
571 | return err; |
572 | } |
573 | } |
574 | spin_lock_irq(lock: &pcm->bus->bus_lock); |
575 | for (i = 3; i < 12; i++) { |
576 | if (!(slots & (1 << i))) |
577 | continue; |
578 | ok_flag = 0; |
579 | for (cidx = 0; cidx < 4; cidx++) { |
580 | if (bus->used_slots[pcm->stream][cidx] & (1 << i)) { |
581 | spin_unlock_irq(lock: &pcm->bus->bus_lock); |
582 | err = -EBUSY; |
583 | goto error; |
584 | } |
585 | if (pcm->r[r].rslots[cidx] & (1 << i)) { |
586 | bus->used_slots[pcm->stream][cidx] |= (1 << i); |
587 | ok_flag++; |
588 | } |
589 | } |
590 | if (!ok_flag) { |
591 | spin_unlock_irq(lock: &pcm->bus->bus_lock); |
592 | dev_err(bus->card->dev, |
593 | "cannot find configuration for AC97 slot %i\n" , |
594 | i); |
595 | err = -EAGAIN; |
596 | goto error; |
597 | } |
598 | } |
599 | pcm->cur_dbl = r; |
600 | spin_unlock_irq(lock: &pcm->bus->bus_lock); |
601 | for (i = 3; i < 12; i++) { |
602 | if (!(slots & (1 << i))) |
603 | continue; |
604 | for (cidx = 0; cidx < 4; cidx++) { |
605 | if (pcm->r[r].rslots[cidx] & (1 << i)) { |
606 | reg = get_slot_reg(pcm, cidx, slot: i, dbl: r); |
607 | if (reg == 0xff) { |
608 | dev_err(bus->card->dev, |
609 | "invalid AC97 slot %i?\n" , i); |
610 | continue; |
611 | } |
612 | if (reg_ok[cidx] & (1 << (reg - AC97_PCM_FRONT_DAC_RATE))) |
613 | continue; |
614 | dev_dbg(bus->card->dev, |
615 | "setting ac97 reg 0x%x to rate %d\n" , |
616 | reg, rate); |
617 | err = snd_ac97_set_rate(pcm->r[r].codec[cidx], reg, rate); |
618 | if (err < 0) |
619 | dev_err(bus->card->dev, |
620 | "error in snd_ac97_set_rate: cidx=%d, reg=0x%x, rate=%d, err=%d\n" , |
621 | cidx, reg, rate, err); |
622 | else |
623 | reg_ok[cidx] |= (1 << (reg - AC97_PCM_FRONT_DAC_RATE)); |
624 | } |
625 | } |
626 | } |
627 | pcm->aslots = slots; |
628 | return 0; |
629 | |
630 | error: |
631 | pcm->aslots = slots; |
632 | snd_ac97_pcm_close(pcm); |
633 | return err; |
634 | } |
635 | |
636 | EXPORT_SYMBOL(snd_ac97_pcm_open); |
637 | |
638 | /** |
639 | * snd_ac97_pcm_close - closes the given AC97 pcm |
640 | * @pcm: the ac97 pcm instance |
641 | * |
642 | * It frees the locked AC97 slots. |
643 | * |
644 | * Return: Zero. |
645 | */ |
646 | int snd_ac97_pcm_close(struct ac97_pcm *pcm) |
647 | { |
648 | struct snd_ac97_bus *bus; |
649 | unsigned short slots = pcm->aslots; |
650 | int i, cidx; |
651 | |
652 | #ifdef CONFIG_SND_AC97_POWER_SAVE |
653 | int r = pcm->cur_dbl; |
654 | for (i = 3; i < 12; i++) { |
655 | if (!(slots & (1 << i))) |
656 | continue; |
657 | for (cidx = 0; cidx < 4; cidx++) { |
658 | if (pcm->r[r].rslots[cidx] & (1 << i)) { |
659 | int reg = get_slot_reg(pcm, cidx, slot: i, dbl: r); |
660 | snd_ac97_update_power(ac97: pcm->r[r].codec[cidx], |
661 | reg, powerup: 0); |
662 | } |
663 | } |
664 | } |
665 | #endif |
666 | |
667 | bus = pcm->bus; |
668 | spin_lock_irq(lock: &pcm->bus->bus_lock); |
669 | for (i = 3; i < 12; i++) { |
670 | if (!(slots & (1 << i))) |
671 | continue; |
672 | for (cidx = 0; cidx < 4; cidx++) |
673 | bus->used_slots[pcm->stream][cidx] &= ~(1 << i); |
674 | } |
675 | pcm->aslots = 0; |
676 | pcm->cur_dbl = 0; |
677 | spin_unlock_irq(lock: &pcm->bus->bus_lock); |
678 | return 0; |
679 | } |
680 | |
681 | EXPORT_SYMBOL(snd_ac97_pcm_close); |
682 | |
683 | static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params, |
684 | struct snd_pcm_hw_rule *rule) |
685 | { |
686 | struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
687 | if (channels->min > 2) { |
688 | static const struct snd_interval single_rates = { |
689 | .min = 1, |
690 | .max = 48000, |
691 | }; |
692 | struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
693 | return snd_interval_refine(i: rate, v: &single_rates); |
694 | } |
695 | return 0; |
696 | } |
697 | |
698 | static int double_rate_hw_constraint_channels(struct snd_pcm_hw_params *params, |
699 | struct snd_pcm_hw_rule *rule) |
700 | { |
701 | struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
702 | if (rate->min > 48000) { |
703 | static const struct snd_interval double_rate_channels = { |
704 | .min = 2, |
705 | .max = 2, |
706 | }; |
707 | struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
708 | return snd_interval_refine(i: channels, v: &double_rate_channels); |
709 | } |
710 | return 0; |
711 | } |
712 | |
713 | /** |
714 | * snd_ac97_pcm_double_rate_rules - set double rate constraints |
715 | * @runtime: the runtime of the ac97 front playback pcm |
716 | * |
717 | * Installs the hardware constraint rules to prevent using double rates and |
718 | * more than two channels at the same time. |
719 | * |
720 | * Return: Zero if successful, or a negative error code on failure. |
721 | */ |
722 | int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime) |
723 | { |
724 | int err; |
725 | |
726 | err = snd_pcm_hw_rule_add(runtime, cond: 0, SNDRV_PCM_HW_PARAM_RATE, |
727 | func: double_rate_hw_constraint_rate, NULL, |
728 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
729 | if (err < 0) |
730 | return err; |
731 | err = snd_pcm_hw_rule_add(runtime, cond: 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
732 | func: double_rate_hw_constraint_channels, NULL, |
733 | SNDRV_PCM_HW_PARAM_RATE, -1); |
734 | return err; |
735 | } |
736 | |
737 | EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules); |
738 | |