1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Maintained by Jaroslav Kysela <perex@perex.cz>
4 * Originated by audio@tridentmicro.com
5 * Fri Feb 19 15:55:28 MST 1999
6 * Routines for control of Trident 4DWave (DX and NX) chip
7 *
8 * BUGS:
9 *
10 * TODO:
11 * ---
12 *
13 * SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net>
14 */
15
16 #include <linux/delay.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/pci.h>
20 #include <linux/slab.h>
21 #include <linux/vmalloc.h>
22 #include <linux/gameport.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/export.h>
25 #include <linux/io.h>
26
27 #include <sound/core.h>
28 #include <sound/info.h>
29 #include <sound/control.h>
30 #include <sound/tlv.h>
31 #include "trident.h"
32 #include <sound/asoundef.h>
33
34 static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
35 struct snd_trident_voice * voice,
36 struct snd_pcm_substream *substream);
37 static int snd_trident_pcm_mixer_free(struct snd_trident *trident,
38 struct snd_trident_voice * voice,
39 struct snd_pcm_substream *substream);
40 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id);
41 static int snd_trident_sis_reset(struct snd_trident *trident);
42
43 static void snd_trident_clear_voices(struct snd_trident * trident,
44 unsigned short v_min, unsigned short v_max);
45 static void snd_trident_free(struct snd_card *card);
46
47 /*
48 * common I/O routines
49 */
50
51
52 #if 0
53 static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice)
54 {
55 unsigned int val, tmp;
56
57 dev_dbg(trident->card->dev, "Trident voice %i:\n", voice);
58 outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR));
59 val = inl(TRID_REG(trident, CH_LBA));
60 dev_dbg(trident->card->dev, "LBA: 0x%x\n", val);
61 val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
62 dev_dbg(trident->card->dev, "GVSel: %i\n", val >> 31);
63 dev_dbg(trident->card->dev, "Pan: 0x%x\n", (val >> 24) & 0x7f);
64 dev_dbg(trident->card->dev, "Vol: 0x%x\n", (val >> 16) & 0xff);
65 dev_dbg(trident->card->dev, "CTRL: 0x%x\n", (val >> 12) & 0x0f);
66 dev_dbg(trident->card->dev, "EC: 0x%x\n", val & 0x0fff);
67 if (trident->device != TRIDENT_DEVICE_ID_NX) {
68 val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS));
69 dev_dbg(trident->card->dev, "CSO: 0x%x\n", val >> 16);
70 dev_dbg(trident->card->dev, "Alpha: 0x%x\n", (val >> 4) & 0x0fff);
71 dev_dbg(trident->card->dev, "FMS: 0x%x\n", val & 0x0f);
72 val = inl(TRID_REG(trident, CH_DX_ESO_DELTA));
73 dev_dbg(trident->card->dev, "ESO: 0x%x\n", val >> 16);
74 dev_dbg(trident->card->dev, "Delta: 0x%x\n", val & 0xffff);
75 val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
76 } else { // TRIDENT_DEVICE_ID_NX
77 val = inl(TRID_REG(trident, CH_NX_DELTA_CSO));
78 tmp = (val >> 24) & 0xff;
79 dev_dbg(trident->card->dev, "CSO: 0x%x\n", val & 0x00ffffff);
80 val = inl(TRID_REG(trident, CH_NX_DELTA_ESO));
81 tmp |= (val >> 16) & 0xff00;
82 dev_dbg(trident->card->dev, "Delta: 0x%x\n", tmp);
83 dev_dbg(trident->card->dev, "ESO: 0x%x\n", val & 0x00ffffff);
84 val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL));
85 dev_dbg(trident->card->dev, "Alpha: 0x%x\n", val >> 20);
86 dev_dbg(trident->card->dev, "FMS: 0x%x\n", (val >> 16) & 0x0f);
87 }
88 dev_dbg(trident->card->dev, "FMC: 0x%x\n", (val >> 14) & 3);
89 dev_dbg(trident->card->dev, "RVol: 0x%x\n", (val >> 7) & 0x7f);
90 dev_dbg(trident->card->dev, "CVol: 0x%x\n", val & 0x7f);
91 }
92 #endif
93
94 /*---------------------------------------------------------------------------
95 unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
96
97 Description: This routine will do all of the reading from the external
98 CODEC (AC97).
99
100 Parameters: ac97 - ac97 codec structure
101 reg - CODEC register index, from AC97 Hal.
102
103 returns: 16 bit value read from the AC97.
104
105 ---------------------------------------------------------------------------*/
snd_trident_codec_read(struct snd_ac97 * ac97,unsigned short reg)106 static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
107 {
108 unsigned int data = 0, treg;
109 unsigned short count = 0xffff;
110 struct snd_trident *trident = ac97->private_data;
111
112 guard(spinlock_irqsave)(&trident->reg_lock);
113 if (trident->device == TRIDENT_DEVICE_ID_DX) {
114 data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
115 outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
116 do {
117 data = inl(TRID_REG(trident, DX_ACR1_AC97_R));
118 if ((data & DX_AC97_BUSY_READ) == 0)
119 break;
120 } while (--count);
121 } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
122 data = (NX_AC97_BUSY_READ | (reg & 0x000000ff));
123 treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY;
124 outl(data, TRID_REG(trident, treg));
125 do {
126 data = inl(TRID_REG(trident, treg));
127 if ((data & 0x00000C00) == 0)
128 break;
129 } while (--count);
130 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
131 data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
132 if (ac97->num == 1)
133 data |= SI_AC97_SECONDARY;
134 outl(data, TRID_REG(trident, SI_AC97_READ));
135 do {
136 data = inl(TRID_REG(trident, SI_AC97_READ));
137 if ((data & (SI_AC97_BUSY_READ)) == 0)
138 break;
139 } while (--count);
140 }
141
142 if (count == 0 && !trident->ac97_detect) {
143 dev_err(trident->card->dev,
144 "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n",
145 reg, data);
146 data = 0;
147 }
148
149 return ((unsigned short) (data >> 16));
150 }
151
152 /*---------------------------------------------------------------------------
153 void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
154 unsigned short wdata)
155
156 Description: This routine will do all of the writing to the external
157 CODEC (AC97).
158
159 Parameters: ac97 - ac97 codec structure
160 reg - CODEC register index, from AC97 Hal.
161 data - Lower 16 bits are the data to write to CODEC.
162
163 returns: TRUE if everything went ok, else FALSE.
164
165 ---------------------------------------------------------------------------*/
snd_trident_codec_write(struct snd_ac97 * ac97,unsigned short reg,unsigned short wdata)166 static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
167 unsigned short wdata)
168 {
169 unsigned int address, data;
170 unsigned short count = 0xffff;
171 struct snd_trident *trident = ac97->private_data;
172
173 data = ((unsigned long) wdata) << 16;
174
175 guard(spinlock_irqsave)(&trident->reg_lock);
176 if (trident->device == TRIDENT_DEVICE_ID_DX) {
177 address = DX_ACR0_AC97_W;
178
179 /* read AC-97 write register status */
180 do {
181 if ((inw(TRID_REG(trident, address)) & DX_AC97_BUSY_WRITE) == 0)
182 break;
183 } while (--count);
184
185 data |= (DX_AC97_BUSY_WRITE | (reg & 0x000000ff));
186 } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
187 address = NX_ACR1_AC97_W;
188
189 /* read AC-97 write register status */
190 do {
191 if ((inw(TRID_REG(trident, address)) & NX_AC97_BUSY_WRITE) == 0)
192 break;
193 } while (--count);
194
195 data |= (NX_AC97_BUSY_WRITE | (ac97->num << 8) | (reg & 0x000000ff));
196 } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
197 address = SI_AC97_WRITE;
198
199 /* read AC-97 write register status */
200 do {
201 if ((inw(TRID_REG(trident, address)) & (SI_AC97_BUSY_WRITE)) == 0)
202 break;
203 } while (--count);
204
205 data |= SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
206 if (ac97->num == 1)
207 data |= SI_AC97_SECONDARY;
208 } else {
209 address = 0; /* keep GCC happy */
210 count = 0; /* return */
211 }
212
213 if (count == 0)
214 return;
215 outl(data, TRID_REG(trident, address));
216 }
217
218 /*---------------------------------------------------------------------------
219 void snd_trident_enable_eso(struct snd_trident *trident)
220
221 Description: This routine will enable end of loop interrupts.
222 End of loop interrupts will occur when a running
223 channel reaches ESO.
224 Also enables middle of loop interrupts.
225
226 Parameters: trident - pointer to target device class for 4DWave.
227
228 ---------------------------------------------------------------------------*/
229
snd_trident_enable_eso(struct snd_trident * trident)230 static void snd_trident_enable_eso(struct snd_trident * trident)
231 {
232 unsigned int val;
233
234 val = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
235 val |= ENDLP_IE;
236 val |= MIDLP_IE;
237 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
238 val |= BANK_B_EN;
239 outl(val, TRID_REG(trident, T4D_LFO_GC_CIR));
240 }
241
242 /*---------------------------------------------------------------------------
243 void snd_trident_disable_eso(struct snd_trident *trident)
244
245 Description: This routine will disable end of loop interrupts.
246 End of loop interrupts will occur when a running
247 channel reaches ESO.
248 Also disables middle of loop interrupts.
249
250 Parameters:
251 trident - pointer to target device class for 4DWave.
252
253 returns: TRUE if everything went ok, else FALSE.
254
255 ---------------------------------------------------------------------------*/
256
snd_trident_disable_eso(struct snd_trident * trident)257 static void snd_trident_disable_eso(struct snd_trident * trident)
258 {
259 unsigned int tmp;
260
261 tmp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
262 tmp &= ~ENDLP_IE;
263 tmp &= ~MIDLP_IE;
264 outl(tmp, TRID_REG(trident, T4D_LFO_GC_CIR));
265 }
266
267 /*---------------------------------------------------------------------------
268 void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
269
270 Description: Start a voice, any channel 0 thru 63.
271 This routine automatically handles the fact that there are
272 more than 32 channels available.
273
274 Parameters : voice - Voice number 0 thru n.
275 trident - pointer to target device class for 4DWave.
276
277 Return Value: None.
278
279 ---------------------------------------------------------------------------*/
280
snd_trident_start_voice(struct snd_trident * trident,unsigned int voice)281 void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
282 {
283 unsigned int mask = 1 << (voice & 0x1f);
284 unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A;
285
286 outl(mask, TRID_REG(trident, reg));
287 }
288
289 EXPORT_SYMBOL(snd_trident_start_voice);
290
291 /*---------------------------------------------------------------------------
292 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
293
294 Description: Stop a voice, any channel 0 thru 63.
295 This routine automatically handles the fact that there are
296 more than 32 channels available.
297
298 Parameters : voice - Voice number 0 thru n.
299 trident - pointer to target device class for 4DWave.
300
301 Return Value: None.
302
303 ---------------------------------------------------------------------------*/
304
snd_trident_stop_voice(struct snd_trident * trident,unsigned int voice)305 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
306 {
307 unsigned int mask = 1 << (voice & 0x1f);
308 unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A;
309
310 outl(mask, TRID_REG(trident, reg));
311 }
312
313 EXPORT_SYMBOL(snd_trident_stop_voice);
314
315 /*---------------------------------------------------------------------------
316 int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
317
318 Description: Allocate hardware channel in Bank B (32-63).
319
320 Parameters : trident - pointer to target device class for 4DWave.
321
322 Return Value: hardware channel - 32-63 or -1 when no channel is available
323
324 ---------------------------------------------------------------------------*/
325
snd_trident_allocate_pcm_channel(struct snd_trident * trident)326 static int snd_trident_allocate_pcm_channel(struct snd_trident * trident)
327 {
328 int idx;
329
330 if (trident->ChanPCMcnt >= trident->ChanPCM)
331 return -1;
332 for (idx = 31; idx >= 0; idx--) {
333 if (!(trident->ChanMap[T4D_BANK_B] & (1 << idx))) {
334 trident->ChanMap[T4D_BANK_B] |= 1 << idx;
335 trident->ChanPCMcnt++;
336 return idx + 32;
337 }
338 }
339 return -1;
340 }
341
342 /*---------------------------------------------------------------------------
343 void snd_trident_free_pcm_channel(int channel)
344
345 Description: Free hardware channel in Bank B (32-63)
346
347 Parameters : trident - pointer to target device class for 4DWave.
348 channel - hardware channel number 0-63
349
350 Return Value: none
351
352 ---------------------------------------------------------------------------*/
353
snd_trident_free_pcm_channel(struct snd_trident * trident,int channel)354 static void snd_trident_free_pcm_channel(struct snd_trident *trident, int channel)
355 {
356 if (channel < 32 || channel > 63)
357 return;
358 channel &= 0x1f;
359 if (trident->ChanMap[T4D_BANK_B] & (1 << channel)) {
360 trident->ChanMap[T4D_BANK_B] &= ~(1 << channel);
361 trident->ChanPCMcnt--;
362 }
363 }
364
365 /*---------------------------------------------------------------------------
366 unsigned int snd_trident_allocate_synth_channel(void)
367
368 Description: Allocate hardware channel in Bank A (0-31).
369
370 Parameters : trident - pointer to target device class for 4DWave.
371
372 Return Value: hardware channel - 0-31 or -1 when no channel is available
373
374 ---------------------------------------------------------------------------*/
375
snd_trident_allocate_synth_channel(struct snd_trident * trident)376 static int snd_trident_allocate_synth_channel(struct snd_trident * trident)
377 {
378 int idx;
379
380 for (idx = 31; idx >= 0; idx--) {
381 if (!(trident->ChanMap[T4D_BANK_A] & (1 << idx))) {
382 trident->ChanMap[T4D_BANK_A] |= 1 << idx;
383 trident->synth.ChanSynthCount++;
384 return idx;
385 }
386 }
387 return -1;
388 }
389
390 /*---------------------------------------------------------------------------
391 void snd_trident_free_synth_channel( int channel )
392
393 Description: Free hardware channel in Bank B (0-31).
394
395 Parameters : trident - pointer to target device class for 4DWave.
396 channel - hardware channel number 0-63
397
398 Return Value: none
399
400 ---------------------------------------------------------------------------*/
401
snd_trident_free_synth_channel(struct snd_trident * trident,int channel)402 static void snd_trident_free_synth_channel(struct snd_trident *trident, int channel)
403 {
404 if (channel < 0 || channel > 31)
405 return;
406 channel &= 0x1f;
407 if (trident->ChanMap[T4D_BANK_A] & (1 << channel)) {
408 trident->ChanMap[T4D_BANK_A] &= ~(1 << channel);
409 trident->synth.ChanSynthCount--;
410 }
411 }
412
413 /*---------------------------------------------------------------------------
414 snd_trident_write_voice_regs
415
416 Description: This routine will complete and write the 5 hardware channel
417 registers to hardware.
418
419 Parameters: trident - pointer to target device class for 4DWave.
420 voice - synthesizer voice structure
421 Each register field.
422
423 ---------------------------------------------------------------------------*/
424
snd_trident_write_voice_regs(struct snd_trident * trident,struct snd_trident_voice * voice)425 void snd_trident_write_voice_regs(struct snd_trident * trident,
426 struct snd_trident_voice * voice)
427 {
428 unsigned int FmcRvolCvol;
429 unsigned int regs[5];
430
431 regs[1] = voice->LBA;
432 regs[4] = (voice->GVSel << 31) |
433 ((voice->Pan & 0x0000007f) << 24) |
434 ((voice->CTRL & 0x0000000f) << 12);
435 FmcRvolCvol = ((voice->FMC & 3) << 14) |
436 ((voice->RVol & 0x7f) << 7) |
437 (voice->CVol & 0x7f);
438
439 switch (trident->device) {
440 case TRIDENT_DEVICE_ID_SI7018:
441 regs[4] |= voice->number > 31 ?
442 (voice->Vol & 0x000003ff) :
443 ((voice->Vol & 0x00003fc) << (16-2)) |
444 (voice->EC & 0x00000fff);
445 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
446 (voice->FMS & 0x0000000f);
447 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
448 regs[3] = (voice->Attribute << 16) | FmcRvolCvol;
449 break;
450 case TRIDENT_DEVICE_ID_DX:
451 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
452 (voice->EC & 0x00000fff);
453 regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
454 (voice->FMS & 0x0000000f);
455 regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
456 regs[3] = FmcRvolCvol;
457 break;
458 case TRIDENT_DEVICE_ID_NX:
459 regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
460 (voice->EC & 0x00000fff);
461 regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);
462 regs[2] = ((voice->Delta << 16) & 0xff000000) |
463 (voice->ESO & 0x00ffffff);
464 regs[3] = (voice->Alpha << 20) |
465 ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
466 break;
467 default:
468 snd_BUG();
469 return;
470 }
471
472 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
473 outl(regs[0], TRID_REG(trident, CH_START + 0));
474 outl(regs[1], TRID_REG(trident, CH_START + 4));
475 outl(regs[2], TRID_REG(trident, CH_START + 8));
476 outl(regs[3], TRID_REG(trident, CH_START + 12));
477 outl(regs[4], TRID_REG(trident, CH_START + 16));
478
479 #if 0
480 dev_dbg(trident->card->dev, "written %i channel:\n", voice->number);
481 dev_dbg(trident->card->dev, " regs[0] = 0x%x/0x%x\n",
482 regs[0], inl(TRID_REG(trident, CH_START + 0)));
483 dev_dbg(trident->card->dev, " regs[1] = 0x%x/0x%x\n",
484 regs[1], inl(TRID_REG(trident, CH_START + 4)));
485 dev_dbg(trident->card->dev, " regs[2] = 0x%x/0x%x\n",
486 regs[2], inl(TRID_REG(trident, CH_START + 8)));
487 dev_dbg(trident->card->dev, " regs[3] = 0x%x/0x%x\n",
488 regs[3], inl(TRID_REG(trident, CH_START + 12)));
489 dev_dbg(trident->card->dev, " regs[4] = 0x%x/0x%x\n",
490 regs[4], inl(TRID_REG(trident, CH_START + 16)));
491 #endif
492 }
493
494 EXPORT_SYMBOL(snd_trident_write_voice_regs);
495
496 /*---------------------------------------------------------------------------
497 snd_trident_write_cso_reg
498
499 Description: This routine will write the new CSO offset
500 register to hardware.
501
502 Parameters: trident - pointer to target device class for 4DWave.
503 voice - synthesizer voice structure
504 CSO - new CSO value
505
506 ---------------------------------------------------------------------------*/
507
snd_trident_write_cso_reg(struct snd_trident * trident,struct snd_trident_voice * voice,unsigned int CSO)508 static void snd_trident_write_cso_reg(struct snd_trident * trident,
509 struct snd_trident_voice * voice,
510 unsigned int CSO)
511 {
512 voice->CSO = CSO;
513 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
514 if (trident->device != TRIDENT_DEVICE_ID_NX) {
515 outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
516 } else {
517 outl((voice->Delta << 24) |
518 (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
519 }
520 }
521
522 /*---------------------------------------------------------------------------
523 snd_trident_write_eso_reg
524
525 Description: This routine will write the new ESO offset
526 register to hardware.
527
528 Parameters: trident - pointer to target device class for 4DWave.
529 voice - synthesizer voice structure
530 ESO - new ESO value
531
532 ---------------------------------------------------------------------------*/
533
snd_trident_write_eso_reg(struct snd_trident * trident,struct snd_trident_voice * voice,unsigned int ESO)534 static void snd_trident_write_eso_reg(struct snd_trident * trident,
535 struct snd_trident_voice * voice,
536 unsigned int ESO)
537 {
538 voice->ESO = ESO;
539 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
540 if (trident->device != TRIDENT_DEVICE_ID_NX) {
541 outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
542 } else {
543 outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff),
544 TRID_REG(trident, CH_NX_DELTA_ESO));
545 }
546 }
547
548 /*---------------------------------------------------------------------------
549 snd_trident_write_vol_reg
550
551 Description: This routine will write the new voice volume
552 register to hardware.
553
554 Parameters: trident - pointer to target device class for 4DWave.
555 voice - synthesizer voice structure
556 Vol - new voice volume
557
558 ---------------------------------------------------------------------------*/
559
snd_trident_write_vol_reg(struct snd_trident * trident,struct snd_trident_voice * voice,unsigned int Vol)560 static void snd_trident_write_vol_reg(struct snd_trident * trident,
561 struct snd_trident_voice * voice,
562 unsigned int Vol)
563 {
564 voice->Vol = Vol;
565 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
566 switch (trident->device) {
567 case TRIDENT_DEVICE_ID_DX:
568 case TRIDENT_DEVICE_ID_NX:
569 outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2));
570 break;
571 case TRIDENT_DEVICE_ID_SI7018:
572 /* dev_dbg(trident->card->dev, "voice->Vol = 0x%x\n", voice->Vol); */
573 outw((voice->CTRL << 12) | voice->Vol,
574 TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
575 break;
576 }
577 }
578
579 /*---------------------------------------------------------------------------
580 snd_trident_write_pan_reg
581
582 Description: This routine will write the new voice pan
583 register to hardware.
584
585 Parameters: trident - pointer to target device class for 4DWave.
586 voice - synthesizer voice structure
587 Pan - new pan value
588
589 ---------------------------------------------------------------------------*/
590
snd_trident_write_pan_reg(struct snd_trident * trident,struct snd_trident_voice * voice,unsigned int Pan)591 static void snd_trident_write_pan_reg(struct snd_trident * trident,
592 struct snd_trident_voice * voice,
593 unsigned int Pan)
594 {
595 voice->Pan = Pan;
596 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
597 outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f),
598 TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
599 }
600
601 /*---------------------------------------------------------------------------
602 snd_trident_write_rvol_reg
603
604 Description: This routine will write the new reverb volume
605 register to hardware.
606
607 Parameters: trident - pointer to target device class for 4DWave.
608 voice - synthesizer voice structure
609 RVol - new reverb volume
610
611 ---------------------------------------------------------------------------*/
612
snd_trident_write_rvol_reg(struct snd_trident * trident,struct snd_trident_voice * voice,unsigned int RVol)613 static void snd_trident_write_rvol_reg(struct snd_trident * trident,
614 struct snd_trident_voice * voice,
615 unsigned int RVol)
616 {
617 voice->RVol = RVol;
618 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
619 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
620 (voice->CVol & 0x007f),
621 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
622 CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
623 }
624
625 /*---------------------------------------------------------------------------
626 snd_trident_write_cvol_reg
627
628 Description: This routine will write the new chorus volume
629 register to hardware.
630
631 Parameters: trident - pointer to target device class for 4DWave.
632 voice - synthesizer voice structure
633 CVol - new chorus volume
634
635 ---------------------------------------------------------------------------*/
636
snd_trident_write_cvol_reg(struct snd_trident * trident,struct snd_trident_voice * voice,unsigned int CVol)637 static void snd_trident_write_cvol_reg(struct snd_trident * trident,
638 struct snd_trident_voice * voice,
639 unsigned int CVol)
640 {
641 voice->CVol = CVol;
642 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
643 outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
644 (voice->CVol & 0x007f),
645 TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
646 CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
647 }
648
649 /*---------------------------------------------------------------------------
650 snd_trident_convert_rate
651
652 Description: This routine converts rate in HZ to hardware delta value.
653
654 Parameters: trident - pointer to target device class for 4DWave.
655 rate - Real or Virtual channel number.
656
657 Returns: Delta value.
658
659 ---------------------------------------------------------------------------*/
snd_trident_convert_rate(unsigned int rate)660 static unsigned int snd_trident_convert_rate(unsigned int rate)
661 {
662 unsigned int delta;
663
664 // We special case 44100 and 8000 since rounding with the equation
665 // does not give us an accurate enough value. For 11025 and 22050
666 // the equation gives us the best answer. All other frequencies will
667 // also use the equation. JDW
668 if (rate == 44100)
669 delta = 0xeb3;
670 else if (rate == 8000)
671 delta = 0x2ab;
672 else if (rate == 48000)
673 delta = 0x1000;
674 else
675 delta = DIV_ROUND_CLOSEST(rate << 12, 48000) & 0x0000ffff;
676 return delta;
677 }
678
679 /*---------------------------------------------------------------------------
680 snd_trident_convert_adc_rate
681
682 Description: This routine converts rate in HZ to hardware delta value.
683
684 Parameters: trident - pointer to target device class for 4DWave.
685 rate - Real or Virtual channel number.
686
687 Returns: Delta value.
688
689 ---------------------------------------------------------------------------*/
snd_trident_convert_adc_rate(unsigned int rate)690 static unsigned int snd_trident_convert_adc_rate(unsigned int rate)
691 {
692 unsigned int delta;
693
694 // We special case 44100 and 8000 since rounding with the equation
695 // does not give us an accurate enough value. For 11025 and 22050
696 // the equation gives us the best answer. All other frequencies will
697 // also use the equation. JDW
698 if (rate == 44100)
699 delta = 0x116a;
700 else if (rate == 8000)
701 delta = 0x6000;
702 else if (rate == 48000)
703 delta = 0x1000;
704 else
705 delta = ((48000 << 12) / rate) & 0x0000ffff;
706 return delta;
707 }
708
709 /*---------------------------------------------------------------------------
710 snd_trident_spurious_threshold
711
712 Description: This routine converts rate in HZ to spurious threshold.
713
714 Parameters: trident - pointer to target device class for 4DWave.
715 rate - Real or Virtual channel number.
716
717 Returns: Delta value.
718
719 ---------------------------------------------------------------------------*/
snd_trident_spurious_threshold(unsigned int rate,unsigned int period_size)720 static unsigned int snd_trident_spurious_threshold(unsigned int rate,
721 unsigned int period_size)
722 {
723 unsigned int res = (rate * period_size) / 48000;
724 if (res < 64)
725 res = res / 2;
726 else
727 res -= 32;
728 return res;
729 }
730
731 /*---------------------------------------------------------------------------
732 snd_trident_control_mode
733
734 Description: This routine returns a control mode for a PCM channel.
735
736 Parameters: trident - pointer to target device class for 4DWave.
737 substream - PCM substream
738
739 Returns: Control value.
740
741 ---------------------------------------------------------------------------*/
snd_trident_control_mode(struct snd_pcm_substream * substream)742 static unsigned int snd_trident_control_mode(struct snd_pcm_substream *substream)
743 {
744 unsigned int CTRL;
745 struct snd_pcm_runtime *runtime = substream->runtime;
746
747 /* set ctrl mode
748 CTRL default: 8-bit (unsigned) mono, loop mode enabled
749 */
750 CTRL = 0x00000001;
751 if (snd_pcm_format_width(runtime->format) == 16)
752 CTRL |= 0x00000008; // 16-bit data
753 if (snd_pcm_format_signed(runtime->format))
754 CTRL |= 0x00000002; // signed data
755 if (runtime->channels > 1)
756 CTRL |= 0x00000004; // stereo data
757 return CTRL;
758 }
759
760 /*
761 * PCM part
762 */
763
764 /*---------------------------------------------------------------------------
765 snd_trident_allocate_pcm_mem
766
767 Description: Allocate PCM ring buffer for given substream
768
769 Parameters: substream - PCM substream class
770 hw_params - hardware parameters
771
772 Returns: Error status
773
774 ---------------------------------------------------------------------------*/
775
snd_trident_allocate_pcm_mem(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)776 static int snd_trident_allocate_pcm_mem(struct snd_pcm_substream *substream,
777 struct snd_pcm_hw_params *hw_params)
778 {
779 struct snd_trident *trident = snd_pcm_substream_chip(substream);
780 struct snd_pcm_runtime *runtime = substream->runtime;
781 struct snd_trident_voice *voice = runtime->private_data;
782
783 if (trident->tlb.entries) {
784 if (runtime->buffer_changed) {
785 if (voice->memblk)
786 snd_trident_free_pages(trident, voice->memblk);
787 voice->memblk = snd_trident_alloc_pages(trident, substream);
788 if (voice->memblk == NULL)
789 return -ENOMEM;
790 }
791 }
792 return 0;
793 }
794
795 /*---------------------------------------------------------------------------
796 snd_trident_allocate_evoice
797
798 Description: Allocate extra voice as interrupt generator
799
800 Parameters: substream - PCM substream class
801 hw_params - hardware parameters
802
803 Returns: Error status
804
805 ---------------------------------------------------------------------------*/
806
snd_trident_allocate_evoice(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)807 static int snd_trident_allocate_evoice(struct snd_pcm_substream *substream,
808 struct snd_pcm_hw_params *hw_params)
809 {
810 struct snd_trident *trident = snd_pcm_substream_chip(substream);
811 struct snd_pcm_runtime *runtime = substream->runtime;
812 struct snd_trident_voice *voice = runtime->private_data;
813 struct snd_trident_voice *evoice = voice->extra;
814
815 /* voice management */
816
817 if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) {
818 if (evoice == NULL) {
819 evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
820 if (evoice == NULL)
821 return -ENOMEM;
822 voice->extra = evoice;
823 evoice->substream = substream;
824 }
825 } else {
826 if (evoice != NULL) {
827 snd_trident_free_voice(trident, evoice);
828 voice->extra = evoice = NULL;
829 }
830 }
831
832 return 0;
833 }
834
835 /*---------------------------------------------------------------------------
836 snd_trident_hw_params
837
838 Description: Set the hardware parameters for the playback device.
839
840 Parameters: substream - PCM substream class
841 hw_params - hardware parameters
842
843 Returns: Error status
844
845 ---------------------------------------------------------------------------*/
846
snd_trident_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)847 static int snd_trident_hw_params(struct snd_pcm_substream *substream,
848 struct snd_pcm_hw_params *hw_params)
849 {
850 int err;
851
852 err = snd_trident_allocate_pcm_mem(substream, hw_params);
853 if (err >= 0)
854 err = snd_trident_allocate_evoice(substream, hw_params);
855 return err;
856 }
857
858 /*---------------------------------------------------------------------------
859 snd_trident_playback_hw_free
860
861 Description: Release the hardware resources for the playback device.
862
863 Parameters: substream - PCM substream class
864
865 Returns: Error status
866
867 ---------------------------------------------------------------------------*/
868
snd_trident_hw_free(struct snd_pcm_substream * substream)869 static int snd_trident_hw_free(struct snd_pcm_substream *substream)
870 {
871 struct snd_trident *trident = snd_pcm_substream_chip(substream);
872 struct snd_pcm_runtime *runtime = substream->runtime;
873 struct snd_trident_voice *voice = runtime->private_data;
874 struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
875
876 if (trident->tlb.entries) {
877 if (voice && voice->memblk) {
878 snd_trident_free_pages(trident, voice->memblk);
879 voice->memblk = NULL;
880 }
881 }
882 if (evoice != NULL) {
883 snd_trident_free_voice(trident, evoice);
884 voice->extra = NULL;
885 }
886 return 0;
887 }
888
889 /*---------------------------------------------------------------------------
890 snd_trident_playback_prepare
891
892 Description: Prepare playback device for playback.
893
894 Parameters: substream - PCM substream class
895
896 Returns: Error status
897
898 ---------------------------------------------------------------------------*/
899
snd_trident_playback_prepare(struct snd_pcm_substream * substream)900 static int snd_trident_playback_prepare(struct snd_pcm_substream *substream)
901 {
902 struct snd_trident *trident = snd_pcm_substream_chip(substream);
903 struct snd_pcm_runtime *runtime = substream->runtime;
904 struct snd_trident_voice *voice = runtime->private_data;
905 struct snd_trident_voice *evoice = voice->extra;
906 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
907
908 guard(spinlock_irq)(&trident->reg_lock);
909
910 /* set delta (rate) value */
911 voice->Delta = snd_trident_convert_rate(runtime->rate);
912 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
913
914 /* set Loop Begin Address */
915 if (voice->memblk)
916 voice->LBA = voice->memblk->offset;
917 else
918 voice->LBA = runtime->dma_addr;
919
920 voice->CSO = 0;
921 voice->ESO = runtime->buffer_size - 1; /* in samples */
922 voice->CTRL = snd_trident_control_mode(substream);
923 voice->FMC = 3;
924 voice->GVSel = 1;
925 voice->EC = 0;
926 voice->Alpha = 0;
927 voice->FMS = 0;
928 voice->Vol = mix->vol;
929 voice->RVol = mix->rvol;
930 voice->CVol = mix->cvol;
931 voice->Pan = mix->pan;
932 voice->Attribute = 0;
933 #if 0
934 voice->Attribute = (1<<(30-16))|(2<<(26-16))|
935 (0<<(24-16))|(0x1f<<(19-16));
936 #else
937 voice->Attribute = 0;
938 #endif
939
940 snd_trident_write_voice_regs(trident, voice);
941
942 if (evoice != NULL) {
943 evoice->Delta = voice->Delta;
944 evoice->spurious_threshold = voice->spurious_threshold;
945 evoice->LBA = voice->LBA;
946 evoice->CSO = 0;
947 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
948 evoice->CTRL = voice->CTRL;
949 evoice->FMC = 3;
950 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
951 evoice->EC = 0;
952 evoice->Alpha = 0;
953 evoice->FMS = 0;
954 evoice->Vol = 0x3ff; /* mute */
955 evoice->RVol = evoice->CVol = 0x7f; /* mute */
956 evoice->Pan = 0x7f; /* mute */
957 #if 0
958 evoice->Attribute = (1<<(30-16))|(2<<(26-16))|
959 (0<<(24-16))|(0x1f<<(19-16));
960 #else
961 evoice->Attribute = 0;
962 #endif
963 snd_trident_write_voice_regs(trident, evoice);
964 evoice->isync2 = 1;
965 evoice->isync_mark = runtime->period_size;
966 evoice->ESO = (runtime->period_size * 2) - 1;
967 }
968
969 return 0;
970 }
971
972 /*---------------------------------------------------------------------------
973 snd_trident_capture_hw_params
974
975 Description: Set the hardware parameters for the capture device.
976
977 Parameters: substream - PCM substream class
978 hw_params - hardware parameters
979
980 Returns: Error status
981
982 ---------------------------------------------------------------------------*/
983
snd_trident_capture_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)984 static int snd_trident_capture_hw_params(struct snd_pcm_substream *substream,
985 struct snd_pcm_hw_params *hw_params)
986 {
987 return snd_trident_allocate_pcm_mem(substream, hw_params);
988 }
989
990 /*---------------------------------------------------------------------------
991 snd_trident_capture_prepare
992
993 Description: Prepare capture device for playback.
994
995 Parameters: substream - PCM substream class
996
997 Returns: Error status
998
999 ---------------------------------------------------------------------------*/
1000
snd_trident_capture_prepare(struct snd_pcm_substream * substream)1001 static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
1002 {
1003 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1004 struct snd_pcm_runtime *runtime = substream->runtime;
1005 struct snd_trident_voice *voice = runtime->private_data;
1006 unsigned int val, ESO_bytes;
1007
1008 guard(spinlock_irq)(&trident->reg_lock);
1009
1010 // Initialize the channel and set channel Mode
1011 outb(0, TRID_REG(trident, LEGACY_DMAR15));
1012
1013 // Set DMA channel operation mode register
1014 outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
1015
1016 // Set channel buffer Address, DMAR0 expects contiguous PCI memory area
1017 voice->LBA = runtime->dma_addr;
1018 outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
1019 if (voice->memblk)
1020 voice->LBA = voice->memblk->offset;
1021
1022 // set ESO
1023 ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
1024 outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6));
1025 outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4));
1026 ESO_bytes++;
1027
1028 // Set channel sample rate, 4.12 format
1029 val = DIV_ROUND_CLOSEST(48000U << 12, runtime->rate);
1030 outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));
1031
1032 // Set channel interrupt blk length
1033 if (snd_pcm_format_width(runtime->format) == 16) {
1034 val = (unsigned short) ((ESO_bytes >> 1) - 1);
1035 } else {
1036 val = (unsigned short) (ESO_bytes - 1);
1037 }
1038
1039 outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL));
1040
1041 // Right now, set format and start to run captureing,
1042 // continuous run loop enable.
1043 trident->bDMAStart = 0x19; // 0001 1001b
1044
1045 if (snd_pcm_format_width(runtime->format) == 16)
1046 trident->bDMAStart |= 0x80;
1047 if (snd_pcm_format_signed(runtime->format))
1048 trident->bDMAStart |= 0x20;
1049 if (runtime->channels > 1)
1050 trident->bDMAStart |= 0x40;
1051
1052 // Prepare capture intr channel
1053
1054 voice->Delta = snd_trident_convert_rate(runtime->rate);
1055 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1056 voice->isync = 1;
1057 voice->isync_mark = runtime->period_size;
1058 voice->isync_max = runtime->buffer_size;
1059
1060 // Set voice parameters
1061 voice->CSO = 0;
1062 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
1063 voice->CTRL = snd_trident_control_mode(substream);
1064 voice->FMC = 3;
1065 voice->RVol = 0x7f;
1066 voice->CVol = 0x7f;
1067 voice->GVSel = 1;
1068 voice->Pan = 0x7f; /* mute */
1069 voice->Vol = 0x3ff; /* mute */
1070 voice->EC = 0;
1071 voice->Alpha = 0;
1072 voice->FMS = 0;
1073 voice->Attribute = 0;
1074
1075 snd_trident_write_voice_regs(trident, voice);
1076
1077 return 0;
1078 }
1079
1080 /*---------------------------------------------------------------------------
1081 snd_trident_si7018_capture_hw_params
1082
1083 Description: Set the hardware parameters for the capture device.
1084
1085 Parameters: substream - PCM substream class
1086 hw_params - hardware parameters
1087
1088 Returns: Error status
1089
1090 ---------------------------------------------------------------------------*/
1091
snd_trident_si7018_capture_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)1092 static int snd_trident_si7018_capture_hw_params(struct snd_pcm_substream *substream,
1093 struct snd_pcm_hw_params *hw_params)
1094 {
1095 return snd_trident_allocate_evoice(substream, hw_params);
1096 }
1097
1098 /*---------------------------------------------------------------------------
1099 snd_trident_si7018_capture_hw_free
1100
1101 Description: Release the hardware resources for the capture device.
1102
1103 Parameters: substream - PCM substream class
1104
1105 Returns: Error status
1106
1107 ---------------------------------------------------------------------------*/
1108
snd_trident_si7018_capture_hw_free(struct snd_pcm_substream * substream)1109 static int snd_trident_si7018_capture_hw_free(struct snd_pcm_substream *substream)
1110 {
1111 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1112 struct snd_pcm_runtime *runtime = substream->runtime;
1113 struct snd_trident_voice *voice = runtime->private_data;
1114 struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
1115
1116 if (evoice != NULL) {
1117 snd_trident_free_voice(trident, evoice);
1118 voice->extra = NULL;
1119 }
1120 return 0;
1121 }
1122
1123 /*---------------------------------------------------------------------------
1124 snd_trident_si7018_capture_prepare
1125
1126 Description: Prepare capture device for playback.
1127
1128 Parameters: substream - PCM substream class
1129
1130 Returns: Error status
1131
1132 ---------------------------------------------------------------------------*/
1133
snd_trident_si7018_capture_prepare(struct snd_pcm_substream * substream)1134 static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substream)
1135 {
1136 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1137 struct snd_pcm_runtime *runtime = substream->runtime;
1138 struct snd_trident_voice *voice = runtime->private_data;
1139 struct snd_trident_voice *evoice = voice->extra;
1140
1141 guard(spinlock_irq)(&trident->reg_lock);
1142
1143 voice->LBA = runtime->dma_addr;
1144 voice->Delta = snd_trident_convert_adc_rate(runtime->rate);
1145 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1146
1147 // Set voice parameters
1148 voice->CSO = 0;
1149 voice->ESO = runtime->buffer_size - 1; /* in samples */
1150 voice->CTRL = snd_trident_control_mode(substream);
1151 voice->FMC = 0;
1152 voice->RVol = 0;
1153 voice->CVol = 0;
1154 voice->GVSel = 1;
1155 voice->Pan = T4D_DEFAULT_PCM_PAN;
1156 voice->Vol = 0;
1157 voice->EC = 0;
1158 voice->Alpha = 0;
1159 voice->FMS = 0;
1160
1161 voice->Attribute = (2 << (30-16)) |
1162 (2 << (26-16)) |
1163 (2 << (24-16)) |
1164 (1 << (23-16));
1165
1166 snd_trident_write_voice_regs(trident, voice);
1167
1168 if (evoice != NULL) {
1169 evoice->Delta = snd_trident_convert_rate(runtime->rate);
1170 evoice->spurious_threshold = voice->spurious_threshold;
1171 evoice->LBA = voice->LBA;
1172 evoice->CSO = 0;
1173 evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */
1174 evoice->CTRL = voice->CTRL;
1175 evoice->FMC = 3;
1176 evoice->GVSel = 0;
1177 evoice->EC = 0;
1178 evoice->Alpha = 0;
1179 evoice->FMS = 0;
1180 evoice->Vol = 0x3ff; /* mute */
1181 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1182 evoice->Pan = 0x7f; /* mute */
1183 evoice->Attribute = 0;
1184 snd_trident_write_voice_regs(trident, evoice);
1185 evoice->isync2 = 1;
1186 evoice->isync_mark = runtime->period_size;
1187 evoice->ESO = (runtime->period_size * 2) - 1;
1188 }
1189
1190 return 0;
1191 }
1192
1193 /*---------------------------------------------------------------------------
1194 snd_trident_foldback_prepare
1195
1196 Description: Prepare foldback capture device for playback.
1197
1198 Parameters: substream - PCM substream class
1199
1200 Returns: Error status
1201
1202 ---------------------------------------------------------------------------*/
1203
snd_trident_foldback_prepare(struct snd_pcm_substream * substream)1204 static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream)
1205 {
1206 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1207 struct snd_pcm_runtime *runtime = substream->runtime;
1208 struct snd_trident_voice *voice = runtime->private_data;
1209 struct snd_trident_voice *evoice = voice->extra;
1210
1211 guard(spinlock_irq)(&trident->reg_lock);
1212
1213 /* Set channel buffer Address */
1214 if (voice->memblk)
1215 voice->LBA = voice->memblk->offset;
1216 else
1217 voice->LBA = runtime->dma_addr;
1218
1219 /* set target ESO for channel */
1220 voice->ESO = runtime->buffer_size - 1; /* in samples */
1221
1222 /* set sample rate */
1223 voice->Delta = 0x1000;
1224 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
1225
1226 voice->CSO = 0;
1227 voice->CTRL = snd_trident_control_mode(substream);
1228 voice->FMC = 3;
1229 voice->RVol = 0x7f;
1230 voice->CVol = 0x7f;
1231 voice->GVSel = 1;
1232 voice->Pan = 0x7f; /* mute */
1233 voice->Vol = 0x3ff; /* mute */
1234 voice->EC = 0;
1235 voice->Alpha = 0;
1236 voice->FMS = 0;
1237 voice->Attribute = 0;
1238
1239 /* set up capture channel */
1240 outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan));
1241
1242 snd_trident_write_voice_regs(trident, voice);
1243
1244 if (evoice != NULL) {
1245 evoice->Delta = voice->Delta;
1246 evoice->spurious_threshold = voice->spurious_threshold;
1247 evoice->LBA = voice->LBA;
1248 evoice->CSO = 0;
1249 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
1250 evoice->CTRL = voice->CTRL;
1251 evoice->FMC = 3;
1252 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
1253 evoice->EC = 0;
1254 evoice->Alpha = 0;
1255 evoice->FMS = 0;
1256 evoice->Vol = 0x3ff; /* mute */
1257 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1258 evoice->Pan = 0x7f; /* mute */
1259 evoice->Attribute = 0;
1260 snd_trident_write_voice_regs(trident, evoice);
1261 evoice->isync2 = 1;
1262 evoice->isync_mark = runtime->period_size;
1263 evoice->ESO = (runtime->period_size * 2) - 1;
1264 }
1265
1266 return 0;
1267 }
1268
1269 /*---------------------------------------------------------------------------
1270 snd_trident_spdif_hw_params
1271
1272 Description: Set the hardware parameters for the spdif device.
1273
1274 Parameters: substream - PCM substream class
1275 hw_params - hardware parameters
1276
1277 Returns: Error status
1278
1279 ---------------------------------------------------------------------------*/
1280
snd_trident_spdif_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)1281 static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream,
1282 struct snd_pcm_hw_params *hw_params)
1283 {
1284 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1285 unsigned int old_bits = 0, change = 0;
1286 int err;
1287
1288 err = snd_trident_allocate_pcm_mem(substream, hw_params);
1289 if (err < 0)
1290 return err;
1291
1292 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
1293 err = snd_trident_allocate_evoice(substream, hw_params);
1294 if (err < 0)
1295 return err;
1296 }
1297
1298 /* prepare SPDIF channel */
1299 scoped_guard(spinlock_irq, &trident->reg_lock) {
1300 old_bits = trident->spdif_pcm_bits;
1301 if (old_bits & IEC958_AES0_PROFESSIONAL)
1302 trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS;
1303 else
1304 trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24);
1305 if (params_rate(hw_params) >= 48000) {
1306 trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz
1307 trident->spdif_pcm_bits |=
1308 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1309 IEC958_AES0_PRO_FS_48000 :
1310 (IEC958_AES3_CON_FS_48000 << 24);
1311 } else if (params_rate(hw_params) >= 44100) {
1312 trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz
1313 trident->spdif_pcm_bits |=
1314 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1315 IEC958_AES0_PRO_FS_44100 :
1316 (IEC958_AES3_CON_FS_44100 << 24);
1317 } else {
1318 trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz
1319 trident->spdif_pcm_bits |=
1320 trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
1321 IEC958_AES0_PRO_FS_32000 :
1322 (IEC958_AES3_CON_FS_32000 << 24);
1323 }
1324 change = old_bits != trident->spdif_pcm_bits;
1325 }
1326
1327 if (change)
1328 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id);
1329
1330 return 0;
1331 }
1332
1333 /*---------------------------------------------------------------------------
1334 snd_trident_spdif_prepare
1335
1336 Description: Prepare SPDIF device for playback.
1337
1338 Parameters: substream - PCM substream class
1339
1340 Returns: Error status
1341
1342 ---------------------------------------------------------------------------*/
1343
snd_trident_spdif_prepare(struct snd_pcm_substream * substream)1344 static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream)
1345 {
1346 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1347 struct snd_pcm_runtime *runtime = substream->runtime;
1348 struct snd_trident_voice *voice = runtime->private_data;
1349 struct snd_trident_voice *evoice = voice->extra;
1350 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
1351 unsigned int RESO, LBAO;
1352 unsigned int temp;
1353
1354 guard(spinlock_irq)(&trident->reg_lock);
1355
1356 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1357
1358 /* set delta (rate) value */
1359 voice->Delta = snd_trident_convert_rate(runtime->rate);
1360 voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
1361
1362 /* set Loop Back Address */
1363 LBAO = runtime->dma_addr;
1364 if (voice->memblk)
1365 voice->LBA = voice->memblk->offset;
1366 else
1367 voice->LBA = LBAO;
1368
1369 voice->isync = 1;
1370 voice->isync3 = 1;
1371 voice->isync_mark = runtime->period_size;
1372 voice->isync_max = runtime->buffer_size;
1373
1374 /* set target ESO for channel */
1375 RESO = runtime->buffer_size - 1;
1376 voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
1377
1378 /* set ctrl mode */
1379 voice->CTRL = snd_trident_control_mode(substream);
1380
1381 voice->FMC = 3;
1382 voice->RVol = 0x7f;
1383 voice->CVol = 0x7f;
1384 voice->GVSel = 1;
1385 voice->Pan = 0x7f;
1386 voice->Vol = 0x3ff;
1387 voice->EC = 0;
1388 voice->CSO = 0;
1389 voice->Alpha = 0;
1390 voice->FMS = 0;
1391 voice->Attribute = 0;
1392
1393 /* prepare surrogate IRQ channel */
1394 snd_trident_write_voice_regs(trident, voice);
1395
1396 outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO));
1397 outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2));
1398 outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA));
1399 outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO));
1400 outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2));
1401
1402 /* set SPDIF setting */
1403 outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1404 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1405
1406 } else { /* SiS */
1407
1408 /* set delta (rate) value */
1409 voice->Delta = 0x800;
1410 voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
1411
1412 /* set Loop Begin Address */
1413 if (voice->memblk)
1414 voice->LBA = voice->memblk->offset;
1415 else
1416 voice->LBA = runtime->dma_addr;
1417
1418 voice->CSO = 0;
1419 voice->ESO = runtime->buffer_size - 1; /* in samples */
1420 voice->CTRL = snd_trident_control_mode(substream);
1421 voice->FMC = 3;
1422 voice->GVSel = 1;
1423 voice->EC = 0;
1424 voice->Alpha = 0;
1425 voice->FMS = 0;
1426 voice->Vol = mix->vol;
1427 voice->RVol = mix->rvol;
1428 voice->CVol = mix->cvol;
1429 voice->Pan = mix->pan;
1430 voice->Attribute = (1<<(30-16))|(7<<(26-16))|
1431 (0<<(24-16))|(0<<(19-16));
1432
1433 snd_trident_write_voice_regs(trident, voice);
1434
1435 if (evoice != NULL) {
1436 evoice->Delta = voice->Delta;
1437 evoice->spurious_threshold = voice->spurious_threshold;
1438 evoice->LBA = voice->LBA;
1439 evoice->CSO = 0;
1440 evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
1441 evoice->CTRL = voice->CTRL;
1442 evoice->FMC = 3;
1443 evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
1444 evoice->EC = 0;
1445 evoice->Alpha = 0;
1446 evoice->FMS = 0;
1447 evoice->Vol = 0x3ff; /* mute */
1448 evoice->RVol = evoice->CVol = 0x7f; /* mute */
1449 evoice->Pan = 0x7f; /* mute */
1450 evoice->Attribute = 0;
1451 snd_trident_write_voice_regs(trident, evoice);
1452 evoice->isync2 = 1;
1453 evoice->isync_mark = runtime->period_size;
1454 evoice->ESO = (runtime->period_size * 2) - 1;
1455 }
1456
1457 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1458 temp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
1459 temp &= ~(1<<19);
1460 outl(temp, TRID_REG(trident, T4D_LFO_GC_CIR));
1461 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1462 temp |= SPDIF_EN;
1463 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1464 }
1465
1466 return 0;
1467 }
1468
1469 /*---------------------------------------------------------------------------
1470 snd_trident_trigger
1471
1472 Description: Start/stop devices
1473
1474 Parameters: substream - PCM substream class
1475 cmd - trigger command (STOP, GO)
1476
1477 Returns: Error status
1478
1479 ---------------------------------------------------------------------------*/
1480
snd_trident_trigger(struct snd_pcm_substream * substream,int cmd)1481 static int snd_trident_trigger(struct snd_pcm_substream *substream,
1482 int cmd)
1483
1484 {
1485 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1486 struct snd_pcm_substream *s;
1487 unsigned int what, whati, capture_flag, spdif_flag;
1488 struct snd_trident_voice *voice, *evoice;
1489 unsigned int val, go;
1490
1491 switch (cmd) {
1492 case SNDRV_PCM_TRIGGER_START:
1493 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1494 case SNDRV_PCM_TRIGGER_RESUME:
1495 go = 1;
1496 break;
1497 case SNDRV_PCM_TRIGGER_STOP:
1498 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1499 case SNDRV_PCM_TRIGGER_SUSPEND:
1500 go = 0;
1501 break;
1502 default:
1503 return -EINVAL;
1504 }
1505 what = whati = capture_flag = spdif_flag = 0;
1506 guard(spinlock)(&trident->reg_lock);
1507 val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
1508 snd_pcm_group_for_each_entry(s, substream) {
1509 if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
1510 voice = s->runtime->private_data;
1511 evoice = voice->extra;
1512 what |= 1 << (voice->number & 0x1f);
1513 if (evoice == NULL) {
1514 whati |= 1 << (voice->number & 0x1f);
1515 } else {
1516 what |= 1 << (evoice->number & 0x1f);
1517 whati |= 1 << (evoice->number & 0x1f);
1518 if (go)
1519 evoice->stimer = val;
1520 }
1521 if (go) {
1522 voice->running = 1;
1523 voice->stimer = val;
1524 } else {
1525 voice->running = 0;
1526 }
1527 snd_pcm_trigger_done(s, substream);
1528 if (voice->capture)
1529 capture_flag = 1;
1530 if (voice->spdif)
1531 spdif_flag = 1;
1532 }
1533 }
1534 if (spdif_flag) {
1535 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1536 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
1537 val = trident->spdif_pcm_ctrl;
1538 if (!go)
1539 val &= ~(0x28);
1540 outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1541 } else {
1542 outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
1543 val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
1544 outl(val, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1545 }
1546 }
1547 if (!go)
1548 outl(what, TRID_REG(trident, T4D_STOP_B));
1549 val = inl(TRID_REG(trident, T4D_AINTEN_B));
1550 if (go) {
1551 val |= whati;
1552 } else {
1553 val &= ~whati;
1554 }
1555 outl(val, TRID_REG(trident, T4D_AINTEN_B));
1556 if (go) {
1557 outl(what, TRID_REG(trident, T4D_START_B));
1558
1559 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
1560 outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
1561 } else {
1562 if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
1563 outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
1564 }
1565 return 0;
1566 }
1567
1568 /*---------------------------------------------------------------------------
1569 snd_trident_playback_pointer
1570
1571 Description: This routine return the playback position
1572
1573 Parameters: substream - PCM substream class
1574
1575 Returns: position of buffer
1576
1577 ---------------------------------------------------------------------------*/
1578
snd_trident_playback_pointer(struct snd_pcm_substream * substream)1579 static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *substream)
1580 {
1581 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1582 struct snd_pcm_runtime *runtime = substream->runtime;
1583 struct snd_trident_voice *voice = runtime->private_data;
1584 unsigned int cso;
1585
1586 if (!voice->running)
1587 return 0;
1588
1589 guard(spinlock)(&trident->reg_lock);
1590
1591 outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
1592
1593 if (trident->device != TRIDENT_DEVICE_ID_NX) {
1594 cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));
1595 } else { // ID_4DWAVE_NX
1596 cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;
1597 }
1598
1599 if (cso >= runtime->buffer_size)
1600 cso = 0;
1601
1602 return cso;
1603 }
1604
1605 /*---------------------------------------------------------------------------
1606 snd_trident_capture_pointer
1607
1608 Description: This routine return the capture position
1609
1610 Parameters: pcm1 - PCM device class
1611
1612 Returns: position of buffer
1613
1614 ---------------------------------------------------------------------------*/
1615
snd_trident_capture_pointer(struct snd_pcm_substream * substream)1616 static snd_pcm_uframes_t snd_trident_capture_pointer(struct snd_pcm_substream *substream)
1617 {
1618 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1619 struct snd_pcm_runtime *runtime = substream->runtime;
1620 struct snd_trident_voice *voice = runtime->private_data;
1621 unsigned int result;
1622
1623 if (!voice->running)
1624 return 0;
1625
1626 result = inw(TRID_REG(trident, T4D_SBBL_SBCL));
1627 if (runtime->channels > 1)
1628 result >>= 1;
1629 if (result > 0)
1630 result = runtime->buffer_size - result;
1631
1632 return result;
1633 }
1634
1635 /*---------------------------------------------------------------------------
1636 snd_trident_spdif_pointer
1637
1638 Description: This routine return the SPDIF playback position
1639
1640 Parameters: substream - PCM substream class
1641
1642 Returns: position of buffer
1643
1644 ---------------------------------------------------------------------------*/
1645
snd_trident_spdif_pointer(struct snd_pcm_substream * substream)1646 static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *substream)
1647 {
1648 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1649 struct snd_pcm_runtime *runtime = substream->runtime;
1650 struct snd_trident_voice *voice = runtime->private_data;
1651 unsigned int result;
1652
1653 if (!voice->running)
1654 return 0;
1655
1656 result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
1657
1658 return result;
1659 }
1660
1661 /*
1662 * Playback support device description
1663 */
1664
1665 static const struct snd_pcm_hardware snd_trident_playback =
1666 {
1667 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1668 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1669 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1670 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
1671 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1672 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1673 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1674 .rate_min = 4000,
1675 .rate_max = 48000,
1676 .channels_min = 1,
1677 .channels_max = 2,
1678 .buffer_bytes_max = (256*1024),
1679 .period_bytes_min = 64,
1680 .period_bytes_max = (256*1024),
1681 .periods_min = 1,
1682 .periods_max = 1024,
1683 .fifo_size = 0,
1684 };
1685
1686 /*
1687 * Capture support device description
1688 */
1689
1690 static const struct snd_pcm_hardware snd_trident_capture =
1691 {
1692 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1693 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1694 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1695 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
1696 .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
1697 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
1698 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1699 .rate_min = 4000,
1700 .rate_max = 48000,
1701 .channels_min = 1,
1702 .channels_max = 2,
1703 .buffer_bytes_max = (128*1024),
1704 .period_bytes_min = 64,
1705 .period_bytes_max = (128*1024),
1706 .periods_min = 1,
1707 .periods_max = 1024,
1708 .fifo_size = 0,
1709 };
1710
1711 /*
1712 * Foldback capture support device description
1713 */
1714
1715 static const struct snd_pcm_hardware snd_trident_foldback =
1716 {
1717 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1718 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1719 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1720 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
1721 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1722 .rates = SNDRV_PCM_RATE_48000,
1723 .rate_min = 48000,
1724 .rate_max = 48000,
1725 .channels_min = 2,
1726 .channels_max = 2,
1727 .buffer_bytes_max = (128*1024),
1728 .period_bytes_min = 64,
1729 .period_bytes_max = (128*1024),
1730 .periods_min = 1,
1731 .periods_max = 1024,
1732 .fifo_size = 0,
1733 };
1734
1735 /*
1736 * SPDIF playback support device description
1737 */
1738
1739 static const struct snd_pcm_hardware snd_trident_spdif =
1740 {
1741 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1742 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1743 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1744 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
1745 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1746 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1747 SNDRV_PCM_RATE_48000),
1748 .rate_min = 32000,
1749 .rate_max = 48000,
1750 .channels_min = 2,
1751 .channels_max = 2,
1752 .buffer_bytes_max = (128*1024),
1753 .period_bytes_min = 64,
1754 .period_bytes_max = (128*1024),
1755 .periods_min = 1,
1756 .periods_max = 1024,
1757 .fifo_size = 0,
1758 };
1759
1760 static const struct snd_pcm_hardware snd_trident_spdif_7018 =
1761 {
1762 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1763 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1764 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
1765 SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
1766 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1767 .rates = SNDRV_PCM_RATE_48000,
1768 .rate_min = 48000,
1769 .rate_max = 48000,
1770 .channels_min = 2,
1771 .channels_max = 2,
1772 .buffer_bytes_max = (128*1024),
1773 .period_bytes_min = 64,
1774 .period_bytes_max = (128*1024),
1775 .periods_min = 1,
1776 .periods_max = 1024,
1777 .fifo_size = 0,
1778 };
1779
snd_trident_pcm_free_substream(struct snd_pcm_runtime * runtime)1780 static void snd_trident_pcm_free_substream(struct snd_pcm_runtime *runtime)
1781 {
1782 struct snd_trident_voice *voice = runtime->private_data;
1783 struct snd_trident *trident;
1784
1785 if (voice) {
1786 trident = voice->trident;
1787 snd_trident_free_voice(trident, voice);
1788 }
1789 }
1790
snd_trident_playback_open(struct snd_pcm_substream * substream)1791 static int snd_trident_playback_open(struct snd_pcm_substream *substream)
1792 {
1793 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1794 struct snd_pcm_runtime *runtime = substream->runtime;
1795 struct snd_trident_voice *voice;
1796
1797 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1798 if (voice == NULL)
1799 return -EAGAIN;
1800 snd_trident_pcm_mixer_build(trident, voice, substream);
1801 voice->substream = substream;
1802 runtime->private_data = voice;
1803 runtime->private_free = snd_trident_pcm_free_substream;
1804 runtime->hw = snd_trident_playback;
1805 snd_pcm_set_sync(substream);
1806 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1807 return 0;
1808 }
1809
1810 /*---------------------------------------------------------------------------
1811 snd_trident_playback_close
1812
1813 Description: This routine will close the 4DWave playback device. For now
1814 we will simply free the dma transfer buffer.
1815
1816 Parameters: substream - PCM substream class
1817
1818 ---------------------------------------------------------------------------*/
snd_trident_playback_close(struct snd_pcm_substream * substream)1819 static int snd_trident_playback_close(struct snd_pcm_substream *substream)
1820 {
1821 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1822 struct snd_pcm_runtime *runtime = substream->runtime;
1823 struct snd_trident_voice *voice = runtime->private_data;
1824
1825 snd_trident_pcm_mixer_free(trident, voice, substream);
1826 return 0;
1827 }
1828
1829 /*---------------------------------------------------------------------------
1830 snd_trident_spdif_open
1831
1832 Description: This routine will open the 4DWave SPDIF device.
1833
1834 Parameters: substream - PCM substream class
1835
1836 Returns: status - success or failure flag
1837
1838 ---------------------------------------------------------------------------*/
1839
snd_trident_spdif_open(struct snd_pcm_substream * substream)1840 static int snd_trident_spdif_open(struct snd_pcm_substream *substream)
1841 {
1842 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1843 struct snd_trident_voice *voice;
1844 struct snd_pcm_runtime *runtime = substream->runtime;
1845
1846 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1847 if (voice == NULL)
1848 return -EAGAIN;
1849 voice->spdif = 1;
1850 voice->substream = substream;
1851 scoped_guard(spinlock_irq, &trident->reg_lock) {
1852 trident->spdif_pcm_bits = trident->spdif_bits;
1853 }
1854
1855 runtime->private_data = voice;
1856 runtime->private_free = snd_trident_pcm_free_substream;
1857 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
1858 runtime->hw = snd_trident_spdif;
1859 } else {
1860 runtime->hw = snd_trident_spdif_7018;
1861 }
1862
1863 trident->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1864 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
1865 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
1866
1867 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1868 return 0;
1869 }
1870
1871
1872 /*---------------------------------------------------------------------------
1873 snd_trident_spdif_close
1874
1875 Description: This routine will close the 4DWave SPDIF device.
1876
1877 Parameters: substream - PCM substream class
1878
1879 ---------------------------------------------------------------------------*/
1880
snd_trident_spdif_close(struct snd_pcm_substream * substream)1881 static int snd_trident_spdif_close(struct snd_pcm_substream *substream)
1882 {
1883 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1884 unsigned int temp;
1885
1886 scoped_guard(spinlock_irq, &trident->reg_lock) {
1887 // restore default SPDIF setting
1888 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
1889 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
1890 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
1891 } else {
1892 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
1893 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1894 if (trident->spdif_ctrl) {
1895 temp |= SPDIF_EN;
1896 } else {
1897 temp &= ~SPDIF_EN;
1898 }
1899 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
1900 }
1901 }
1902 trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1903 snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
1904 SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
1905 return 0;
1906 }
1907
1908 /*---------------------------------------------------------------------------
1909 snd_trident_capture_open
1910
1911 Description: This routine will open the 4DWave capture device.
1912
1913 Parameters: substream - PCM substream class
1914
1915 Returns: status - success or failure flag
1916
1917 ---------------------------------------------------------------------------*/
1918
snd_trident_capture_open(struct snd_pcm_substream * substream)1919 static int snd_trident_capture_open(struct snd_pcm_substream *substream)
1920 {
1921 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1922 struct snd_trident_voice *voice;
1923 struct snd_pcm_runtime *runtime = substream->runtime;
1924
1925 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1926 if (voice == NULL)
1927 return -EAGAIN;
1928 voice->capture = 1;
1929 voice->substream = substream;
1930 runtime->private_data = voice;
1931 runtime->private_free = snd_trident_pcm_free_substream;
1932 runtime->hw = snd_trident_capture;
1933 snd_pcm_set_sync(substream);
1934 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1935 return 0;
1936 }
1937
1938 /*---------------------------------------------------------------------------
1939 snd_trident_capture_close
1940
1941 Description: This routine will close the 4DWave capture device. For now
1942 we will simply free the dma transfer buffer.
1943
1944 Parameters: substream - PCM substream class
1945
1946 ---------------------------------------------------------------------------*/
snd_trident_capture_close(struct snd_pcm_substream * substream)1947 static int snd_trident_capture_close(struct snd_pcm_substream *substream)
1948 {
1949 return 0;
1950 }
1951
1952 /*---------------------------------------------------------------------------
1953 snd_trident_foldback_open
1954
1955 Description: This routine will open the 4DWave foldback capture device.
1956
1957 Parameters: substream - PCM substream class
1958
1959 Returns: status - success or failure flag
1960
1961 ---------------------------------------------------------------------------*/
1962
snd_trident_foldback_open(struct snd_pcm_substream * substream)1963 static int snd_trident_foldback_open(struct snd_pcm_substream *substream)
1964 {
1965 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1966 struct snd_trident_voice *voice;
1967 struct snd_pcm_runtime *runtime = substream->runtime;
1968
1969 voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
1970 if (voice == NULL)
1971 return -EAGAIN;
1972 voice->foldback_chan = substream->number;
1973 voice->substream = substream;
1974 runtime->private_data = voice;
1975 runtime->private_free = snd_trident_pcm_free_substream;
1976 runtime->hw = snd_trident_foldback;
1977 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
1978 return 0;
1979 }
1980
1981 /*---------------------------------------------------------------------------
1982 snd_trident_foldback_close
1983
1984 Description: This routine will close the 4DWave foldback capture device.
1985 For now we will simply free the dma transfer buffer.
1986
1987 Parameters: substream - PCM substream class
1988
1989 ---------------------------------------------------------------------------*/
snd_trident_foldback_close(struct snd_pcm_substream * substream)1990 static int snd_trident_foldback_close(struct snd_pcm_substream *substream)
1991 {
1992 struct snd_trident *trident = snd_pcm_substream_chip(substream);
1993 struct snd_trident_voice *voice;
1994 struct snd_pcm_runtime *runtime = substream->runtime;
1995 voice = runtime->private_data;
1996
1997 /* stop capture channel */
1998 guard(spinlock_irq)(&trident->reg_lock);
1999 outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan));
2000 return 0;
2001 }
2002
2003 /*---------------------------------------------------------------------------
2004 PCM operations
2005 ---------------------------------------------------------------------------*/
2006
2007 static const struct snd_pcm_ops snd_trident_playback_ops = {
2008 .open = snd_trident_playback_open,
2009 .close = snd_trident_playback_close,
2010 .hw_params = snd_trident_hw_params,
2011 .hw_free = snd_trident_hw_free,
2012 .prepare = snd_trident_playback_prepare,
2013 .trigger = snd_trident_trigger,
2014 .pointer = snd_trident_playback_pointer,
2015 };
2016
2017 static const struct snd_pcm_ops snd_trident_nx_playback_ops = {
2018 .open = snd_trident_playback_open,
2019 .close = snd_trident_playback_close,
2020 .hw_params = snd_trident_hw_params,
2021 .hw_free = snd_trident_hw_free,
2022 .prepare = snd_trident_playback_prepare,
2023 .trigger = snd_trident_trigger,
2024 .pointer = snd_trident_playback_pointer,
2025 };
2026
2027 static const struct snd_pcm_ops snd_trident_capture_ops = {
2028 .open = snd_trident_capture_open,
2029 .close = snd_trident_capture_close,
2030 .hw_params = snd_trident_capture_hw_params,
2031 .hw_free = snd_trident_hw_free,
2032 .prepare = snd_trident_capture_prepare,
2033 .trigger = snd_trident_trigger,
2034 .pointer = snd_trident_capture_pointer,
2035 };
2036
2037 static const struct snd_pcm_ops snd_trident_si7018_capture_ops = {
2038 .open = snd_trident_capture_open,
2039 .close = snd_trident_capture_close,
2040 .hw_params = snd_trident_si7018_capture_hw_params,
2041 .hw_free = snd_trident_si7018_capture_hw_free,
2042 .prepare = snd_trident_si7018_capture_prepare,
2043 .trigger = snd_trident_trigger,
2044 .pointer = snd_trident_playback_pointer,
2045 };
2046
2047 static const struct snd_pcm_ops snd_trident_foldback_ops = {
2048 .open = snd_trident_foldback_open,
2049 .close = snd_trident_foldback_close,
2050 .hw_params = snd_trident_hw_params,
2051 .hw_free = snd_trident_hw_free,
2052 .prepare = snd_trident_foldback_prepare,
2053 .trigger = snd_trident_trigger,
2054 .pointer = snd_trident_playback_pointer,
2055 };
2056
2057 static const struct snd_pcm_ops snd_trident_nx_foldback_ops = {
2058 .open = snd_trident_foldback_open,
2059 .close = snd_trident_foldback_close,
2060 .hw_params = snd_trident_hw_params,
2061 .hw_free = snd_trident_hw_free,
2062 .prepare = snd_trident_foldback_prepare,
2063 .trigger = snd_trident_trigger,
2064 .pointer = snd_trident_playback_pointer,
2065 };
2066
2067 static const struct snd_pcm_ops snd_trident_spdif_ops = {
2068 .open = snd_trident_spdif_open,
2069 .close = snd_trident_spdif_close,
2070 .hw_params = snd_trident_spdif_hw_params,
2071 .hw_free = snd_trident_hw_free,
2072 .prepare = snd_trident_spdif_prepare,
2073 .trigger = snd_trident_trigger,
2074 .pointer = snd_trident_spdif_pointer,
2075 };
2076
2077 static const struct snd_pcm_ops snd_trident_spdif_7018_ops = {
2078 .open = snd_trident_spdif_open,
2079 .close = snd_trident_spdif_close,
2080 .hw_params = snd_trident_spdif_hw_params,
2081 .hw_free = snd_trident_hw_free,
2082 .prepare = snd_trident_spdif_prepare,
2083 .trigger = snd_trident_trigger,
2084 .pointer = snd_trident_playback_pointer,
2085 };
2086
2087 /*---------------------------------------------------------------------------
2088 snd_trident_pcm
2089
2090 Description: This routine registers the 4DWave device for PCM support.
2091
2092 Parameters: trident - pointer to target device class for 4DWave.
2093
2094 Returns: None
2095
2096 ---------------------------------------------------------------------------*/
2097
snd_trident_pcm(struct snd_trident * trident,int device)2098 int snd_trident_pcm(struct snd_trident *trident, int device)
2099 {
2100 struct snd_pcm *pcm;
2101 int err;
2102
2103 err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm);
2104 if (err < 0)
2105 return err;
2106
2107 pcm->private_data = trident;
2108
2109 if (trident->tlb.entries) {
2110 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
2111 } else {
2112 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
2113 }
2114 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
2115 trident->device != TRIDENT_DEVICE_ID_SI7018 ?
2116 &snd_trident_capture_ops :
2117 &snd_trident_si7018_capture_ops);
2118
2119 pcm->info_flags = 0;
2120 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
2121 strscpy(pcm->name, "Trident 4DWave");
2122 trident->pcm = pcm;
2123
2124 if (trident->tlb.entries) {
2125 struct snd_pcm_substream *substream;
2126 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
2127 snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_SG,
2128 &trident->pci->dev,
2129 64*1024, 128*1024);
2130 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
2131 SNDRV_DMA_TYPE_DEV,
2132 &trident->pci->dev,
2133 64*1024, 128*1024);
2134 } else {
2135 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
2136 &trident->pci->dev,
2137 64*1024, 128*1024);
2138 }
2139
2140 return 0;
2141 }
2142
2143 /*---------------------------------------------------------------------------
2144 snd_trident_foldback_pcm
2145
2146 Description: This routine registers the 4DWave device for foldback PCM support.
2147
2148 Parameters: trident - pointer to target device class for 4DWave.
2149
2150 Returns: None
2151
2152 ---------------------------------------------------------------------------*/
2153
snd_trident_foldback_pcm(struct snd_trident * trident,int device)2154 int snd_trident_foldback_pcm(struct snd_trident *trident, int device)
2155 {
2156 struct snd_pcm *foldback;
2157 int err;
2158 int num_chan = 3;
2159 struct snd_pcm_substream *substream;
2160
2161 if (trident->device == TRIDENT_DEVICE_ID_NX)
2162 num_chan = 4;
2163 err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback);
2164 if (err < 0)
2165 return err;
2166
2167 foldback->private_data = trident;
2168 if (trident->tlb.entries)
2169 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
2170 else
2171 snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
2172 foldback->info_flags = 0;
2173 strscpy(foldback->name, "Trident 4DWave");
2174 substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
2175 strscpy(substream->name, "Front Mixer");
2176 substream = substream->next;
2177 strscpy(substream->name, "Reverb Mixer");
2178 substream = substream->next;
2179 strscpy(substream->name, "Chorus Mixer");
2180 if (num_chan == 4) {
2181 substream = substream->next;
2182 strscpy(substream->name, "Second AC'97 ADC");
2183 }
2184 trident->foldback = foldback;
2185
2186 if (trident->tlb.entries)
2187 snd_pcm_set_managed_buffer_all(foldback, SNDRV_DMA_TYPE_DEV_SG,
2188 &trident->pci->dev,
2189 0, 128*1024);
2190 else
2191 snd_pcm_set_managed_buffer_all(foldback, SNDRV_DMA_TYPE_DEV,
2192 &trident->pci->dev,
2193 64*1024, 128*1024);
2194
2195 return 0;
2196 }
2197
2198 /*---------------------------------------------------------------------------
2199 snd_trident_spdif
2200
2201 Description: This routine registers the 4DWave-NX device for SPDIF support.
2202
2203 Parameters: trident - pointer to target device class for 4DWave-NX.
2204
2205 Returns: None
2206
2207 ---------------------------------------------------------------------------*/
2208
snd_trident_spdif_pcm(struct snd_trident * trident,int device)2209 int snd_trident_spdif_pcm(struct snd_trident *trident, int device)
2210 {
2211 struct snd_pcm *spdif;
2212 int err;
2213
2214 err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif);
2215 if (err < 0)
2216 return err;
2217
2218 spdif->private_data = trident;
2219 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2220 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
2221 } else {
2222 snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
2223 }
2224 spdif->info_flags = 0;
2225 strscpy(spdif->name, "Trident 4DWave IEC958");
2226 trident->spdif = spdif;
2227
2228 snd_pcm_set_managed_buffer_all(spdif, SNDRV_DMA_TYPE_DEV,
2229 &trident->pci->dev, 64*1024, 128*1024);
2230
2231 return 0;
2232 }
2233
2234 /*
2235 * Mixer part
2236 */
2237
2238
2239 /*---------------------------------------------------------------------------
2240 snd_trident_spdif_control
2241
2242 Description: enable/disable S/PDIF out from ac97 mixer
2243 ---------------------------------------------------------------------------*/
2244
2245 #define snd_trident_spdif_control_info snd_ctl_boolean_mono_info
2246
snd_trident_spdif_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2247 static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
2248 struct snd_ctl_elem_value *ucontrol)
2249 {
2250 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2251 unsigned char val;
2252
2253 guard(spinlock_irq)(&trident->reg_lock);
2254 val = trident->spdif_ctrl;
2255 ucontrol->value.integer.value[0] = val == kcontrol->private_value;
2256 return 0;
2257 }
2258
snd_trident_spdif_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2259 static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
2260 struct snd_ctl_elem_value *ucontrol)
2261 {
2262 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2263 unsigned char val;
2264 int change;
2265
2266 val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00;
2267 guard(spinlock_irq)(&trident->reg_lock);
2268 /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
2269 change = trident->spdif_ctrl != val;
2270 trident->spdif_ctrl = val;
2271 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2272 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) {
2273 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2274 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
2275 }
2276 } else {
2277 if (trident->spdif == NULL) {
2278 unsigned int temp;
2279 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2280 temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN;
2281 if (val)
2282 temp |= SPDIF_EN;
2283 outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
2284 }
2285 }
2286 return change;
2287 }
2288
2289 static const struct snd_kcontrol_new snd_trident_spdif_control =
2290 {
2291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2292 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
2293 .info = snd_trident_spdif_control_info,
2294 .get = snd_trident_spdif_control_get,
2295 .put = snd_trident_spdif_control_put,
2296 .private_value = 0x28,
2297 };
2298
2299 /*---------------------------------------------------------------------------
2300 snd_trident_spdif_default
2301
2302 Description: put/get the S/PDIF default settings
2303 ---------------------------------------------------------------------------*/
2304
snd_trident_spdif_default_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2305 static int snd_trident_spdif_default_info(struct snd_kcontrol *kcontrol,
2306 struct snd_ctl_elem_info *uinfo)
2307 {
2308 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2309 uinfo->count = 1;
2310 return 0;
2311 }
2312
snd_trident_spdif_default_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2313 static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol,
2314 struct snd_ctl_elem_value *ucontrol)
2315 {
2316 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2317
2318 guard(spinlock_irq)(&trident->reg_lock);
2319 ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
2320 ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff;
2321 ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff;
2322 ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff;
2323 return 0;
2324 }
2325
snd_trident_spdif_default_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2326 static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
2327 struct snd_ctl_elem_value *ucontrol)
2328 {
2329 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2330 unsigned int val;
2331 int change;
2332
2333 val = (ucontrol->value.iec958.status[0] << 0) |
2334 (ucontrol->value.iec958.status[1] << 8) |
2335 (ucontrol->value.iec958.status[2] << 16) |
2336 (ucontrol->value.iec958.status[3] << 24);
2337 guard(spinlock_irq)(&trident->reg_lock);
2338 change = trident->spdif_bits != val;
2339 trident->spdif_bits = val;
2340 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2341 if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0)
2342 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
2343 } else {
2344 if (trident->spdif == NULL)
2345 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2346 }
2347 return change;
2348 }
2349
2350 static const struct snd_kcontrol_new snd_trident_spdif_default =
2351 {
2352 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2353 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2354 .info = snd_trident_spdif_default_info,
2355 .get = snd_trident_spdif_default_get,
2356 .put = snd_trident_spdif_default_put
2357 };
2358
2359 /*---------------------------------------------------------------------------
2360 snd_trident_spdif_mask
2361
2362 Description: put/get the S/PDIF mask
2363 ---------------------------------------------------------------------------*/
2364
snd_trident_spdif_mask_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2365 static int snd_trident_spdif_mask_info(struct snd_kcontrol *kcontrol,
2366 struct snd_ctl_elem_info *uinfo)
2367 {
2368 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2369 uinfo->count = 1;
2370 return 0;
2371 }
2372
snd_trident_spdif_mask_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2373 static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
2374 struct snd_ctl_elem_value *ucontrol)
2375 {
2376 ucontrol->value.iec958.status[0] = 0xff;
2377 ucontrol->value.iec958.status[1] = 0xff;
2378 ucontrol->value.iec958.status[2] = 0xff;
2379 ucontrol->value.iec958.status[3] = 0xff;
2380 return 0;
2381 }
2382
2383 static const struct snd_kcontrol_new snd_trident_spdif_mask =
2384 {
2385 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2386 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2387 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2388 .info = snd_trident_spdif_mask_info,
2389 .get = snd_trident_spdif_mask_get,
2390 };
2391
2392 /*---------------------------------------------------------------------------
2393 snd_trident_spdif_stream
2394
2395 Description: put/get the S/PDIF stream settings
2396 ---------------------------------------------------------------------------*/
2397
snd_trident_spdif_stream_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2398 static int snd_trident_spdif_stream_info(struct snd_kcontrol *kcontrol,
2399 struct snd_ctl_elem_info *uinfo)
2400 {
2401 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2402 uinfo->count = 1;
2403 return 0;
2404 }
2405
snd_trident_spdif_stream_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2406 static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol,
2407 struct snd_ctl_elem_value *ucontrol)
2408 {
2409 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2410
2411 guard(spinlock_irq)(&trident->reg_lock);
2412 ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
2413 ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff;
2414 ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff;
2415 ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff;
2416 return 0;
2417 }
2418
snd_trident_spdif_stream_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2419 static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
2420 struct snd_ctl_elem_value *ucontrol)
2421 {
2422 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2423 unsigned int val;
2424 int change;
2425
2426 val = (ucontrol->value.iec958.status[0] << 0) |
2427 (ucontrol->value.iec958.status[1] << 8) |
2428 (ucontrol->value.iec958.status[2] << 16) |
2429 (ucontrol->value.iec958.status[3] << 24);
2430 guard(spinlock_irq)(&trident->reg_lock);
2431 change = trident->spdif_pcm_bits != val;
2432 trident->spdif_pcm_bits = val;
2433 if (trident->spdif != NULL) {
2434 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2435 outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
2436 } else {
2437 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
2438 }
2439 }
2440 return change;
2441 }
2442
2443 static const struct snd_kcontrol_new snd_trident_spdif_stream =
2444 {
2445 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2446 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2447 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2448 .info = snd_trident_spdif_stream_info,
2449 .get = snd_trident_spdif_stream_get,
2450 .put = snd_trident_spdif_stream_put
2451 };
2452
2453 /*---------------------------------------------------------------------------
2454 snd_trident_ac97_control
2455
2456 Description: enable/disable rear path for ac97
2457 ---------------------------------------------------------------------------*/
2458
2459 #define snd_trident_ac97_control_info snd_ctl_boolean_mono_info
2460
snd_trident_ac97_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2461 static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
2462 struct snd_ctl_elem_value *ucontrol)
2463 {
2464 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2465 unsigned char val;
2466
2467 guard(spinlock_irq)(&trident->reg_lock);
2468 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2469 ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0;
2470 return 0;
2471 }
2472
snd_trident_ac97_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2473 static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
2474 struct snd_ctl_elem_value *ucontrol)
2475 {
2476 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2477 unsigned char val;
2478 int change = 0;
2479
2480 guard(spinlock_irq)(&trident->reg_lock);
2481 val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2482 val &= ~(1 << kcontrol->private_value);
2483 if (ucontrol->value.integer.value[0])
2484 val |= 1 << kcontrol->private_value;
2485 change = val != trident->ac97_ctrl;
2486 trident->ac97_ctrl = val;
2487 outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
2488 return change;
2489 }
2490
2491 static const struct snd_kcontrol_new snd_trident_ac97_rear_control =
2492 {
2493 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2494 .name = "Rear Path",
2495 .info = snd_trident_ac97_control_info,
2496 .get = snd_trident_ac97_control_get,
2497 .put = snd_trident_ac97_control_put,
2498 .private_value = 4,
2499 };
2500
2501 /*---------------------------------------------------------------------------
2502 snd_trident_vol_control
2503
2504 Description: wave & music volume control
2505 ---------------------------------------------------------------------------*/
2506
snd_trident_vol_control_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2507 static int snd_trident_vol_control_info(struct snd_kcontrol *kcontrol,
2508 struct snd_ctl_elem_info *uinfo)
2509 {
2510 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2511 uinfo->count = 2;
2512 uinfo->value.integer.min = 0;
2513 uinfo->value.integer.max = 255;
2514 return 0;
2515 }
2516
snd_trident_vol_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2517 static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol,
2518 struct snd_ctl_elem_value *ucontrol)
2519 {
2520 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2521 unsigned int val;
2522
2523 val = trident->musicvol_wavevol;
2524 ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff);
2525 ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff);
2526 return 0;
2527 }
2528
2529 static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0);
2530
snd_trident_vol_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2531 static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
2532 struct snd_ctl_elem_value *ucontrol)
2533 {
2534 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2535 unsigned int val;
2536 int change = 0;
2537
2538 guard(spinlock_irq)(&trident->reg_lock);
2539 val = trident->musicvol_wavevol;
2540 val &= ~(0xffff << kcontrol->private_value);
2541 val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) |
2542 ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value;
2543 change = val != trident->musicvol_wavevol;
2544 outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
2545 return change;
2546 }
2547
2548 static const struct snd_kcontrol_new snd_trident_vol_music_control =
2549 {
2550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2551 .name = "Music Playback Volume",
2552 .info = snd_trident_vol_control_info,
2553 .get = snd_trident_vol_control_get,
2554 .put = snd_trident_vol_control_put,
2555 .private_value = 16,
2556 .tlv = { .p = db_scale_gvol },
2557 };
2558
2559 static const struct snd_kcontrol_new snd_trident_vol_wave_control =
2560 {
2561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2562 .name = "Wave Playback Volume",
2563 .info = snd_trident_vol_control_info,
2564 .get = snd_trident_vol_control_get,
2565 .put = snd_trident_vol_control_put,
2566 .private_value = 0,
2567 .tlv = { .p = db_scale_gvol },
2568 };
2569
2570 /*---------------------------------------------------------------------------
2571 snd_trident_pcm_vol_control
2572
2573 Description: PCM front volume control
2574 ---------------------------------------------------------------------------*/
2575
snd_trident_pcm_vol_control_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2576 static int snd_trident_pcm_vol_control_info(struct snd_kcontrol *kcontrol,
2577 struct snd_ctl_elem_info *uinfo)
2578 {
2579 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2580
2581 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2582 uinfo->count = 1;
2583 uinfo->value.integer.min = 0;
2584 uinfo->value.integer.max = 255;
2585 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
2586 uinfo->value.integer.max = 1023;
2587 return 0;
2588 }
2589
snd_trident_pcm_vol_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2590 static int snd_trident_pcm_vol_control_get(struct snd_kcontrol *kcontrol,
2591 struct snd_ctl_elem_value *ucontrol)
2592 {
2593 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2594 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2595
2596 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2597 ucontrol->value.integer.value[0] = 1023 - mix->vol;
2598 } else {
2599 ucontrol->value.integer.value[0] = 255 - (mix->vol>>2);
2600 }
2601 return 0;
2602 }
2603
snd_trident_pcm_vol_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2604 static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
2605 struct snd_ctl_elem_value *ucontrol)
2606 {
2607 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2608 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2609 unsigned int val;
2610 int change = 0;
2611
2612 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2613 val = 1023 - (ucontrol->value.integer.value[0] & 1023);
2614 } else {
2615 val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2;
2616 }
2617 guard(spinlock_irq)(&trident->reg_lock);
2618 change = val != mix->vol;
2619 mix->vol = val;
2620 if (mix->voice != NULL)
2621 snd_trident_write_vol_reg(trident, mix->voice, val);
2622 return change;
2623 }
2624
2625 static const struct snd_kcontrol_new snd_trident_pcm_vol_control =
2626 {
2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2628 .name = "PCM Front Playback Volume",
2629 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2630 .count = 32,
2631 .info = snd_trident_pcm_vol_control_info,
2632 .get = snd_trident_pcm_vol_control_get,
2633 .put = snd_trident_pcm_vol_control_put,
2634 /* FIXME: no tlv yet */
2635 };
2636
2637 /*---------------------------------------------------------------------------
2638 snd_trident_pcm_pan_control
2639
2640 Description: PCM front pan control
2641 ---------------------------------------------------------------------------*/
2642
snd_trident_pcm_pan_control_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2643 static int snd_trident_pcm_pan_control_info(struct snd_kcontrol *kcontrol,
2644 struct snd_ctl_elem_info *uinfo)
2645 {
2646 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2647 uinfo->count = 1;
2648 uinfo->value.integer.min = 0;
2649 uinfo->value.integer.max = 127;
2650 return 0;
2651 }
2652
snd_trident_pcm_pan_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2653 static int snd_trident_pcm_pan_control_get(struct snd_kcontrol *kcontrol,
2654 struct snd_ctl_elem_value *ucontrol)
2655 {
2656 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2657 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2658
2659 ucontrol->value.integer.value[0] = mix->pan;
2660 if (ucontrol->value.integer.value[0] & 0x40) {
2661 ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f));
2662 } else {
2663 ucontrol->value.integer.value[0] |= 0x40;
2664 }
2665 return 0;
2666 }
2667
snd_trident_pcm_pan_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2668 static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
2669 struct snd_ctl_elem_value *ucontrol)
2670 {
2671 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2672 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2673 unsigned char val;
2674 int change = 0;
2675
2676 if (ucontrol->value.integer.value[0] & 0x40)
2677 val = ucontrol->value.integer.value[0] & 0x3f;
2678 else
2679 val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40;
2680 guard(spinlock_irq)(&trident->reg_lock);
2681 change = val != mix->pan;
2682 mix->pan = val;
2683 if (mix->voice != NULL)
2684 snd_trident_write_pan_reg(trident, mix->voice, val);
2685 return change;
2686 }
2687
2688 static const struct snd_kcontrol_new snd_trident_pcm_pan_control =
2689 {
2690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2691 .name = "PCM Pan Playback Control",
2692 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2693 .count = 32,
2694 .info = snd_trident_pcm_pan_control_info,
2695 .get = snd_trident_pcm_pan_control_get,
2696 .put = snd_trident_pcm_pan_control_put,
2697 };
2698
2699 /*---------------------------------------------------------------------------
2700 snd_trident_pcm_rvol_control
2701
2702 Description: PCM reverb volume control
2703 ---------------------------------------------------------------------------*/
2704
snd_trident_pcm_rvol_control_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2705 static int snd_trident_pcm_rvol_control_info(struct snd_kcontrol *kcontrol,
2706 struct snd_ctl_elem_info *uinfo)
2707 {
2708 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2709 uinfo->count = 1;
2710 uinfo->value.integer.min = 0;
2711 uinfo->value.integer.max = 127;
2712 return 0;
2713 }
2714
snd_trident_pcm_rvol_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2715 static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol *kcontrol,
2716 struct snd_ctl_elem_value *ucontrol)
2717 {
2718 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2719 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2720
2721 ucontrol->value.integer.value[0] = 127 - mix->rvol;
2722 return 0;
2723 }
2724
snd_trident_pcm_rvol_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2725 static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
2726 struct snd_ctl_elem_value *ucontrol)
2727 {
2728 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2729 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2730 unsigned short val;
2731 int change = 0;
2732
2733 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2734 guard(spinlock_irq)(&trident->reg_lock);
2735 change = val != mix->rvol;
2736 mix->rvol = val;
2737 if (mix->voice != NULL)
2738 snd_trident_write_rvol_reg(trident, mix->voice, val);
2739 return change;
2740 }
2741
2742 static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
2743
2744 static const struct snd_kcontrol_new snd_trident_pcm_rvol_control =
2745 {
2746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2747 .name = "PCM Reverb Playback Volume",
2748 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2749 .count = 32,
2750 .info = snd_trident_pcm_rvol_control_info,
2751 .get = snd_trident_pcm_rvol_control_get,
2752 .put = snd_trident_pcm_rvol_control_put,
2753 .tlv = { .p = db_scale_crvol },
2754 };
2755
2756 /*---------------------------------------------------------------------------
2757 snd_trident_pcm_cvol_control
2758
2759 Description: PCM chorus volume control
2760 ---------------------------------------------------------------------------*/
2761
snd_trident_pcm_cvol_control_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2762 static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol *kcontrol,
2763 struct snd_ctl_elem_info *uinfo)
2764 {
2765 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2766 uinfo->count = 1;
2767 uinfo->value.integer.min = 0;
2768 uinfo->value.integer.max = 127;
2769 return 0;
2770 }
2771
snd_trident_pcm_cvol_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2772 static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol *kcontrol,
2773 struct snd_ctl_elem_value *ucontrol)
2774 {
2775 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2776 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2777
2778 ucontrol->value.integer.value[0] = 127 - mix->cvol;
2779 return 0;
2780 }
2781
snd_trident_pcm_cvol_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2782 static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
2783 struct snd_ctl_elem_value *ucontrol)
2784 {
2785 struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
2786 struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
2787 unsigned short val;
2788 int change = 0;
2789
2790 val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
2791 guard(spinlock_irq)(&trident->reg_lock);
2792 change = val != mix->cvol;
2793 mix->cvol = val;
2794 if (mix->voice != NULL)
2795 snd_trident_write_cvol_reg(trident, mix->voice, val);
2796 return change;
2797 }
2798
2799 static const struct snd_kcontrol_new snd_trident_pcm_cvol_control =
2800 {
2801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2802 .name = "PCM Chorus Playback Volume",
2803 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2804 .count = 32,
2805 .info = snd_trident_pcm_cvol_control_info,
2806 .get = snd_trident_pcm_cvol_control_get,
2807 .put = snd_trident_pcm_cvol_control_put,
2808 .tlv = { .p = db_scale_crvol },
2809 };
2810
snd_trident_notify_pcm_change1(struct snd_card * card,struct snd_kcontrol * kctl,int num,int activate)2811 static void snd_trident_notify_pcm_change1(struct snd_card *card,
2812 struct snd_kcontrol *kctl,
2813 int num, int activate)
2814 {
2815 struct snd_ctl_elem_id id;
2816
2817 if (! kctl)
2818 return;
2819 if (activate)
2820 kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2821 else
2822 kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
2823 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
2824 SNDRV_CTL_EVENT_MASK_INFO,
2825 snd_ctl_build_ioff(&id, kctl, num));
2826 }
2827
snd_trident_notify_pcm_change(struct snd_trident * trident,struct snd_trident_pcm_mixer * tmix,int num,int activate)2828 static void snd_trident_notify_pcm_change(struct snd_trident *trident,
2829 struct snd_trident_pcm_mixer *tmix,
2830 int num, int activate)
2831 {
2832 snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
2833 snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
2834 snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate);
2835 snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
2836 }
2837
snd_trident_pcm_mixer_build(struct snd_trident * trident,struct snd_trident_voice * voice,struct snd_pcm_substream * substream)2838 static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
2839 struct snd_trident_voice *voice,
2840 struct snd_pcm_substream *substream)
2841 {
2842 struct snd_trident_pcm_mixer *tmix;
2843
2844 if (snd_BUG_ON(!trident || !voice || !substream))
2845 return -EINVAL;
2846 tmix = &trident->pcm_mixer[substream->number];
2847 tmix->voice = voice;
2848 tmix->vol = T4D_DEFAULT_PCM_VOL;
2849 tmix->pan = T4D_DEFAULT_PCM_PAN;
2850 tmix->rvol = T4D_DEFAULT_PCM_RVOL;
2851 tmix->cvol = T4D_DEFAULT_PCM_CVOL;
2852 snd_trident_notify_pcm_change(trident, tmix, substream->number, 1);
2853 return 0;
2854 }
2855
snd_trident_pcm_mixer_free(struct snd_trident * trident,struct snd_trident_voice * voice,struct snd_pcm_substream * substream)2856 static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream)
2857 {
2858 struct snd_trident_pcm_mixer *tmix;
2859
2860 if (snd_BUG_ON(!trident || !substream))
2861 return -EINVAL;
2862 tmix = &trident->pcm_mixer[substream->number];
2863 tmix->voice = NULL;
2864 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
2865 return 0;
2866 }
2867
2868 /*---------------------------------------------------------------------------
2869 snd_trident_mixer
2870
2871 Description: This routine registers the 4DWave device for mixer support.
2872
2873 Parameters: trident - pointer to target device class for 4DWave.
2874
2875 Returns: None
2876
2877 ---------------------------------------------------------------------------*/
2878
snd_trident_mixer(struct snd_trident * trident,int pcm_spdif_device)2879 static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
2880 {
2881 struct snd_ac97_template _ac97;
2882 struct snd_card *card = trident->card;
2883 struct snd_kcontrol *kctl;
2884 struct snd_ctl_elem_value *uctl;
2885 int idx, err, retries = 2;
2886 static const struct snd_ac97_bus_ops ops = {
2887 .write = snd_trident_codec_write,
2888 .read = snd_trident_codec_read,
2889 };
2890
2891 uctl = kzalloc_obj(*uctl);
2892 if (!uctl)
2893 return -ENOMEM;
2894
2895 err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus);
2896 if (err < 0)
2897 goto __out;
2898
2899 memset(&_ac97, 0, sizeof(_ac97));
2900 _ac97.private_data = trident;
2901 trident->ac97_detect = 1;
2902
2903 __again:
2904 err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97);
2905 if (err < 0) {
2906 if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
2907 err = snd_trident_sis_reset(trident);
2908 if (err < 0)
2909 goto __out;
2910 if (retries-- > 0)
2911 goto __again;
2912 err = -EIO;
2913 }
2914 goto __out;
2915 }
2916
2917 /* secondary codec? */
2918 if (trident->device == TRIDENT_DEVICE_ID_SI7018 &&
2919 (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) {
2920 _ac97.num = 1;
2921 err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
2922 if (err < 0)
2923 dev_err(trident->card->dev,
2924 "SI7018: the secondary codec - invalid access\n");
2925 #if 0 // only for my testing purpose --jk
2926 {
2927 struct snd_ac97 *mc97;
2928 err = snd_ac97_modem(trident->card, &_ac97, &mc97);
2929 if (err < 0)
2930 dev_err(trident->card->dev,
2931 "snd_ac97_modem returned error %i\n", err);
2932 }
2933 #endif
2934 }
2935
2936 trident->ac97_detect = 0;
2937
2938 if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
2939 kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident);
2940 err = snd_ctl_add(card, kctl);
2941 if (err < 0)
2942 goto __out;
2943 kctl->put(kctl, uctl);
2944 kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident);
2945 err = snd_ctl_add(card, kctl);
2946 if (err < 0)
2947 goto __out;
2948 kctl->put(kctl, uctl);
2949 outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
2950 } else {
2951 outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
2952 }
2953
2954 for (idx = 0; idx < 32; idx++) {
2955 struct snd_trident_pcm_mixer *tmix;
2956
2957 tmix = &trident->pcm_mixer[idx];
2958 tmix->voice = NULL;
2959 }
2960 trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident);
2961 if (!trident->ctl_vol)
2962 goto __nomem;
2963 err = snd_ctl_add(card, trident->ctl_vol);
2964 if (err)
2965 goto __out;
2966
2967 trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident);
2968 if (!trident->ctl_pan)
2969 goto __nomem;
2970 err = snd_ctl_add(card, trident->ctl_pan);
2971 if (err)
2972 goto __out;
2973
2974 trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident);
2975 if (!trident->ctl_rvol)
2976 goto __nomem;
2977 err = snd_ctl_add(card, trident->ctl_rvol);
2978 if (err)
2979 goto __out;
2980
2981 trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident);
2982 if (!trident->ctl_cvol)
2983 goto __nomem;
2984 err = snd_ctl_add(card, trident->ctl_cvol);
2985 if (err)
2986 goto __out;
2987
2988 if (trident->device == TRIDENT_DEVICE_ID_NX) {
2989 kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident);
2990 err = snd_ctl_add(card, kctl);
2991 if (err < 0)
2992 goto __out;
2993 kctl->put(kctl, uctl);
2994 }
2995 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
2996
2997 kctl = snd_ctl_new1(&snd_trident_spdif_control, trident);
2998 if (kctl == NULL) {
2999 err = -ENOMEM;
3000 goto __out;
3001 }
3002 if (trident->ac97->ext_id & AC97_EI_SPDIF)
3003 kctl->id.index++;
3004 if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
3005 kctl->id.index++;
3006 idx = kctl->id.index;
3007 err = snd_ctl_add(card, kctl);
3008 if (err < 0)
3009 goto __out;
3010 kctl->put(kctl, uctl);
3011
3012 kctl = snd_ctl_new1(&snd_trident_spdif_default, trident);
3013 if (kctl == NULL) {
3014 err = -ENOMEM;
3015 goto __out;
3016 }
3017 kctl->id.index = idx;
3018 kctl->id.device = pcm_spdif_device;
3019 err = snd_ctl_add(card, kctl);
3020 if (err < 0)
3021 goto __out;
3022
3023 kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident);
3024 if (kctl == NULL) {
3025 err = -ENOMEM;
3026 goto __out;
3027 }
3028 kctl->id.index = idx;
3029 kctl->id.device = pcm_spdif_device;
3030 err = snd_ctl_add(card, kctl);
3031 if (err < 0)
3032 goto __out;
3033
3034 kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident);
3035 if (kctl == NULL) {
3036 err = -ENOMEM;
3037 goto __out;
3038 }
3039 kctl->id.index = idx;
3040 kctl->id.device = pcm_spdif_device;
3041 err = snd_ctl_add(card, kctl);
3042 if (err < 0)
3043 goto __out;
3044 trident->spdif_pcm_ctl = kctl;
3045 }
3046
3047 err = 0;
3048 goto __out;
3049
3050 __nomem:
3051 err = -ENOMEM;
3052
3053 __out:
3054 kfree(uctl);
3055
3056 return err;
3057 }
3058
3059 /*
3060 * gameport interface
3061 */
3062
3063 #if IS_REACHABLE(CONFIG_GAMEPORT)
3064
snd_trident_gameport_read(struct gameport * gameport)3065 static unsigned char snd_trident_gameport_read(struct gameport *gameport)
3066 {
3067 struct snd_trident *chip = gameport_get_port_data(gameport);
3068
3069 if (snd_BUG_ON(!chip))
3070 return 0;
3071 return inb(TRID_REG(chip, GAMEPORT_LEGACY));
3072 }
3073
snd_trident_gameport_trigger(struct gameport * gameport)3074 static void snd_trident_gameport_trigger(struct gameport *gameport)
3075 {
3076 struct snd_trident *chip = gameport_get_port_data(gameport);
3077
3078 if (snd_BUG_ON(!chip))
3079 return;
3080 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
3081 }
3082
snd_trident_gameport_cooked_read(struct gameport * gameport,int * axes,int * buttons)3083 static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
3084 {
3085 struct snd_trident *chip = gameport_get_port_data(gameport);
3086 int i;
3087
3088 if (snd_BUG_ON(!chip))
3089 return 0;
3090
3091 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
3092
3093 for (i = 0; i < 4; i++) {
3094 axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2));
3095 if (axes[i] == 0xffff) axes[i] = -1;
3096 }
3097
3098 return 0;
3099 }
3100
snd_trident_gameport_open(struct gameport * gameport,int mode)3101 static int snd_trident_gameport_open(struct gameport *gameport, int mode)
3102 {
3103 struct snd_trident *chip = gameport_get_port_data(gameport);
3104
3105 if (snd_BUG_ON(!chip))
3106 return 0;
3107
3108 switch (mode) {
3109 case GAMEPORT_MODE_COOKED:
3110 outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
3111 msleep(20);
3112 return 0;
3113 case GAMEPORT_MODE_RAW:
3114 outb(0, TRID_REG(chip, GAMEPORT_GCR));
3115 return 0;
3116 default:
3117 return -1;
3118 }
3119 }
3120
snd_trident_create_gameport(struct snd_trident * chip)3121 int snd_trident_create_gameport(struct snd_trident *chip)
3122 {
3123 struct gameport *gp;
3124
3125 chip->gameport = gp = gameport_allocate_port();
3126 if (!gp) {
3127 dev_err(chip->card->dev,
3128 "cannot allocate memory for gameport\n");
3129 return -ENOMEM;
3130 }
3131
3132 gameport_set_name(gp, "Trident 4DWave");
3133 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
3134 gameport_set_dev_parent(gp, &chip->pci->dev);
3135
3136 gameport_set_port_data(gp, chip);
3137 gp->fuzz = 64;
3138 gp->read = snd_trident_gameport_read;
3139 gp->trigger = snd_trident_gameport_trigger;
3140 gp->cooked_read = snd_trident_gameport_cooked_read;
3141 gp->open = snd_trident_gameport_open;
3142
3143 gameport_register_port(gp);
3144
3145 return 0;
3146 }
3147
snd_trident_free_gameport(struct snd_trident * chip)3148 static inline void snd_trident_free_gameport(struct snd_trident *chip)
3149 {
3150 if (chip->gameport) {
3151 gameport_unregister_port(chip->gameport);
3152 chip->gameport = NULL;
3153 }
3154 }
3155 #else
snd_trident_create_gameport(struct snd_trident * chip)3156 int snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
snd_trident_free_gameport(struct snd_trident * chip)3157 static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
3158 #endif /* CONFIG_GAMEPORT */
3159
3160 /*
3161 * delay for 1 tick
3162 */
do_delay(struct snd_trident * chip)3163 static inline void do_delay(struct snd_trident *chip)
3164 {
3165 schedule_timeout_uninterruptible(1);
3166 }
3167
3168 /*
3169 * SiS reset routine
3170 */
3171
snd_trident_sis_reset(struct snd_trident * trident)3172 static int snd_trident_sis_reset(struct snd_trident *trident)
3173 {
3174 unsigned long end_time;
3175 unsigned int i;
3176 int r;
3177
3178 r = trident->in_suspend ? 0 : 2; /* count of retries */
3179 __si7018_retry:
3180 pci_write_config_byte(trident->pci, 0x46, 0x04); /* SOFTWARE RESET */
3181 udelay(100);
3182 pci_write_config_byte(trident->pci, 0x46, 0x00);
3183 udelay(100);
3184 /* disable AC97 GPIO interrupt */
3185 outb(0x00, TRID_REG(trident, SI_AC97_GPIO));
3186 /* initialize serial interface, force cold reset */
3187 i = PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID|COLD_RESET;
3188 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3189 udelay(1000);
3190 /* remove cold reset */
3191 i &= ~COLD_RESET;
3192 outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3193 udelay(2000);
3194 /* wait, until the codec is ready */
3195 end_time = (jiffies + (HZ * 3) / 4) + 1;
3196 do {
3197 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0)
3198 goto __si7018_ok;
3199 do_delay(trident);
3200 } while (time_after_eq(end_time, jiffies));
3201 dev_err(trident->card->dev, "AC'97 codec ready error [0x%x]\n",
3202 inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
3203 if (r-- > 0) {
3204 end_time = jiffies + HZ;
3205 do {
3206 do_delay(trident);
3207 } while (time_after_eq(end_time, jiffies));
3208 goto __si7018_retry;
3209 }
3210 __si7018_ok:
3211 /* wait for the second codec */
3212 do {
3213 if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0)
3214 break;
3215 do_delay(trident);
3216 } while (time_after_eq(end_time, jiffies));
3217 /* enable 64 channel mode */
3218 outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR));
3219 return 0;
3220 }
3221
3222 /*
3223 * /proc interface
3224 */
3225
snd_trident_proc_read(struct snd_info_entry * entry,struct snd_info_buffer * buffer)3226 static void snd_trident_proc_read(struct snd_info_entry *entry,
3227 struct snd_info_buffer *buffer)
3228 {
3229 struct snd_trident *trident = entry->private_data;
3230 char *s;
3231
3232 switch (trident->device) {
3233 case TRIDENT_DEVICE_ID_SI7018:
3234 s = "SiS 7018 Audio";
3235 break;
3236 case TRIDENT_DEVICE_ID_DX:
3237 s = "Trident 4DWave PCI DX";
3238 break;
3239 case TRIDENT_DEVICE_ID_NX:
3240 s = "Trident 4DWave PCI NX";
3241 break;
3242 default:
3243 s = "???";
3244 }
3245 snd_iprintf(buffer, "%s\n\n", s);
3246 snd_iprintf(buffer, "Spurious IRQs : %d\n", trident->spurious_irq_count);
3247 snd_iprintf(buffer, "Spurious IRQ dlta: %d\n", trident->spurious_irq_max_delta);
3248 if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018)
3249 snd_iprintf(buffer, "IEC958 Mixer Out : %s\n", str_on_off(trident->spdif_ctrl == 0x28));
3250 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3251 snd_iprintf(buffer, "Rear Speakers : %s\n", str_on_off(trident->ac97_ctrl & 0x00000010));
3252 if (trident->tlb.entries) {
3253 snd_iprintf(buffer,"\nVirtual Memory\n");
3254 snd_iprintf(buffer, "Memory Maximum : %d\n", trident->tlb.memhdr->size);
3255 snd_iprintf(buffer, "Memory Used : %d\n", trident->tlb.memhdr->used);
3256 snd_iprintf(buffer, "Memory Free : %d\n", snd_util_mem_avail(trident->tlb.memhdr));
3257 }
3258 }
3259 }
3260
snd_trident_proc_init(struct snd_trident * trident)3261 static void snd_trident_proc_init(struct snd_trident *trident)
3262 {
3263 const char *s = "trident";
3264
3265 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
3266 s = "sis7018";
3267 snd_card_ro_proc_new(trident->card, s, trident, snd_trident_proc_read);
3268 }
3269
3270 /*---------------------------------------------------------------------------
3271 snd_trident_tlb_alloc
3272
3273 Description: Allocate and set up the TLB page table on 4D NX.
3274 Each entry has 4 bytes (physical PCI address).
3275
3276 Parameters: trident - pointer to target device class for 4DWave.
3277
3278 Returns: 0 or negative error code
3279
3280 ---------------------------------------------------------------------------*/
3281
snd_trident_tlb_alloc(struct snd_trident * trident)3282 static int snd_trident_tlb_alloc(struct snd_trident *trident)
3283 {
3284 int i;
3285
3286 /* TLB array must be aligned to 16kB !!! so we allocate
3287 32kB region and correct offset when necessary */
3288
3289 trident->tlb.buffer =
3290 snd_devm_alloc_pages(&trident->pci->dev, SNDRV_DMA_TYPE_DEV,
3291 2 * SNDRV_TRIDENT_MAX_PAGES * 4);
3292 if (!trident->tlb.buffer) {
3293 dev_err(trident->card->dev, "unable to allocate TLB buffer\n");
3294 return -ENOMEM;
3295 }
3296 trident->tlb.entries = (__le32 *)ALIGN((unsigned long)trident->tlb.buffer->area, SNDRV_TRIDENT_MAX_PAGES * 4);
3297 trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer->addr, SNDRV_TRIDENT_MAX_PAGES * 4);
3298
3299 /* allocate and setup silent page and initialise TLB entries */
3300 trident->tlb.silent_page =
3301 snd_devm_alloc_pages(&trident->pci->dev, SNDRV_DMA_TYPE_DEV,
3302 SNDRV_TRIDENT_PAGE_SIZE);
3303 if (!trident->tlb.silent_page) {
3304 dev_err(trident->card->dev, "unable to allocate silent page\n");
3305 return -ENOMEM;
3306 }
3307 memset(trident->tlb.silent_page->area, 0, SNDRV_TRIDENT_PAGE_SIZE);
3308 for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++)
3309 trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page->addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
3310
3311 /* use emu memory block manager code to manage tlb page allocation */
3312 trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
3313 if (trident->tlb.memhdr == NULL)
3314 return -ENOMEM;
3315
3316 trident->tlb.memhdr->block_extra_size = sizeof(struct snd_trident_memblk_arg);
3317 return 0;
3318 }
3319
3320 /*
3321 * initialize 4D DX chip
3322 */
3323
snd_trident_stop_all_voices(struct snd_trident * trident)3324 static void snd_trident_stop_all_voices(struct snd_trident *trident)
3325 {
3326 outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
3327 outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
3328 outl(0, TRID_REG(trident, T4D_AINTEN_A));
3329 outl(0, TRID_REG(trident, T4D_AINTEN_B));
3330 }
3331
snd_trident_4d_dx_init(struct snd_trident * trident)3332 static int snd_trident_4d_dx_init(struct snd_trident *trident)
3333 {
3334 struct pci_dev *pci = trident->pci;
3335 unsigned long end_time;
3336
3337 /* reset the legacy configuration and whole audio/wavetable block */
3338 pci_write_config_dword(pci, 0x40, 0); /* DDMA */
3339 pci_write_config_byte(pci, 0x44, 0); /* ports */
3340 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
3341 pci_write_config_byte(pci, 0x46, 4); /* reset */
3342 udelay(100);
3343 pci_write_config_byte(pci, 0x46, 0); /* release reset */
3344 udelay(100);
3345
3346 /* warm reset of the AC'97 codec */
3347 outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3348 udelay(100);
3349 outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3350 /* DAC on, disable SB IRQ and try to force ADC valid signal */
3351 trident->ac97_ctrl = 0x0000004a;
3352 outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
3353 /* wait, until the codec is ready */
3354 end_time = (jiffies + (HZ * 3) / 4) + 1;
3355 do {
3356 if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
3357 goto __dx_ok;
3358 do_delay(trident);
3359 } while (time_after_eq(end_time, jiffies));
3360 dev_err(trident->card->dev, "AC'97 codec ready error\n");
3361 return -EIO;
3362
3363 __dx_ok:
3364 snd_trident_stop_all_voices(trident);
3365
3366 return 0;
3367 }
3368
3369 /*
3370 * initialize 4D NX chip
3371 */
snd_trident_4d_nx_init(struct snd_trident * trident)3372 static int snd_trident_4d_nx_init(struct snd_trident *trident)
3373 {
3374 struct pci_dev *pci = trident->pci;
3375 unsigned long end_time;
3376
3377 /* reset the legacy configuration and whole audio/wavetable block */
3378 pci_write_config_dword(pci, 0x40, 0); /* DDMA */
3379 pci_write_config_byte(pci, 0x44, 0); /* ports */
3380 pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
3381
3382 pci_write_config_byte(pci, 0x46, 1); /* reset */
3383 udelay(100);
3384 pci_write_config_byte(pci, 0x46, 0); /* release reset */
3385 udelay(100);
3386
3387 /* warm reset of the AC'97 codec */
3388 outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3389 udelay(100);
3390 outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3391 /* wait, until the codec is ready */
3392 end_time = (jiffies + (HZ * 3) / 4) + 1;
3393 do {
3394 if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
3395 goto __nx_ok;
3396 do_delay(trident);
3397 } while (time_after_eq(end_time, jiffies));
3398 dev_err(trident->card->dev, "AC'97 codec ready error [0x%x]\n",
3399 inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
3400 return -EIO;
3401
3402 __nx_ok:
3403 /* DAC on */
3404 trident->ac97_ctrl = 0x00000002;
3405 outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
3406 /* disable SB IRQ */
3407 outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
3408
3409 snd_trident_stop_all_voices(trident);
3410
3411 if (trident->tlb.entries != NULL) {
3412 unsigned int i;
3413 /* enable virtual addressing via TLB */
3414 i = trident->tlb.entries_dmaaddr;
3415 i |= 0x00000001;
3416 outl(i, TRID_REG(trident, NX_TLBC));
3417 } else {
3418 outl(0, TRID_REG(trident, NX_TLBC));
3419 }
3420 /* initialize S/PDIF */
3421 outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
3422 outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3423
3424 return 0;
3425 }
3426
3427 /*
3428 * initialize sis7018 chip
3429 */
snd_trident_sis_init(struct snd_trident * trident)3430 static int snd_trident_sis_init(struct snd_trident *trident)
3431 {
3432 int err;
3433
3434 err = snd_trident_sis_reset(trident);
3435 if (err < 0)
3436 return err;
3437
3438 snd_trident_stop_all_voices(trident);
3439
3440 /* initialize S/PDIF */
3441 outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
3442
3443 return 0;
3444 }
3445
3446 /*---------------------------------------------------------------------------
3447 snd_trident_create
3448
3449 Description: This routine will create the device specific class for
3450 the 4DWave card. It will also perform basic initialization.
3451
3452 Parameters: card - which card to create
3453 pci - interface to PCI bus resource info
3454 dma1ptr - playback dma buffer
3455 dma2ptr - capture dma buffer
3456 irqptr - interrupt resource info
3457
3458 Returns: 4DWave device class private data
3459
3460 ---------------------------------------------------------------------------*/
3461
snd_trident_create(struct snd_card * card,struct pci_dev * pci,int pcm_streams,int pcm_spdif_device,int max_wavetable_size)3462 int snd_trident_create(struct snd_card *card,
3463 struct pci_dev *pci,
3464 int pcm_streams,
3465 int pcm_spdif_device,
3466 int max_wavetable_size)
3467 {
3468 struct snd_trident *trident = card->private_data;
3469 int i, err;
3470 struct snd_trident_voice *voice;
3471 struct snd_trident_pcm_mixer *tmix;
3472
3473 /* enable PCI device */
3474 err = pcim_enable_device(pci);
3475 if (err < 0)
3476 return err;
3477 /* check, if we can restrict PCI DMA transfers to 30 bits */
3478 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(30))) {
3479 dev_err(card->dev,
3480 "architecture does not support 30bit PCI busmaster DMA\n");
3481 return -ENXIO;
3482 }
3483
3484 trident->device = (pci->vendor << 16) | pci->device;
3485 trident->card = card;
3486 trident->pci = pci;
3487 spin_lock_init(&trident->reg_lock);
3488 spin_lock_init(&trident->event_lock);
3489 spin_lock_init(&trident->voice_alloc);
3490 if (pcm_streams < 1)
3491 pcm_streams = 1;
3492 if (pcm_streams > 32)
3493 pcm_streams = 32;
3494 trident->ChanPCM = pcm_streams;
3495 if (max_wavetable_size < 0 )
3496 max_wavetable_size = 0;
3497 trident->synth.max_size = max_wavetable_size * 1024;
3498 trident->irq = -1;
3499 card->private_free = snd_trident_free;
3500
3501 trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE);
3502 pci_set_master(pci);
3503
3504 err = pcim_request_all_regions(pci, "Trident Audio");
3505 if (err < 0)
3506 return err;
3507 trident->port = pci_resource_start(pci, 0);
3508
3509 if (devm_request_irq(&pci->dev, pci->irq, snd_trident_interrupt,
3510 IRQF_SHARED, KBUILD_MODNAME, trident)) {
3511 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
3512 return -EBUSY;
3513 }
3514 trident->irq = pci->irq;
3515 card->sync_irq = trident->irq;
3516
3517 /* allocate 16k-aligned TLB for NX cards */
3518 trident->tlb.entries = NULL;
3519 if (trident->device == TRIDENT_DEVICE_ID_NX) {
3520 err = snd_trident_tlb_alloc(trident);
3521 if (err < 0)
3522 return err;
3523 }
3524
3525 trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
3526
3527 /* initialize chip */
3528 switch (trident->device) {
3529 case TRIDENT_DEVICE_ID_DX:
3530 err = snd_trident_4d_dx_init(trident);
3531 break;
3532 case TRIDENT_DEVICE_ID_NX:
3533 err = snd_trident_4d_nx_init(trident);
3534 break;
3535 case TRIDENT_DEVICE_ID_SI7018:
3536 err = snd_trident_sis_init(trident);
3537 break;
3538 default:
3539 snd_BUG();
3540 break;
3541 }
3542 if (err < 0)
3543 return err;
3544
3545 err = snd_trident_mixer(trident, pcm_spdif_device);
3546 if (err < 0)
3547 return err;
3548
3549 /* initialise synth voices */
3550 for (i = 0; i < 64; i++) {
3551 voice = &trident->synth.voices[i];
3552 voice->number = i;
3553 voice->trident = trident;
3554 }
3555 /* initialize pcm mixer entries */
3556 for (i = 0; i < 32; i++) {
3557 tmix = &trident->pcm_mixer[i];
3558 tmix->vol = T4D_DEFAULT_PCM_VOL;
3559 tmix->pan = T4D_DEFAULT_PCM_PAN;
3560 tmix->rvol = T4D_DEFAULT_PCM_RVOL;
3561 tmix->cvol = T4D_DEFAULT_PCM_CVOL;
3562 }
3563
3564 snd_trident_enable_eso(trident);
3565
3566 snd_trident_proc_init(trident);
3567 return 0;
3568 }
3569
3570 /*---------------------------------------------------------------------------
3571 snd_trident_free
3572
3573 Description: This routine will free the device specific class for
3574 the 4DWave card.
3575
3576 Parameters: card - card to release
3577
3578 Returns: None.
3579
3580 ---------------------------------------------------------------------------*/
3581
snd_trident_free(struct snd_card * card)3582 static void snd_trident_free(struct snd_card *card)
3583 {
3584 struct snd_trident *trident = card->private_data;
3585
3586 snd_trident_free_gameport(trident);
3587 snd_trident_disable_eso(trident);
3588 // Disable S/PDIF out
3589 if (trident->device == TRIDENT_DEVICE_ID_NX)
3590 outb(0x00, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
3591 else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
3592 outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
3593 }
3594 if (trident->tlb.buffer) {
3595 outl(0, TRID_REG(trident, NX_TLBC));
3596 snd_util_memhdr_free(trident->tlb.memhdr);
3597 }
3598 }
3599
3600 /*---------------------------------------------------------------------------
3601 snd_trident_interrupt
3602
3603 Description: ISR for Trident 4DWave device
3604
3605 Parameters: trident - device specific private data for 4DWave card
3606
3607 Problems: It seems that Trident chips generates interrupts more than
3608 one time in special cases. The spurious interrupts are
3609 detected via sample timer (T4D_STIMER) and computing
3610 corresponding delta value. The limits are detected with
3611 the method try & fail so it is possible that it won't
3612 work on all computers. [jaroslav]
3613
3614 Returns: None.
3615
3616 ---------------------------------------------------------------------------*/
3617
snd_trident_interrupt(int irq,void * dev_id)3618 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
3619 {
3620 struct snd_trident *trident = dev_id;
3621 unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
3622 int delta;
3623 struct snd_trident_voice *voice;
3624
3625 audio_int = inl(TRID_REG(trident, T4D_MISCINT));
3626 if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
3627 return IRQ_NONE;
3628 if (audio_int & ADDRESS_IRQ) {
3629 // get interrupt status for all channels
3630 scoped_guard(spinlock, &trident->reg_lock) {
3631 stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
3632 chn_int = inl(TRID_REG(trident, T4D_AINT_A));
3633 if (chn_int)
3634 outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */
3635 chn_int = inl(TRID_REG(trident, T4D_AINT_B));
3636 if (chn_int == 0)
3637 break;
3638 for (channel = 63; channel >= 32; channel--) {
3639 mask = 1 << (channel&0x1f);
3640 if ((chn_int & mask) == 0)
3641 continue;
3642 voice = &trident->synth.voices[channel];
3643 if (!voice->pcm || voice->substream == NULL) {
3644 outl(mask, TRID_REG(trident, T4D_STOP_B));
3645 continue;
3646 }
3647 delta = (int)stimer - (int)voice->stimer;
3648 if (delta < 0)
3649 delta = -delta;
3650 if ((unsigned int)delta < voice->spurious_threshold) {
3651 /* do some statistics here */
3652 trident->spurious_irq_count++;
3653 if (trident->spurious_irq_max_delta < (unsigned int)delta)
3654 trident->spurious_irq_max_delta = delta;
3655 continue;
3656 }
3657 voice->stimer = stimer;
3658 if (voice->isync) {
3659 if (!voice->isync3) {
3660 tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
3661 if (trident->bDMAStart & 0x40)
3662 tmp >>= 1;
3663 if (tmp > 0)
3664 tmp = voice->isync_max - tmp;
3665 } else {
3666 tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
3667 }
3668 if (tmp < voice->isync_mark) {
3669 if (tmp > 0x10)
3670 tmp = voice->isync_ESO - 7;
3671 else
3672 tmp = voice->isync_ESO + 2;
3673 /* update ESO for IRQ voice to preserve sync */
3674 snd_trident_stop_voice(trident, voice->number);
3675 snd_trident_write_eso_reg(trident, voice, tmp);
3676 snd_trident_start_voice(trident, voice->number);
3677 }
3678 } else if (voice->isync2) {
3679 voice->isync2 = 0;
3680 /* write original ESO and update CSO for IRQ voice to preserve sync */
3681 snd_trident_stop_voice(trident, voice->number);
3682 snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
3683 snd_trident_write_eso_reg(trident, voice, voice->ESO);
3684 snd_trident_start_voice(trident, voice->number);
3685 }
3686 #if 0
3687 if (voice->extra) {
3688 /* update CSO for extra voice to preserve sync */
3689 snd_trident_stop_voice(trident, voice->extra->number);
3690 snd_trident_write_cso_reg(trident, voice->extra, 0);
3691 snd_trident_start_voice(trident, voice->extra->number);
3692 }
3693 #endif
3694 spin_unlock(&trident->reg_lock);
3695 snd_pcm_period_elapsed(voice->substream);
3696 spin_lock(&trident->reg_lock);
3697 }
3698 outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */
3699 }
3700 }
3701 if (audio_int & MPU401_IRQ) {
3702 if (trident->rmidi) {
3703 snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data);
3704 } else {
3705 inb(TRID_REG(trident, T4D_MPUR0));
3706 }
3707 }
3708 // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT));
3709 return IRQ_HANDLED;
3710 }
3711
snd_trident_alloc_voice(struct snd_trident * trident,int type,int client,int port)3712 struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port)
3713 {
3714 struct snd_trident_voice *pvoice;
3715 int idx;
3716
3717 guard(spinlock_irqsave)(&trident->voice_alloc);
3718 if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) {
3719 idx = snd_trident_allocate_pcm_channel(trident);
3720 if (idx < 0)
3721 return NULL;
3722 pvoice = &trident->synth.voices[idx];
3723 pvoice->use = 1;
3724 pvoice->pcm = 1;
3725 pvoice->capture = 0;
3726 pvoice->spdif = 0;
3727 pvoice->memblk = NULL;
3728 pvoice->substream = NULL;
3729 return pvoice;
3730 }
3731 if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) {
3732 idx = snd_trident_allocate_synth_channel(trident);
3733 if (idx < 0)
3734 return NULL;
3735 pvoice = &trident->synth.voices[idx];
3736 pvoice->use = 1;
3737 pvoice->synth = 1;
3738 pvoice->client = client;
3739 pvoice->port = port;
3740 pvoice->memblk = NULL;
3741 return pvoice;
3742 }
3743 if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) {
3744 }
3745 return NULL;
3746 }
3747
3748 EXPORT_SYMBOL(snd_trident_alloc_voice);
3749
snd_trident_free_voice(struct snd_trident * trident,struct snd_trident_voice * voice)3750 void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
3751 {
3752 void (*private_free)(struct snd_trident_voice *);
3753
3754 if (voice == NULL || !voice->use)
3755 return;
3756 snd_trident_clear_voices(trident, voice->number, voice->number);
3757 scoped_guard(spinlock_irqsave, &trident->voice_alloc) {
3758 private_free = voice->private_free;
3759 voice->private_free = NULL;
3760 voice->private_data = NULL;
3761 if (voice->pcm)
3762 snd_trident_free_pcm_channel(trident, voice->number);
3763 if (voice->synth)
3764 snd_trident_free_synth_channel(trident, voice->number);
3765 voice->use = voice->pcm = voice->synth = voice->midi = 0;
3766 voice->capture = voice->spdif = 0;
3767 voice->sample_ops = NULL;
3768 voice->substream = NULL;
3769 voice->extra = NULL;
3770 }
3771 if (private_free)
3772 private_free(voice);
3773 }
3774
3775 EXPORT_SYMBOL(snd_trident_free_voice);
3776
snd_trident_clear_voices(struct snd_trident * trident,unsigned short v_min,unsigned short v_max)3777 static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
3778 {
3779 unsigned int i, val, mask[2] = { 0, 0 };
3780
3781 if (snd_BUG_ON(v_min > 63 || v_max > 63))
3782 return;
3783 for (i = v_min; i <= v_max; i++)
3784 mask[i >> 5] |= 1 << (i & 0x1f);
3785 if (mask[0]) {
3786 outl(mask[0], TRID_REG(trident, T4D_STOP_A));
3787 val = inl(TRID_REG(trident, T4D_AINTEN_A));
3788 outl(val & ~mask[0], TRID_REG(trident, T4D_AINTEN_A));
3789 }
3790 if (mask[1]) {
3791 outl(mask[1], TRID_REG(trident, T4D_STOP_B));
3792 val = inl(TRID_REG(trident, T4D_AINTEN_B));
3793 outl(val & ~mask[1], TRID_REG(trident, T4D_AINTEN_B));
3794 }
3795 }
3796
3797 #ifdef CONFIG_PM_SLEEP
snd_trident_suspend(struct device * dev)3798 static int snd_trident_suspend(struct device *dev)
3799 {
3800 struct snd_card *card = dev_get_drvdata(dev);
3801 struct snd_trident *trident = card->private_data;
3802
3803 trident->in_suspend = 1;
3804 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3805 snd_ac97_suspend(trident->ac97);
3806 snd_ac97_suspend(trident->ac97_sec);
3807 return 0;
3808 }
3809
snd_trident_resume(struct device * dev)3810 static int snd_trident_resume(struct device *dev)
3811 {
3812 struct snd_card *card = dev_get_drvdata(dev);
3813 struct snd_trident *trident = card->private_data;
3814
3815 switch (trident->device) {
3816 case TRIDENT_DEVICE_ID_DX:
3817 snd_trident_4d_dx_init(trident);
3818 break;
3819 case TRIDENT_DEVICE_ID_NX:
3820 snd_trident_4d_nx_init(trident);
3821 break;
3822 case TRIDENT_DEVICE_ID_SI7018:
3823 snd_trident_sis_init(trident);
3824 break;
3825 }
3826
3827 snd_ac97_resume(trident->ac97);
3828 snd_ac97_resume(trident->ac97_sec);
3829
3830 /* restore some registers */
3831 outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
3832
3833 snd_trident_enable_eso(trident);
3834
3835 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3836 trident->in_suspend = 0;
3837 return 0;
3838 }
3839
3840 SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
3841 #endif /* CONFIG_PM_SLEEP */
3842