Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/trident/trident_main.c
29269 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Maintained by Jaroslav Kysela <[email protected]>
4
* Originated by [email protected]
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 <[email protected]>
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
---------------------------------------------------------------------------*/
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
---------------------------------------------------------------------------*/
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
---------------------------------------------------------------------------*/
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
---------------------------------------------------------------------------*/
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
---------------------------------------------------------------------------*/
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
---------------------------------------------------------------------------*/
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
---------------------------------------------------------------------------*/
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
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
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
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
---------------------------------------------------------------------------*/
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
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
---------------------------------------------------------------------------*/
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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(sizeof(*uctl), GFP_KERNEL);
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
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
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
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
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
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
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
3156
int snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
3157
static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
3158
#endif /* CONFIG_GAMEPORT */
3159
3160
/*
3161
* delay for 1 tick
3162
*/
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
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
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
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
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
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
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
*/
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
*/
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
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
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
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
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
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
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
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
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
3843