Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/au88x0/au88x0_core.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
*/
4
5
/*
6
Vortex core low level functions.
7
8
Author: Manuel Jander ([email protected])
9
These functions are mainly the result of translations made
10
from the original disassembly of the au88x0 binary drivers,
11
written by Aureal before they went down.
12
Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
13
contributed to the OpenVortex project.
14
The author of this file, put the few available pieces together
15
and translated the rest of the riddle (Mix, Src and connection stuff).
16
Some things are still to be discovered, and their meanings are unclear.
17
18
Some of these functions aren't intended to be really used, rather
19
to help to understand how does the AU88X0 chips work. Keep them in, because
20
they could be used somewhere in the future.
21
22
This code hasn't been tested or proof read thoroughly. If you wanna help,
23
take a look at the AU88X0 assembly and check if this matches.
24
Functions tested ok so far are (they show the desired effect
25
at least):
26
vortex_routes(); (1 bug fixed).
27
vortex_adb_addroute();
28
vortex_adb_addroutes();
29
vortex_connect_codecplay();
30
vortex_src_flushbuffers();
31
vortex_adbdma_setmode(); note: still some unknown arguments!
32
vortex_adbdma_startfifo();
33
vortex_adbdma_stopfifo();
34
vortex_fifo_setadbctrl(); note: still some unknown arguments!
35
vortex_mix_setinputvolumebyte();
36
vortex_mix_enableinput();
37
vortex_mixer_addWTD(); (fixed)
38
vortex_connection_adbdma_src_src();
39
vortex_connection_adbdma_src();
40
vortex_src_change_convratio();
41
vortex_src_addWTD(); (fixed)
42
43
History:
44
45
01-03-2003 First revision.
46
01-21-2003 Some bug fixes.
47
17-02-2003 many bugfixes after a big versioning mess.
48
18-02-2003 JAAAAAHHHUUUUUU!!!! The mixer works !! I'm just so happy !
49
(2 hours later...) I cant believe it! Im really lucky today.
50
Now the SRC is working too! Yeah! XMMS works !
51
20-02-2003 First steps into the ALSA world.
52
28-02-2003 As my birthday present, i discovered how the DMA buffer pages really
53
work :-). It was all wrong.
54
12-03-2003 ALSA driver starts working (2 channels).
55
16-03-2003 More srcblock_setupchannel discoveries.
56
12-04-2003 AU8830 playback support. Recording in the works.
57
17-04-2003 vortex_route() and vortex_routes() bug fixes. AU8830 recording
58
works now, but chipn' dale effect is still there.
59
16-05-2003 SrcSetupChannel cleanup. Moved the Src setup stuff entirely
60
into au88x0_pcm.c .
61
06-06-2003 Buffer shifter bugfix. Mixer volume fix.
62
07-12-2003 A3D routing finally fixed. Believed to be OK.
63
25-03-2004 Many thanks to Claudia, for such valuable bug reports.
64
65
*/
66
67
#include "au88x0.h"
68
#include "au88x0_a3d.h"
69
#include <linux/delay.h>
70
71
/* MIXER (CAsp4Mix.s and CAsp4Mixer.s) */
72
73
// FIXME: get rid of this.
74
static int mchannels[NR_MIXIN];
75
static int rampchs[NR_MIXIN];
76
77
static void vortex_mixer_en_sr(vortex_t * vortex, int channel)
78
{
79
hwwrite(vortex->mmio, VORTEX_MIXER_SR,
80
hwread(vortex->mmio, VORTEX_MIXER_SR) | (0x1 << channel));
81
}
82
static void vortex_mixer_dis_sr(vortex_t * vortex, int channel)
83
{
84
hwwrite(vortex->mmio, VORTEX_MIXER_SR,
85
hwread(vortex->mmio, VORTEX_MIXER_SR) & ~(0x1 << channel));
86
}
87
88
#if 0
89
static void
90
vortex_mix_muteinputgain(vortex_t * vortex, unsigned char mix,
91
unsigned char channel)
92
{
93
hwwrite(vortex->mmio, VORTEX_MIX_INVOL_A + ((mix << 5) + channel),
94
0x80);
95
hwwrite(vortex->mmio, VORTEX_MIX_INVOL_B + ((mix << 5) + channel),
96
0x80);
97
}
98
99
static int vortex_mix_getvolume(vortex_t * vortex, unsigned char mix)
100
{
101
int a;
102
a = hwread(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2)) & 0xff;
103
//FP2LinearFrac(a);
104
return (a);
105
}
106
107
static int
108
vortex_mix_getinputvolume(vortex_t * vortex, unsigned char mix,
109
int channel, int *vol)
110
{
111
int a;
112
if (!(mchannels[mix] & (1 << channel)))
113
return 0;
114
a = hwread(vortex->mmio,
115
VORTEX_MIX_INVOL_A + (((mix << 5) + channel) << 2));
116
/*
117
if (rampchs[mix] == 0)
118
a = FP2LinearFrac(a);
119
else
120
a = FP2LinearFracWT(a);
121
*/
122
*vol = a;
123
return (0);
124
}
125
126
static unsigned int vortex_mix_boost6db(unsigned char vol)
127
{
128
return (vol + 8); /* WOW! what a complex function! */
129
}
130
131
static void vortex_mix_rampvolume(vortex_t * vortex, int mix)
132
{
133
int ch;
134
char a;
135
// This function is intended for ramping down only (see vortex_disableinput()).
136
for (ch = 0; ch < 0x20; ch++) {
137
if (((1 << ch) & rampchs[mix]) == 0)
138
continue;
139
a = hwread(vortex->mmio,
140
VORTEX_MIX_INVOL_B + (((mix << 5) + ch) << 2));
141
if (a > -126) {
142
a -= 2;
143
hwwrite(vortex->mmio,
144
VORTEX_MIX_INVOL_A +
145
(((mix << 5) + ch) << 2), a);
146
hwwrite(vortex->mmio,
147
VORTEX_MIX_INVOL_B +
148
(((mix << 5) + ch) << 2), a);
149
} else
150
vortex_mix_killinput(vortex, mix, ch);
151
}
152
}
153
154
static int
155
vortex_mix_getenablebit(vortex_t * vortex, unsigned char mix, int mixin)
156
{
157
int addr, temp;
158
if (mixin >= 0)
159
addr = mixin;
160
else
161
addr = mixin + 3;
162
addr = ((mix << 3) + (addr >> 2)) << 2;
163
temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
164
return ((temp >> (mixin & 3)) & 1);
165
}
166
#endif
167
static void
168
vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix,
169
unsigned char vol)
170
{
171
int temp;
172
hwwrite(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2), vol);
173
if (1) { /*if (this_10) */
174
temp = hwread(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2));
175
if ((temp != 0x80) || (vol == 0x80))
176
return;
177
}
178
hwwrite(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2), vol);
179
}
180
181
static void
182
vortex_mix_setinputvolumebyte(vortex_t * vortex, unsigned char mix,
183
int mixin, unsigned char vol)
184
{
185
int temp;
186
187
hwwrite(vortex->mmio,
188
VORTEX_MIX_INVOL_A + (((mix << 5) + mixin) << 2), vol);
189
if (1) { /* this_10, initialized to 1. */
190
temp =
191
hwread(vortex->mmio,
192
VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2));
193
if ((temp != 0x80) || (vol == 0x80))
194
return;
195
}
196
hwwrite(vortex->mmio,
197
VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), vol);
198
}
199
200
static void
201
vortex_mix_setenablebit(vortex_t * vortex, unsigned char mix, int mixin, int en)
202
{
203
int temp, addr;
204
205
if (mixin < 0)
206
addr = (mixin + 3);
207
else
208
addr = mixin;
209
addr = ((mix << 3) + (addr >> 2)) << 2;
210
temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
211
if (en)
212
temp |= (1 << (mixin & 3));
213
else
214
temp &= ~(1 << (mixin & 3));
215
/* Mute input. Astatic void crackling? */
216
hwwrite(vortex->mmio,
217
VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), 0x80);
218
/* Looks like clear buffer. */
219
hwwrite(vortex->mmio, VORTEX_MIX_SMP + (mixin << 2), 0x0);
220
hwwrite(vortex->mmio, VORTEX_MIX_SMP + 4 + (mixin << 2), 0x0);
221
/* Write enable bit. */
222
hwwrite(vortex->mmio, VORTEX_MIX_ENIN + addr, temp);
223
}
224
225
static void
226
vortex_mix_killinput(vortex_t * vortex, unsigned char mix, int mixin)
227
{
228
rampchs[mix] &= ~(1 << mixin);
229
vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80);
230
mchannels[mix] &= ~(1 << mixin);
231
vortex_mix_setenablebit(vortex, mix, mixin, 0);
232
}
233
234
static void
235
vortex_mix_enableinput(vortex_t * vortex, unsigned char mix, int mixin)
236
{
237
vortex_mix_killinput(vortex, mix, mixin);
238
if ((mchannels[mix] & (1 << mixin)) == 0) {
239
vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80); /*0x80 : mute */
240
mchannels[mix] |= (1 << mixin);
241
}
242
vortex_mix_setenablebit(vortex, mix, mixin, 1);
243
}
244
245
static void
246
vortex_mix_disableinput(vortex_t * vortex, unsigned char mix, int channel,
247
int ramp)
248
{
249
if (ramp) {
250
rampchs[mix] |= (1 << channel);
251
// Register callback.
252
//vortex_mix_startrampvolume(vortex);
253
vortex_mix_killinput(vortex, mix, channel);
254
} else
255
vortex_mix_killinput(vortex, mix, channel);
256
}
257
258
static int
259
vortex_mixer_addWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
260
{
261
int temp, lifeboat = 0, prev;
262
263
temp = hwread(vortex->mmio, VORTEX_MIXER_SR);
264
if ((temp & (1 << ch)) == 0) {
265
hwwrite(vortex->mmio, VORTEX_MIXER_CHNBASE + (ch << 2), mix);
266
vortex_mixer_en_sr(vortex, ch);
267
return 1;
268
}
269
prev = VORTEX_MIXER_CHNBASE + (ch << 2);
270
temp = hwread(vortex->mmio, prev);
271
while (temp & 0x10) {
272
prev = VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2);
273
temp = hwread(vortex->mmio, prev);
274
//printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp);
275
if ((++lifeboat) > 0xf) {
276
dev_err(vortex->card->dev,
277
"vortex_mixer_addWTD: lifeboat overflow\n");
278
return 0;
279
}
280
}
281
hwwrite(vortex->mmio, VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2), mix);
282
hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
283
return 1;
284
}
285
286
static int
287
vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
288
{
289
int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
290
//int esp1f=edi(while)=src, esp10=ch;
291
292
eax = hwread(vortex->mmio, VORTEX_MIXER_SR);
293
if (((1 << ch) & eax) == 0) {
294
dev_err(vortex->card->dev, "mix ALARM %x\n", eax);
295
return 0;
296
}
297
ebp = VORTEX_MIXER_CHNBASE + (ch << 2);
298
esp18 = hwread(vortex->mmio, ebp);
299
if (esp18 & 0x10) {
300
ebx = (esp18 & 0xf);
301
if (mix == ebx) {
302
ebx = VORTEX_MIXER_RTBASE + (mix << 2);
303
edx = hwread(vortex->mmio, ebx);
304
//7b60
305
hwwrite(vortex->mmio, ebp, edx);
306
hwwrite(vortex->mmio, ebx, 0);
307
} else {
308
//7ad3
309
edx =
310
hwread(vortex->mmio,
311
VORTEX_MIXER_RTBASE + (ebx << 2));
312
//printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
313
while ((edx & 0xf) != mix) {
314
if ((esi) > 0xf) {
315
dev_err(vortex->card->dev,
316
"mixdelWTD: error lifeboat overflow\n");
317
return 0;
318
}
319
esp14 = ebx;
320
ebx = edx & 0xf;
321
ebp = ebx << 2;
322
edx =
323
hwread(vortex->mmio,
324
VORTEX_MIXER_RTBASE + ebp);
325
//printk(KERN_INFO "vortex: mixdelWTD: while addr=%x, val=%x\n", ebp, edx);
326
esi++;
327
}
328
//7b30
329
ebp = ebx << 2;
330
if (edx & 0x10) { /* Delete entry in between others */
331
ebx = VORTEX_MIXER_RTBASE + ((edx & 0xf) << 2);
332
edx = hwread(vortex->mmio, ebx);
333
//7b60
334
hwwrite(vortex->mmio,
335
VORTEX_MIXER_RTBASE + ebp, edx);
336
hwwrite(vortex->mmio, ebx, 0);
337
//printk(KERN_INFO "vortex mixdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
338
} else { /* Delete last entry */
339
//7b83
340
if (esp14 == -1)
341
hwwrite(vortex->mmio,
342
VORTEX_MIXER_CHNBASE +
343
(ch << 2), esp18 & 0xef);
344
else {
345
ebx = (0xffffffe0 & edx) | (0xf & ebx);
346
hwwrite(vortex->mmio,
347
VORTEX_MIXER_RTBASE +
348
(esp14 << 2), ebx);
349
//printk(KERN_INFO "vortex mixdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
350
}
351
hwwrite(vortex->mmio,
352
VORTEX_MIXER_RTBASE + ebp, 0);
353
return 1;
354
}
355
}
356
} else {
357
//printk(KERN_INFO "removed last mix\n");
358
//7be0
359
vortex_mixer_dis_sr(vortex, ch);
360
hwwrite(vortex->mmio, ebp, 0);
361
}
362
return 1;
363
}
364
365
static void vortex_mixer_init(vortex_t * vortex)
366
{
367
u32 addr;
368
int x;
369
370
// FIXME: get rid of this crap.
371
memset(mchannels, 0, NR_MIXOUT * sizeof(int));
372
memset(rampchs, 0, NR_MIXOUT * sizeof(int));
373
374
addr = VORTEX_MIX_SMP + 0x17c;
375
for (x = 0x5f; x >= 0; x--) {
376
hwwrite(vortex->mmio, addr, 0);
377
addr -= 4;
378
}
379
addr = VORTEX_MIX_ENIN + 0x1fc;
380
for (x = 0x7f; x >= 0; x--) {
381
hwwrite(vortex->mmio, addr, 0);
382
addr -= 4;
383
}
384
addr = VORTEX_MIX_SMP + 0x17c;
385
for (x = 0x5f; x >= 0; x--) {
386
hwwrite(vortex->mmio, addr, 0);
387
addr -= 4;
388
}
389
addr = VORTEX_MIX_INVOL_A + 0x7fc;
390
for (x = 0x1ff; x >= 0; x--) {
391
hwwrite(vortex->mmio, addr, 0x80);
392
addr -= 4;
393
}
394
addr = VORTEX_MIX_VOL_A + 0x3c;
395
for (x = 0xf; x >= 0; x--) {
396
hwwrite(vortex->mmio, addr, 0x80);
397
addr -= 4;
398
}
399
addr = VORTEX_MIX_INVOL_B + 0x7fc;
400
for (x = 0x1ff; x >= 0; x--) {
401
hwwrite(vortex->mmio, addr, 0x80);
402
addr -= 4;
403
}
404
addr = VORTEX_MIX_VOL_B + 0x3c;
405
for (x = 0xf; x >= 0; x--) {
406
hwwrite(vortex->mmio, addr, 0x80);
407
addr -= 4;
408
}
409
addr = VORTEX_MIXER_RTBASE + (MIXER_RTBASE_SIZE - 1) * 4;
410
for (x = (MIXER_RTBASE_SIZE - 1); x >= 0; x--) {
411
hwwrite(vortex->mmio, addr, 0x0);
412
addr -= 4;
413
}
414
hwwrite(vortex->mmio, VORTEX_MIXER_SR, 0);
415
416
/* Set clipping ceiling (this may be all wrong). */
417
/*
418
for (x = 0; x < 0x80; x++) {
419
hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff);
420
}
421
*/
422
/*
423
call CAsp4Mix__Initialize_CAsp4HwIO____CAsp4Mixer____
424
Register ISR callback for volume smooth fade out.
425
Maybe this avoids clicks when press "stop" ?
426
*/
427
}
428
429
/* SRC (CAsp4Src.s and CAsp4SrcBlock) */
430
431
static void vortex_src_en_sr(vortex_t * vortex, int channel)
432
{
433
hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
434
hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) | (0x1 << channel));
435
}
436
437
static void vortex_src_dis_sr(vortex_t * vortex, int channel)
438
{
439
hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
440
hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) & ~(0x1 << channel));
441
}
442
443
static void vortex_src_flushbuffers(vortex_t * vortex, unsigned char src)
444
{
445
int i;
446
447
for (i = 0x1f; i >= 0; i--)
448
hwwrite(vortex->mmio,
449
VORTEX_SRC_DATA0 + (src << 7) + (i << 2), 0);
450
hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3), 0);
451
hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3) + 4, 0);
452
}
453
454
static void vortex_src_cleardrift(vortex_t * vortex, unsigned char src)
455
{
456
hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
457
hwwrite(vortex->mmio, VORTEX_SRC_DRIFT1 + (src << 2), 0);
458
hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
459
}
460
461
static void
462
vortex_src_set_throttlesource(vortex_t * vortex, unsigned char src, int en)
463
{
464
int temp;
465
466
temp = hwread(vortex->mmio, VORTEX_SRC_SOURCE);
467
if (en)
468
temp |= 1 << src;
469
else
470
temp &= ~(1 << src);
471
hwwrite(vortex->mmio, VORTEX_SRC_SOURCE, temp);
472
}
473
474
static int
475
vortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio)
476
{
477
int temp, lifeboat = 0;
478
479
do {
480
hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio);
481
temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
482
if ((++lifeboat) > 0x9) {
483
dev_err(vortex->card->dev, "Src cvr fail\n");
484
break;
485
}
486
}
487
while (temp != ratio);
488
return temp;
489
}
490
491
#if 0
492
static void vortex_src_slowlock(vortex_t * vortex, unsigned char src)
493
{
494
int temp;
495
496
hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
497
hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
498
temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2));
499
if (temp & 0x200)
500
hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2),
501
temp & ~0x200L);
502
}
503
504
static void
505
vortex_src_change_convratio(vortex_t * vortex, unsigned char src, int ratio)
506
{
507
int temp, a;
508
509
if ((ratio & 0x10000) && (ratio != 0x10000)) {
510
if (ratio & 0x3fff)
511
a = (0x11 - ((ratio >> 0xe) & 0x3)) - 1;
512
else
513
a = (0x11 - ((ratio >> 0xe) & 0x3)) - 2;
514
} else
515
a = 0xc;
516
temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2));
517
if (((temp >> 4) & 0xf) != a)
518
hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2),
519
(temp & 0xf) | ((a & 0xf) << 4));
520
521
vortex_src_persist_convratio(vortex, src, ratio);
522
}
523
524
static int
525
vortex_src_checkratio(vortex_t * vortex, unsigned char src,
526
unsigned int desired_ratio)
527
{
528
int hw_ratio, lifeboat = 0;
529
530
hw_ratio = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
531
532
while (hw_ratio != desired_ratio) {
533
hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), desired_ratio);
534
535
if ((lifeboat++) > 15) {
536
pr_err( "Vortex: could not set src-%d from %d to %d\n",
537
src, hw_ratio, desired_ratio);
538
break;
539
}
540
}
541
542
return hw_ratio;
543
}
544
545
#endif
546
/*
547
Objective: Set samplerate for given SRC module.
548
Arguments:
549
card: pointer to vortex_t strcut.
550
src: Integer index of the SRC module.
551
cr: Current sample rate conversion factor.
552
b: unknown 16 bit value.
553
sweep: Enable Samplerate fade from cr toward tr flag.
554
dirplay: 1: playback, 0: recording.
555
sl: Slow Lock flag.
556
tr: Target samplerate conversion.
557
thsource: Throttle source flag (no idea what that means).
558
*/
559
static void vortex_src_setupchannel(vortex_t * card, unsigned char src,
560
unsigned int cr, unsigned int b, int sweep, int d,
561
int dirplay, int sl, unsigned int tr, int thsource)
562
{
563
// noplayback: d=2,4,7,0xa,0xb when using first 2 src's.
564
// c: enables pitch sweep.
565
// looks like g is c related. Maybe g is a sweep parameter ?
566
// g = cvr
567
// dirplay: 0 = recording, 1 = playback
568
// d = src hw index.
569
570
int esi, ebp = 0, esp10;
571
572
vortex_src_flushbuffers(card, src);
573
574
if (sweep) {
575
if ((tr & 0x10000) && (tr != 0x10000)) {
576
tr = 0;
577
esi = 0x7;
578
} else {
579
if ((((short)tr) < 0) && (tr != 0x8000)) {
580
tr = 0;
581
esi = 0x8;
582
} else {
583
tr = 1;
584
esi = 0xc;
585
}
586
}
587
} else {
588
if ((cr & 0x10000) && (cr != 0x10000)) {
589
tr = 0; /*ebx = 0 */
590
esi = 0x11 - ((cr >> 0xe) & 7);
591
if (cr & 0x3fff)
592
esi -= 1;
593
else
594
esi -= 2;
595
} else {
596
tr = 1;
597
esi = 0xc;
598
}
599
}
600
vortex_src_cleardrift(card, src);
601
vortex_src_set_throttlesource(card, src, thsource);
602
603
if ((dirplay == 0) && (sweep == 0)) {
604
if (tr)
605
esp10 = 0xf;
606
else
607
esp10 = 0xc;
608
ebp = 0;
609
} else {
610
if (tr)
611
ebp = 0xf;
612
else
613
ebp = 0xc;
614
esp10 = 0;
615
}
616
hwwrite(card->mmio, VORTEX_SRC_U0 + (src << 2),
617
(sl << 0x9) | (sweep << 0x8) | ((esi & 0xf) << 4) | d);
618
/* 0xc0 esi=0xc c=f=0 d=0 */
619
vortex_src_persist_convratio(card, src, cr);
620
hwwrite(card->mmio, VORTEX_SRC_U1 + (src << 2), b & 0xffff);
621
/* 0 b=0 */
622
hwwrite(card->mmio, VORTEX_SRC_U2 + (src << 2),
623
(tr << 0x11) | (dirplay << 0x10) | (ebp << 0x8) | esp10);
624
/* 0x30f00 e=g=1 esp10=0 ebp=f */
625
//printk(KERN_INFO "vortex: SRC %d, d=0x%x, esi=0x%x, esp10=0x%x, ebp=0x%x\n", src, d, esi, esp10, ebp);
626
}
627
628
static void vortex_srcblock_init(vortex_t * vortex)
629
{
630
u32 addr;
631
int x;
632
hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff);
633
/*
634
for (x=0; x<0x10; x++) {
635
vortex_src_init(&vortex_src[x], x);
636
}
637
*/
638
//addr = 0xcc3c;
639
//addr = 0x26c3c;
640
addr = VORTEX_SRC_RTBASE + 0x3c;
641
for (x = 0xf; x >= 0; x--) {
642
hwwrite(vortex->mmio, addr, 0);
643
addr -= 4;
644
}
645
//addr = 0xcc94;
646
//addr = 0x26c94;
647
addr = VORTEX_SRC_CHNBASE + 0x54;
648
for (x = 0x15; x >= 0; x--) {
649
hwwrite(vortex->mmio, addr, 0);
650
addr -= 4;
651
}
652
}
653
654
static int
655
vortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
656
{
657
int temp, lifeboat = 0, prev;
658
// esp13 = src
659
660
temp = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
661
if ((temp & (1 << ch)) == 0) {
662
hwwrite(vortex->mmio, VORTEX_SRC_CHNBASE + (ch << 2), src);
663
vortex_src_en_sr(vortex, ch);
664
return 1;
665
}
666
prev = VORTEX_SRC_CHNBASE + (ch << 2); /*ebp */
667
temp = hwread(vortex->mmio, prev);
668
//while (temp & NR_SRC) {
669
while (temp & 0x10) {
670
prev = VORTEX_SRC_RTBASE + ((temp & 0xf) << 2); /*esp12 */
671
//prev = VORTEX_SRC_RTBASE + ((temp & (NR_SRC-1)) << 2); /*esp12*/
672
temp = hwread(vortex->mmio, prev);
673
//printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp);
674
if ((++lifeboat) > 0xf) {
675
dev_err(vortex->card->dev,
676
"vortex_src_addWTD: lifeboat overflow\n");
677
return 0;
678
}
679
}
680
hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ((temp & 0xf) << 2), src);
681
//hwwrite(vortex->mmio, prev, (temp & (NR_SRC-1)) | NR_SRC);
682
hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
683
return 1;
684
}
685
686
static int
687
vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
688
{
689
int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
690
//int esp1f=edi(while)=src, esp10=ch;
691
692
eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
693
if (((1 << ch) & eax) == 0) {
694
dev_err(vortex->card->dev, "src alarm\n");
695
return 0;
696
}
697
ebp = VORTEX_SRC_CHNBASE + (ch << 2);
698
esp18 = hwread(vortex->mmio, ebp);
699
if (esp18 & 0x10) {
700
ebx = (esp18 & 0xf);
701
if (src == ebx) {
702
ebx = VORTEX_SRC_RTBASE + (src << 2);
703
edx = hwread(vortex->mmio, ebx);
704
//7b60
705
hwwrite(vortex->mmio, ebp, edx);
706
hwwrite(vortex->mmio, ebx, 0);
707
} else {
708
//7ad3
709
edx =
710
hwread(vortex->mmio,
711
VORTEX_SRC_RTBASE + (ebx << 2));
712
//printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
713
while ((edx & 0xf) != src) {
714
if ((esi) > 0xf) {
715
dev_warn(vortex->card->dev,
716
"srcdelWTD: error, lifeboat overflow\n");
717
return 0;
718
}
719
esp14 = ebx;
720
ebx = edx & 0xf;
721
ebp = ebx << 2;
722
edx =
723
hwread(vortex->mmio,
724
VORTEX_SRC_RTBASE + ebp);
725
//printk(KERN_INFO "vortex: srcdelWTD: while addr=%x, val=%x\n", ebp, edx);
726
esi++;
727
}
728
//7b30
729
ebp = ebx << 2;
730
if (edx & 0x10) { /* Delete entry in between others */
731
ebx = VORTEX_SRC_RTBASE + ((edx & 0xf) << 2);
732
edx = hwread(vortex->mmio, ebx);
733
//7b60
734
hwwrite(vortex->mmio,
735
VORTEX_SRC_RTBASE + ebp, edx);
736
hwwrite(vortex->mmio, ebx, 0);
737
//printk(KERN_INFO "vortex srcdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
738
} else { /* Delete last entry */
739
//7b83
740
if (esp14 == -1)
741
hwwrite(vortex->mmio,
742
VORTEX_SRC_CHNBASE +
743
(ch << 2), esp18 & 0xef);
744
else {
745
ebx = (0xffffffe0 & edx) | (0xf & ebx);
746
hwwrite(vortex->mmio,
747
VORTEX_SRC_RTBASE +
748
(esp14 << 2), ebx);
749
//printk(KERN_INFO"vortex srcdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
750
}
751
hwwrite(vortex->mmio,
752
VORTEX_SRC_RTBASE + ebp, 0);
753
return 1;
754
}
755
}
756
} else {
757
//7be0
758
vortex_src_dis_sr(vortex, ch);
759
hwwrite(vortex->mmio, ebp, 0);
760
}
761
return 1;
762
}
763
764
/*FIFO*/
765
766
static void
767
vortex_fifo_clearadbdata(vortex_t * vortex, int fifo, int x)
768
{
769
for (x--; x >= 0; x--)
770
hwwrite(vortex->mmio,
771
VORTEX_FIFO_ADBDATA +
772
(((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
773
}
774
775
#if 0
776
static void vortex_fifo_adbinitialize(vortex_t * vortex, int fifo, int j)
777
{
778
vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
779
#ifdef CHIP_AU8820
780
hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
781
(FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
782
#else
783
hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
784
(FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
785
#endif
786
}
787
#endif
788
static void vortex_fifo_setadbvalid(vortex_t * vortex, int fifo, int en)
789
{
790
hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
791
(hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)) &
792
0xffffffef) | ((1 & en) << 4) | FIFO_U1);
793
}
794
795
static void
796
vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int stereo, int priority,
797
int empty, int valid, int f)
798
{
799
int temp, lifeboat = 0;
800
//int this_8[NR_ADB] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* position */
801
int this_4 = 0x2;
802
/* f seems priority related.
803
* CAsp4AdbDma::SetPriority is the only place that calls SetAdbCtrl with f set to 1
804
* every where else it is set to 0. It seems, however, that CAsp4AdbDma::SetPriority
805
* is never called, thus the f related bits remain a mystery for now.
806
*/
807
do {
808
temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
809
if (lifeboat++ > 0xbb8) {
810
dev_err(vortex->card->dev,
811
"vortex_fifo_setadbctrl fail\n");
812
break;
813
}
814
}
815
while (temp & FIFO_RDONLY);
816
817
// AU8830 semes to take some special care about fifo content (data).
818
// But i'm just to lazy to translate that :)
819
if (valid) {
820
if ((temp & FIFO_VALID) == 0) {
821
//this_8[fifo] = 0;
822
vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE); // this_4
823
#ifdef CHIP_AU8820
824
temp = (this_4 & 0x1f) << 0xb;
825
#else
826
temp = (this_4 & 0x3f) << 0xc;
827
#endif
828
temp = (temp & 0xfffffffd) | ((stereo & 1) << 1);
829
temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
830
temp = (temp & 0xffffffef) | ((valid & 1) << 4);
831
temp |= FIFO_U1;
832
temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
833
#ifdef CHIP_AU8820
834
temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
835
#endif
836
#ifdef CHIP_AU8830
837
temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
838
temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
839
#endif
840
#ifdef CHIP_AU8810
841
temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
842
temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
843
#endif
844
}
845
} else {
846
if (temp & FIFO_VALID) {
847
#ifdef CHIP_AU8820
848
temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
849
#endif
850
#ifdef CHIP_AU8830
851
temp =
852
((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
853
#endif
854
#ifdef CHIP_AU8810
855
temp =
856
((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
857
#endif
858
} else
859
/*if (this_8[fifo]) */
860
vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
861
}
862
hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), temp);
863
hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
864
}
865
866
#ifndef CHIP_AU8810
867
static void vortex_fifo_clearwtdata(vortex_t * vortex, int fifo, int x)
868
{
869
if (x < 1)
870
return;
871
for (x--; x >= 0; x--)
872
hwwrite(vortex->mmio,
873
VORTEX_FIFO_WTDATA +
874
(((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
875
}
876
877
static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j)
878
{
879
vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
880
#ifdef CHIP_AU8820
881
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
882
(FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
883
#else
884
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
885
(FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
886
#endif
887
}
888
889
static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en)
890
{
891
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
892
(hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)) &
893
0xffffffef) | ((en & 1) << 4) | FIFO_U1);
894
}
895
896
static void
897
vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority,
898
int empty, int valid, int f)
899
{
900
int temp = 0, lifeboat = 0;
901
int this_4 = 2;
902
903
do {
904
temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
905
if (lifeboat++ > 0xbb8) {
906
dev_err(vortex->card->dev,
907
"vortex_fifo_setwtctrl fail\n");
908
break;
909
}
910
}
911
while (temp & FIFO_RDONLY);
912
913
if (valid) {
914
if ((temp & FIFO_VALID) == 0) {
915
vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE); // this_4
916
#ifdef CHIP_AU8820
917
temp = (this_4 & 0x1f) << 0xb;
918
#else
919
temp = (this_4 & 0x3f) << 0xc;
920
#endif
921
temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
922
temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
923
temp = (temp & 0xffffffef) | ((valid & 1) << 4);
924
temp |= FIFO_U1;
925
temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
926
#ifdef CHIP_AU8820
927
temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
928
#endif
929
#ifdef CHIP_AU8830
930
temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
931
temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
932
#endif
933
#ifdef CHIP_AU8810
934
temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
935
temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
936
#endif
937
}
938
} else {
939
if (temp & FIFO_VALID) {
940
#ifdef CHIP_AU8820
941
temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
942
#endif
943
#ifdef CHIP_AU8830
944
temp =
945
((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
946
#endif
947
#ifdef CHIP_AU8810
948
temp =
949
((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
950
#endif
951
} else
952
/*if (this_8[fifo]) */
953
vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
954
}
955
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
956
hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
957
958
/*
959
do {
960
temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
961
if (lifeboat++ > 0xbb8) {
962
pr_err( "Vortex: vortex_fifo_setwtctrl fail (hanging)\n");
963
break;
964
}
965
} while ((temp & FIFO_RDONLY)&&(temp & FIFO_VALID)&&(temp != 0xFFFFFFFF));
966
967
968
if (valid) {
969
if (temp & FIFO_VALID) {
970
temp = 0x40000;
971
//temp |= 0x08000000;
972
//temp |= 0x10000000;
973
//temp |= 0x04000000;
974
//temp |= 0x00400000;
975
temp |= 0x1c400000;
976
temp &= 0xFFFFFFF3;
977
temp &= 0xFFFFFFEF;
978
temp |= (valid & 1) << 4;
979
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
980
return;
981
} else {
982
vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
983
return;
984
}
985
} else {
986
temp &= 0xffffffef;
987
temp |= 0x08000000;
988
temp |= 0x10000000;
989
temp |= 0x04000000;
990
temp |= 0x00400000;
991
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
992
temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
993
//((temp >> 6) & 0x3f)
994
995
priority = 0;
996
if (((temp & 0x0fc0) ^ ((temp >> 6) & 0x0fc0)) & 0FFFFFFC0)
997
vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
998
valid = 0xfb;
999
temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
1000
temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
1001
temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
1002
temp = (temp & 0xffffffef) | ((valid & 1) << 4);
1003
temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
1004
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
1005
}
1006
1007
*/
1008
1009
/*
1010
temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
1011
temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
1012
temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
1013
temp = (temp & 0xffffffef) | ((valid & 1) << 4);
1014
temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
1015
#ifdef FIFO_BITS
1016
temp = temp | FIFO_BITS | 40000;
1017
#endif
1018
// 0x1c440010, 0x1c400000
1019
hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
1020
*/
1021
}
1022
1023
#endif
1024
static void vortex_fifo_init(vortex_t * vortex)
1025
{
1026
int x;
1027
u32 addr;
1028
1029
/* ADB DMA channels fifos. */
1030
addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4);
1031
for (x = NR_ADB - 1; x >= 0; x--) {
1032
hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1));
1033
if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1))
1034
dev_err(vortex->card->dev, "bad adb fifo reset!\n");
1035
vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE);
1036
addr -= 4;
1037
}
1038
1039
#ifndef CHIP_AU8810
1040
/* WT DMA channels fifos. */
1041
addr = VORTEX_FIFO_WTCTRL + ((NR_WT - 1) * 4);
1042
for (x = NR_WT - 1; x >= 0; x--) {
1043
hwwrite(vortex->mmio, addr, FIFO_U0);
1044
if (hwread(vortex->mmio, addr) != FIFO_U0)
1045
dev_err(vortex->card->dev,
1046
"bad wt fifo reset (0x%08x, 0x%08x)!\n",
1047
addr, hwread(vortex->mmio, addr));
1048
vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE);
1049
addr -= 4;
1050
}
1051
#endif
1052
/* trigger... */
1053
#ifdef CHIP_AU8820
1054
hwwrite(vortex->mmio, 0xf8c0, 0xd03); //0x0843 0xd6b
1055
#else
1056
#ifdef CHIP_AU8830
1057
hwwrite(vortex->mmio, 0x17000, 0x61); /* wt a */
1058
hwwrite(vortex->mmio, 0x17004, 0x61); /* wt b */
1059
#endif
1060
hwwrite(vortex->mmio, 0x17008, 0x61); /* adb */
1061
#endif
1062
}
1063
1064
/* ADBDMA */
1065
1066
static void vortex_adbdma_init(vortex_t * vortex)
1067
{
1068
}
1069
1070
static void vortex_adbdma_setfirstbuffer(vortex_t * vortex, int adbdma)
1071
{
1072
stream_t *dma = &vortex->dma_adb[adbdma];
1073
1074
hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1075
dma->dma_ctrl);
1076
}
1077
1078
static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)
1079
{
1080
stream_t *dma = &vortex->dma_adb[adbdma];
1081
//hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2), sb << (((NR_ADB-1)-((adbdma&0xf)*2))));
1082
hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2),
1083
sb << ((0xf - (adbdma & 0xf)) * 2));
1084
dma->period_real = dma->period_virt = sb;
1085
}
1086
1087
static void
1088
vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
1089
int psize, int count)
1090
{
1091
stream_t *dma = &vortex->dma_adb[adbdma];
1092
1093
dma->period_bytes = psize;
1094
dma->nr_periods = count;
1095
1096
dma->cfg0 = 0;
1097
dma->cfg1 = 0;
1098
switch (count) {
1099
/* Four or more pages */
1100
default:
1101
case 4:
1102
dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
1103
hwwrite(vortex->mmio,
1104
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
1105
snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
1106
fallthrough;
1107
/* 3 pages */
1108
case 3:
1109
dma->cfg0 |= 0x12000000;
1110
dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
1111
hwwrite(vortex->mmio,
1112
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
1113
snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
1114
fallthrough;
1115
/* 2 pages */
1116
case 2:
1117
dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
1118
hwwrite(vortex->mmio,
1119
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
1120
snd_pcm_sgbuf_get_addr(dma->substream, psize));
1121
fallthrough;
1122
/* 1 page */
1123
case 1:
1124
dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
1125
hwwrite(vortex->mmio,
1126
VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
1127
snd_pcm_sgbuf_get_addr(dma->substream, 0));
1128
break;
1129
}
1130
/*
1131
pr_debug( "vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n",
1132
dma->cfg0, dma->cfg1);
1133
*/
1134
hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0);
1135
hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1);
1136
1137
vortex_adbdma_setfirstbuffer(vortex, adbdma);
1138
vortex_adbdma_setstartbuffer(vortex, adbdma, 0);
1139
}
1140
1141
static void
1142
vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
1143
int fmt, int stereo, u32 offset)
1144
{
1145
stream_t *dma = &vortex->dma_adb[adbdma];
1146
1147
dma->dma_unknown = stereo;
1148
dma->dma_ctrl =
1149
((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1150
/* Enable PCMOUT interrupts. */
1151
dma->dma_ctrl =
1152
(dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1153
1154
dma->dma_ctrl =
1155
(dma->dma_ctrl & ~DIR_MASK) | ((dir << DIR_SHIFT) & DIR_MASK);
1156
dma->dma_ctrl =
1157
(dma->dma_ctrl & ~FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1158
1159
hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1160
dma->dma_ctrl);
1161
hwread(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2));
1162
}
1163
1164
static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
1165
{
1166
stream_t *dma = &vortex->dma_adb[adbdma];
1167
int page, p, pp, delta, i;
1168
1169
page =
1170
(hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)) &
1171
ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
1172
if (dma->nr_periods >= 4)
1173
delta = (page - dma->period_real) & 3;
1174
else {
1175
delta = (page - dma->period_real);
1176
if (delta < 0)
1177
delta += dma->nr_periods;
1178
}
1179
if (delta == 0)
1180
return 0;
1181
1182
/* refresh hw page table */
1183
if (dma->nr_periods > 4) {
1184
for (i = 0; i < delta; i++) {
1185
/* p: audio buffer page index */
1186
p = dma->period_virt + i + 4;
1187
if (p >= dma->nr_periods)
1188
p -= dma->nr_periods;
1189
/* pp: hardware DMA page index. */
1190
pp = dma->period_real + i;
1191
if (pp >= 4)
1192
pp -= 4;
1193
//hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
1194
hwwrite(vortex->mmio,
1195
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1196
snd_pcm_sgbuf_get_addr(dma->substream,
1197
dma->period_bytes * p));
1198
/* Force write through cache. */
1199
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
1200
(((adbdma << 2) + pp) << 2));
1201
}
1202
}
1203
dma->period_virt += delta;
1204
dma->period_real = page;
1205
if (dma->period_virt >= dma->nr_periods)
1206
dma->period_virt -= dma->nr_periods;
1207
if (delta != 1)
1208
dev_info(vortex->card->dev,
1209
"%d virt=%d, real=%d, delta=%d\n",
1210
adbdma, dma->period_virt, dma->period_real, delta);
1211
1212
return delta;
1213
}
1214
1215
1216
static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
1217
stream_t *dma = &vortex->dma_adb[adbdma];
1218
int p, pp, i;
1219
1220
/* refresh hw page table */
1221
for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
1222
/* p: audio buffer page index */
1223
p = dma->period_virt + i;
1224
if (p >= dma->nr_periods)
1225
p -= dma->nr_periods;
1226
/* pp: hardware DMA page index. */
1227
pp = dma->period_real + i;
1228
if (dma->nr_periods < 4) {
1229
if (pp >= dma->nr_periods)
1230
pp -= dma->nr_periods;
1231
}
1232
else {
1233
if (pp >= 4)
1234
pp -= 4;
1235
}
1236
hwwrite(vortex->mmio,
1237
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1238
snd_pcm_sgbuf_get_addr(dma->substream,
1239
dma->period_bytes * p));
1240
/* Force write through cache. */
1241
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
1242
}
1243
}
1244
1245
static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
1246
{
1247
stream_t *dma = &vortex->dma_adb[adbdma];
1248
int temp, page, delta;
1249
1250
temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
1251
page = (temp & ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
1252
if (dma->nr_periods >= 4)
1253
delta = (page - dma->period_real) & 3;
1254
else {
1255
delta = (page - dma->period_real);
1256
if (delta < 0)
1257
delta += dma->nr_periods;
1258
}
1259
return (dma->period_virt + delta) * dma->period_bytes
1260
+ (temp & (dma->period_bytes - 1));
1261
}
1262
1263
static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
1264
{
1265
int this_8 = 0 /*empty */ , this_4 = 0 /*priority */ ;
1266
stream_t *dma = &vortex->dma_adb[adbdma];
1267
1268
switch (dma->fifo_status) {
1269
case FIFO_START:
1270
vortex_fifo_setadbvalid(vortex, adbdma,
1271
dma->fifo_enabled ? 1 : 0);
1272
break;
1273
case FIFO_STOP:
1274
this_8 = 1;
1275
hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1276
dma->dma_ctrl);
1277
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1278
this_4, this_8,
1279
dma->fifo_enabled ? 1 : 0, 0);
1280
break;
1281
case FIFO_PAUSE:
1282
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1283
this_4, this_8,
1284
dma->fifo_enabled ? 1 : 0, 0);
1285
break;
1286
}
1287
dma->fifo_status = FIFO_START;
1288
}
1289
1290
static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma)
1291
{
1292
stream_t *dma = &vortex->dma_adb[adbdma];
1293
1294
int this_8 = 1, this_4 = 0;
1295
switch (dma->fifo_status) {
1296
case FIFO_STOP:
1297
hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1298
dma->dma_ctrl);
1299
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1300
this_4, this_8,
1301
dma->fifo_enabled ? 1 : 0, 0);
1302
break;
1303
case FIFO_PAUSE:
1304
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1305
this_4, this_8,
1306
dma->fifo_enabled ? 1 : 0, 0);
1307
break;
1308
}
1309
dma->fifo_status = FIFO_START;
1310
}
1311
1312
static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma)
1313
{
1314
stream_t *dma = &vortex->dma_adb[adbdma];
1315
1316
int this_8 = 0, this_4 = 0;
1317
switch (dma->fifo_status) {
1318
case FIFO_START:
1319
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1320
this_4, this_8, 0, 0);
1321
break;
1322
case FIFO_STOP:
1323
hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1324
dma->dma_ctrl);
1325
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1326
this_4, this_8, 0, 0);
1327
break;
1328
}
1329
dma->fifo_status = FIFO_PAUSE;
1330
}
1331
1332
static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma)
1333
{
1334
stream_t *dma = &vortex->dma_adb[adbdma];
1335
1336
int this_4 = 0, this_8 = 0;
1337
if (dma->fifo_status == FIFO_START)
1338
vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1339
this_4, this_8, 0, 0);
1340
else if (dma->fifo_status == FIFO_STOP)
1341
return;
1342
dma->fifo_status = FIFO_STOP;
1343
dma->fifo_enabled = 0;
1344
}
1345
1346
/* WTDMA */
1347
1348
#ifndef CHIP_AU8810
1349
static void vortex_wtdma_setfirstbuffer(vortex_t * vortex, int wtdma)
1350
{
1351
//int this_7c=dma_ctrl;
1352
stream_t *dma = &vortex->dma_wt[wtdma];
1353
1354
hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1355
}
1356
1357
static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
1358
{
1359
stream_t *dma = &vortex->dma_wt[wtdma];
1360
//hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2), sb << ((0x1f-(wtdma&0xf)*2)));
1361
hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2),
1362
sb << ((0xf - (wtdma & 0xf)) * 2));
1363
dma->period_real = dma->period_virt = sb;
1364
}
1365
1366
static void
1367
vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
1368
int psize, int count)
1369
{
1370
stream_t *dma = &vortex->dma_wt[wtdma];
1371
1372
dma->period_bytes = psize;
1373
dma->nr_periods = count;
1374
1375
dma->cfg0 = 0;
1376
dma->cfg1 = 0;
1377
switch (count) {
1378
/* Four or more pages */
1379
default:
1380
case 4:
1381
dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
1382
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
1383
snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
1384
fallthrough;
1385
/* 3 pages */
1386
case 3:
1387
dma->cfg0 |= 0x12000000;
1388
dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1389
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
1390
snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
1391
fallthrough;
1392
/* 2 pages */
1393
case 2:
1394
dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
1395
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
1396
snd_pcm_sgbuf_get_addr(dma->substream, psize));
1397
fallthrough;
1398
/* 1 page */
1399
case 1:
1400
dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1401
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
1402
snd_pcm_sgbuf_get_addr(dma->substream, 0));
1403
break;
1404
}
1405
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
1406
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG1 + (wtdma << 3), dma->cfg1);
1407
1408
vortex_wtdma_setfirstbuffer(vortex, wtdma);
1409
vortex_wtdma_setstartbuffer(vortex, wtdma, 0);
1410
}
1411
1412
static void
1413
vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,
1414
/*int e, */ u32 offset)
1415
{
1416
stream_t *dma = &vortex->dma_wt[wtdma];
1417
1418
//dma->this_08 = e;
1419
dma->dma_unknown = d;
1420
dma->dma_ctrl = 0;
1421
dma->dma_ctrl =
1422
((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1423
/* PCMOUT interrupt */
1424
dma->dma_ctrl =
1425
(dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1426
/* Always playback. */
1427
dma->dma_ctrl |= (1 << DIR_SHIFT);
1428
/* Audio Format */
1429
dma->dma_ctrl =
1430
(dma->dma_ctrl & FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1431
/* Write into hardware */
1432
hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1433
}
1434
1435
static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
1436
{
1437
stream_t *dma = &vortex->dma_wt[wtdma];
1438
int page, p, pp, delta, i;
1439
1440
page =
1441
(hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2))
1442
>> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
1443
if (dma->nr_periods >= 4)
1444
delta = (page - dma->period_real) & 3;
1445
else {
1446
delta = (page - dma->period_real);
1447
if (delta < 0)
1448
delta += dma->nr_periods;
1449
}
1450
if (delta == 0)
1451
return 0;
1452
1453
/* refresh hw page table */
1454
if (dma->nr_periods > 4) {
1455
for (i = 0; i < delta; i++) {
1456
/* p: audio buffer page index */
1457
p = dma->period_virt + i + 4;
1458
if (p >= dma->nr_periods)
1459
p -= dma->nr_periods;
1460
/* pp: hardware DMA page index. */
1461
pp = dma->period_real + i;
1462
if (pp >= 4)
1463
pp -= 4;
1464
hwwrite(vortex->mmio,
1465
VORTEX_WTDMA_BUFBASE +
1466
(((wtdma << 2) + pp) << 2),
1467
snd_pcm_sgbuf_get_addr(dma->substream,
1468
dma->period_bytes * p));
1469
/* Force write through cache. */
1470
hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
1471
(((wtdma << 2) + pp) << 2));
1472
}
1473
}
1474
dma->period_virt += delta;
1475
if (dma->period_virt >= dma->nr_periods)
1476
dma->period_virt -= dma->nr_periods;
1477
dma->period_real = page;
1478
1479
if (delta != 1)
1480
dev_warn(vortex->card->dev, "wt virt = %d, delta = %d\n",
1481
dma->period_virt, delta);
1482
1483
return delta;
1484
}
1485
1486
#if 0
1487
static void
1488
vortex_wtdma_getposition(vortex_t * vortex, int wtdma, int *subbuf, int *pos)
1489
{
1490
int temp;
1491
temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1492
*subbuf = (temp >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
1493
*pos = temp & POS_MASK;
1494
}
1495
1496
static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma)
1497
{
1498
return ((hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) >>
1499
POS_SHIFT) & POS_MASK);
1500
}
1501
#endif
1502
static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
1503
{
1504
stream_t *dma = &vortex->dma_wt[wtdma];
1505
int temp;
1506
1507
temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1508
temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
1509
return temp;
1510
}
1511
1512
static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma)
1513
{
1514
stream_t *dma = &vortex->dma_wt[wtdma];
1515
int this_8 = 0, this_4 = 0;
1516
1517
switch (dma->fifo_status) {
1518
case FIFO_START:
1519
vortex_fifo_setwtvalid(vortex, wtdma,
1520
dma->fifo_enabled ? 1 : 0);
1521
break;
1522
case FIFO_STOP:
1523
this_8 = 1;
1524
hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1525
dma->dma_ctrl);
1526
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1527
this_4, this_8,
1528
dma->fifo_enabled ? 1 : 0, 0);
1529
break;
1530
case FIFO_PAUSE:
1531
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1532
this_4, this_8,
1533
dma->fifo_enabled ? 1 : 0, 0);
1534
break;
1535
}
1536
dma->fifo_status = FIFO_START;
1537
}
1538
1539
static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma)
1540
{
1541
stream_t *dma = &vortex->dma_wt[wtdma];
1542
1543
int this_8 = 0, this_4 = 0;
1544
switch (dma->fifo_status) {
1545
case FIFO_STOP:
1546
hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1547
dma->dma_ctrl);
1548
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1549
this_4, this_8,
1550
dma->fifo_enabled ? 1 : 0, 0);
1551
break;
1552
case FIFO_PAUSE:
1553
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1554
this_4, this_8,
1555
dma->fifo_enabled ? 1 : 0, 0);
1556
break;
1557
}
1558
dma->fifo_status = FIFO_START;
1559
}
1560
1561
static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma)
1562
{
1563
stream_t *dma = &vortex->dma_wt[wtdma];
1564
1565
int this_8 = 0, this_4 = 0;
1566
switch (dma->fifo_status) {
1567
case FIFO_START:
1568
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1569
this_4, this_8, 0, 0);
1570
break;
1571
case FIFO_STOP:
1572
hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1573
dma->dma_ctrl);
1574
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1575
this_4, this_8, 0, 0);
1576
break;
1577
}
1578
dma->fifo_status = FIFO_PAUSE;
1579
}
1580
1581
static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma)
1582
{
1583
stream_t *dma = &vortex->dma_wt[wtdma];
1584
1585
int this_4 = 0, this_8 = 0;
1586
if (dma->fifo_status == FIFO_START)
1587
vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1588
this_4, this_8, 0, 0);
1589
else if (dma->fifo_status == FIFO_STOP)
1590
return;
1591
dma->fifo_status = FIFO_STOP;
1592
dma->fifo_enabled = 0;
1593
}
1594
1595
#endif
1596
/* ADB Routes */
1597
1598
typedef int ADBRamLink;
1599
static void vortex_adb_init(vortex_t * vortex)
1600
{
1601
int i;
1602
/* it looks like we are writing more than we need to...
1603
* if we write what we are supposed to it breaks things... */
1604
hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);
1605
for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)
1606
hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),
1607
hwread(vortex->mmio,
1608
VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);
1609
for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {
1610
hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),
1611
hwread(vortex->mmio,
1612
VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);
1613
}
1614
}
1615
1616
static void vortex_adb_en_sr(vortex_t * vortex, int channel)
1617
{
1618
hwwrite(vortex->mmio, VORTEX_ADB_SR,
1619
hwread(vortex->mmio, VORTEX_ADB_SR) | (0x1 << channel));
1620
}
1621
1622
static void vortex_adb_dis_sr(vortex_t * vortex, int channel)
1623
{
1624
hwwrite(vortex->mmio, VORTEX_ADB_SR,
1625
hwread(vortex->mmio, VORTEX_ADB_SR) & ~(0x1 << channel));
1626
}
1627
1628
static void
1629
vortex_adb_addroutes(vortex_t * vortex, unsigned char channel,
1630
ADBRamLink * route, int rnum)
1631
{
1632
int temp, prev, lifeboat = 0;
1633
1634
if ((rnum <= 0) || (route == NULL))
1635
return;
1636
/* Write last routes. */
1637
rnum--;
1638
hwwrite(vortex->mmio,
1639
VORTEX_ADB_RTBASE + ((route[rnum] & ADB_MASK) << 2),
1640
ROUTE_MASK);
1641
while (rnum > 0) {
1642
hwwrite(vortex->mmio,
1643
VORTEX_ADB_RTBASE +
1644
((route[rnum - 1] & ADB_MASK) << 2), route[rnum]);
1645
rnum--;
1646
}
1647
/* Write first route. */
1648
temp =
1649
hwread(vortex->mmio,
1650
VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1651
if (temp == ADB_MASK) {
1652
/* First entry on this channel. */
1653
hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1654
route[0]);
1655
vortex_adb_en_sr(vortex, channel);
1656
return;
1657
}
1658
/* Not first entry on this channel. Need to link. */
1659
do {
1660
prev = temp;
1661
temp =
1662
hwread(vortex->mmio,
1663
VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK;
1664
if ((lifeboat++) > ADB_MASK) {
1665
dev_err(vortex->card->dev,
1666
"vortex_adb_addroutes: unending route! 0x%x\n",
1667
*route);
1668
return;
1669
}
1670
}
1671
while (temp != ADB_MASK);
1672
hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), route[0]);
1673
}
1674
1675
static void
1676
vortex_adb_delroutes(vortex_t * vortex, unsigned char channel,
1677
ADBRamLink route0, ADBRamLink route1)
1678
{
1679
int temp, lifeboat = 0, prev;
1680
1681
/* Find route. */
1682
temp =
1683
hwread(vortex->mmio,
1684
VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1685
if (temp == (route0 & ADB_MASK)) {
1686
temp =
1687
hwread(vortex->mmio,
1688
VORTEX_ADB_RTBASE + ((route1 & ADB_MASK) << 2));
1689
if ((temp & ADB_MASK) == ADB_MASK)
1690
vortex_adb_dis_sr(vortex, channel);
1691
hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1692
temp);
1693
return;
1694
}
1695
do {
1696
prev = temp;
1697
temp =
1698
hwread(vortex->mmio,
1699
VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK;
1700
if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) {
1701
dev_err(vortex->card->dev,
1702
"vortex_adb_delroutes: route not found! 0x%x\n",
1703
route0);
1704
return;
1705
}
1706
}
1707
while (temp != (route0 & ADB_MASK));
1708
temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1709
if ((temp & ADB_MASK) == route1)
1710
temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1711
/* Make bridge over deleted route. */
1712
hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), temp);
1713
}
1714
1715
static void
1716
vortex_route(vortex_t * vortex, int en, unsigned char channel,
1717
unsigned char source, unsigned char dest)
1718
{
1719
ADBRamLink route;
1720
1721
route = ((source & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1722
if (en) {
1723
vortex_adb_addroutes(vortex, channel, &route, 1);
1724
if ((source < (OFFSET_SRCOUT + NR_SRC))
1725
&& (source >= OFFSET_SRCOUT))
1726
vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1727
channel);
1728
else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1729
&& (source >= OFFSET_MIXOUT))
1730
vortex_mixer_addWTD(vortex,
1731
(source - OFFSET_MIXOUT), channel);
1732
} else {
1733
vortex_adb_delroutes(vortex, channel, route, route);
1734
if ((source < (OFFSET_SRCOUT + NR_SRC))
1735
&& (source >= OFFSET_SRCOUT))
1736
vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1737
channel);
1738
else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1739
&& (source >= OFFSET_MIXOUT))
1740
vortex_mixer_delWTD(vortex,
1741
(source - OFFSET_MIXOUT), channel);
1742
}
1743
}
1744
1745
#if 0
1746
static void
1747
vortex_routes(vortex_t * vortex, int en, unsigned char channel,
1748
unsigned char source, unsigned char dest0, unsigned char dest1)
1749
{
1750
ADBRamLink route[2];
1751
1752
route[0] = ((source & ADB_MASK) << ADB_SHIFT) | (dest0 & ADB_MASK);
1753
route[1] = ((source & ADB_MASK) << ADB_SHIFT) | (dest1 & ADB_MASK);
1754
1755
if (en) {
1756
vortex_adb_addroutes(vortex, channel, route, 2);
1757
if ((source < (OFFSET_SRCOUT + NR_SRC))
1758
&& (source >= (OFFSET_SRCOUT)))
1759
vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1760
channel);
1761
else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1762
&& (source >= (OFFSET_MIXOUT)))
1763
vortex_mixer_addWTD(vortex,
1764
(source - OFFSET_MIXOUT), channel);
1765
} else {
1766
vortex_adb_delroutes(vortex, channel, route[0], route[1]);
1767
if ((source < (OFFSET_SRCOUT + NR_SRC))
1768
&& (source >= (OFFSET_SRCOUT)))
1769
vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1770
channel);
1771
else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1772
&& (source >= (OFFSET_MIXOUT)))
1773
vortex_mixer_delWTD(vortex,
1774
(source - OFFSET_MIXOUT), channel);
1775
}
1776
}
1777
1778
#endif
1779
/* Route two sources to same target. Sources must be of same class !!! */
1780
static void
1781
vortex_routeLRT(vortex_t * vortex, int en, unsigned char ch,
1782
unsigned char source0, unsigned char source1,
1783
unsigned char dest)
1784
{
1785
ADBRamLink route[2];
1786
1787
route[0] = ((source0 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1788
route[1] = ((source1 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1789
1790
if (dest < 0x10)
1791
route[1] = (route[1] & ~ADB_MASK) | (dest + 0x20); /* fifo A */
1792
1793
if (en) {
1794
vortex_adb_addroutes(vortex, ch, route, 2);
1795
if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1796
&& (source0 >= OFFSET_SRCOUT)) {
1797
vortex_src_addWTD(vortex,
1798
(source0 - OFFSET_SRCOUT), ch);
1799
vortex_src_addWTD(vortex,
1800
(source1 - OFFSET_SRCOUT), ch);
1801
} else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1802
&& (source0 >= OFFSET_MIXOUT)) {
1803
vortex_mixer_addWTD(vortex,
1804
(source0 - OFFSET_MIXOUT), ch);
1805
vortex_mixer_addWTD(vortex,
1806
(source1 - OFFSET_MIXOUT), ch);
1807
}
1808
} else {
1809
vortex_adb_delroutes(vortex, ch, route[0], route[1]);
1810
if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1811
&& (source0 >= OFFSET_SRCOUT)) {
1812
vortex_src_delWTD(vortex,
1813
(source0 - OFFSET_SRCOUT), ch);
1814
vortex_src_delWTD(vortex,
1815
(source1 - OFFSET_SRCOUT), ch);
1816
} else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1817
&& (source0 >= OFFSET_MIXOUT)) {
1818
vortex_mixer_delWTD(vortex,
1819
(source0 - OFFSET_MIXOUT), ch);
1820
vortex_mixer_delWTD(vortex,
1821
(source1 - OFFSET_MIXOUT), ch);
1822
}
1823
}
1824
}
1825
1826
/* Connection stuff */
1827
1828
// Connect adbdma to src('s).
1829
static void
1830
vortex_connection_adbdma_src(vortex_t * vortex, int en, unsigned char ch,
1831
unsigned char adbdma, unsigned char src)
1832
{
1833
vortex_route(vortex, en, ch, ADB_DMA(adbdma), ADB_SRCIN(src));
1834
}
1835
1836
// Connect SRC to mixin.
1837
static void
1838
vortex_connection_src_mixin(vortex_t * vortex, int en,
1839
unsigned char channel, unsigned char src,
1840
unsigned char mixin)
1841
{
1842
vortex_route(vortex, en, channel, ADB_SRCOUT(src), ADB_MIXIN(mixin));
1843
}
1844
1845
// Connect mixin with mix output.
1846
static void
1847
vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
1848
unsigned char mix, int a)
1849
{
1850
if (en) {
1851
vortex_mix_enableinput(vortex, mix, mixin);
1852
vortex_mix_setinputvolumebyte(vortex, mix, mixin, MIX_DEFIGAIN); // added to original code.
1853
} else
1854
vortex_mix_disableinput(vortex, mix, mixin, a);
1855
}
1856
1857
// Connect absolute address to mixin.
1858
static void
1859
vortex_connection_adb_mixin(vortex_t * vortex, int en,
1860
unsigned char channel, unsigned char source,
1861
unsigned char mixin)
1862
{
1863
vortex_route(vortex, en, channel, source, ADB_MIXIN(mixin));
1864
}
1865
1866
static void
1867
vortex_connection_src_adbdma(vortex_t * vortex, int en, unsigned char ch,
1868
unsigned char src, unsigned char adbdma)
1869
{
1870
vortex_route(vortex, en, ch, ADB_SRCOUT(src), ADB_DMA(adbdma));
1871
}
1872
1873
static void
1874
vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
1875
unsigned char ch, unsigned char src0,
1876
unsigned char src1, unsigned char adbdma)
1877
{
1878
1879
vortex_routeLRT(vortex, en, ch, ADB_SRCOUT(src0), ADB_SRCOUT(src1),
1880
ADB_DMA(adbdma));
1881
}
1882
1883
// mix to absolute address.
1884
static void
1885
vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
1886
unsigned char mix, unsigned char dest)
1887
{
1888
vortex_route(vortex, en, ch, ADB_MIXOUT(mix), dest);
1889
vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN); // added to original code.
1890
}
1891
1892
// mixer to src.
1893
static void
1894
vortex_connection_mix_src(vortex_t * vortex, int en, unsigned char ch,
1895
unsigned char mix, unsigned char src)
1896
{
1897
vortex_route(vortex, en, ch, ADB_MIXOUT(mix), ADB_SRCIN(src));
1898
vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN); // added to original code.
1899
}
1900
1901
#if 0
1902
static void
1903
vortex_connection_adbdma_src_src(vortex_t * vortex, int en,
1904
unsigned char channel,
1905
unsigned char adbdma, unsigned char src0,
1906
unsigned char src1)
1907
{
1908
vortex_routes(vortex, en, channel, ADB_DMA(adbdma),
1909
ADB_SRCIN(src0), ADB_SRCIN(src1));
1910
}
1911
1912
// Connect two mix to AdbDma.
1913
static void
1914
vortex_connection_mix_mix_adbdma(vortex_t * vortex, int en,
1915
unsigned char ch, unsigned char mix0,
1916
unsigned char mix1, unsigned char adbdma)
1917
{
1918
1919
ADBRamLink routes[2];
1920
routes[0] =
1921
(((mix0 +
1922
OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | (adbdma & ADB_MASK);
1923
routes[1] =
1924
(((mix1 + OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | ((adbdma +
1925
0x20) &
1926
ADB_MASK);
1927
if (en) {
1928
vortex_adb_addroutes(vortex, ch, routes, 0x2);
1929
vortex_mixer_addWTD(vortex, mix0, ch);
1930
vortex_mixer_addWTD(vortex, mix1, ch);
1931
} else {
1932
vortex_adb_delroutes(vortex, ch, routes[0], routes[1]);
1933
vortex_mixer_delWTD(vortex, mix0, ch);
1934
vortex_mixer_delWTD(vortex, mix1, ch);
1935
}
1936
}
1937
#endif
1938
1939
/* CODEC connect. */
1940
1941
static void
1942
vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[])
1943
{
1944
#ifdef CHIP_AU8820
1945
vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1946
vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1947
#else
1948
#if 1
1949
// Connect front channels through EQ.
1950
vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));
1951
vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));
1952
/* Lower volume, since EQ has some gain. */
1953
vortex_mix_setvolumebyte(vortex, mixers[0], 0);
1954
vortex_mix_setvolumebyte(vortex, mixers[1], 0);
1955
vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));
1956
vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));
1957
1958
/* Check if reg 0x28 has SDAC bit set. */
1959
if (VORTEX_IS_QUAD(vortex)) {
1960
/* Rear channel. Note: ADB_CODECOUT(0+2) and (1+2) is for AC97 modem */
1961
vortex_connection_mix_adb(vortex, en, 0x11, mixers[2],
1962
ADB_CODECOUT(0 + 4));
1963
vortex_connection_mix_adb(vortex, en, 0x11, mixers[3],
1964
ADB_CODECOUT(1 + 4));
1965
/* pr_debug( "SDAC detected "); */
1966
}
1967
#else
1968
// Use plain direct output to codec.
1969
vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1970
vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1971
#endif
1972
#endif
1973
}
1974
1975
static void
1976
vortex_connect_codecrec(vortex_t * vortex, int en, unsigned char mixin0,
1977
unsigned char mixin1)
1978
{
1979
/*
1980
Enable: 0x1, 0x1
1981
Channel: 0x11, 0x11
1982
ADB Source address: 0x48, 0x49
1983
Destination Asp4Topology_0x9c,0x98
1984
*/
1985
vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(0), mixin0);
1986
vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(1), mixin1);
1987
}
1988
1989
// Higher level ADB audio path (de)allocator.
1990
1991
/* Resource manager */
1992
static const int resnum[VORTEX_RESOURCE_LAST] =
1993
{ NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D };
1994
/*
1995
Checkout/Checkin resource of given type.
1996
resmap: resource map to be used. If NULL means that we want to allocate
1997
a DMA resource (root of all other resources of a dma channel).
1998
out: Mean checkout if != 0. Else mean Checkin resource.
1999
restype: Indicates type of resource to be checked in or out.
2000
*/
2001
static int
2002
vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2003
{
2004
int i, qty = resnum[restype], resinuse = 0;
2005
2006
if (out) {
2007
/* Gather used resources by all streams. */
2008
for (i = 0; i < NR_ADB; i++) {
2009
resinuse |= vortex->dma_adb[i].resources[restype];
2010
}
2011
resinuse |= vortex->fixed_res[restype];
2012
/* Find and take free resource. */
2013
for (i = 0; i < qty; i++) {
2014
if ((resinuse & (1 << i)) == 0) {
2015
if (resmap != NULL)
2016
resmap[restype] |= (1 << i);
2017
else
2018
vortex->dma_adb[i].resources[restype] |= (1 << i);
2019
/*
2020
pr_debug(
2021
"vortex: ResManager: type %d out %d\n",
2022
restype, i);
2023
*/
2024
return i;
2025
}
2026
}
2027
} else {
2028
if (resmap == NULL)
2029
return -EINVAL;
2030
/* Checkin first resource of type restype. */
2031
for (i = 0; i < qty; i++) {
2032
if (resmap[restype] & (1 << i)) {
2033
resmap[restype] &= ~(1 << i);
2034
/*
2035
pr_debug(
2036
"vortex: ResManager: type %d in %d\n",
2037
restype, i);
2038
*/
2039
return i;
2040
}
2041
}
2042
}
2043
dev_err(vortex->card->dev,
2044
"FATAL: ResManager: resource type %d exhausted.\n",
2045
restype);
2046
return -ENOMEM;
2047
}
2048
2049
/* Default Connections */
2050
2051
static void vortex_connect_default(vortex_t * vortex, int en)
2052
{
2053
// Connect AC97 codec.
2054
vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2055
VORTEX_RESOURCE_MIXOUT);
2056
vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2057
VORTEX_RESOURCE_MIXOUT);
2058
if (VORTEX_IS_QUAD(vortex)) {
2059
vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2060
VORTEX_RESOURCE_MIXOUT);
2061
vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2062
VORTEX_RESOURCE_MIXOUT);
2063
}
2064
vortex_connect_codecplay(vortex, en, vortex->mixplayb);
2065
2066
vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2067
VORTEX_RESOURCE_MIXIN);
2068
vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2069
VORTEX_RESOURCE_MIXIN);
2070
vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1));
2071
2072
// Connect SPDIF
2073
#ifndef CHIP_AU8820
2074
vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2075
VORTEX_RESOURCE_MIXOUT);
2076
vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2077
VORTEX_RESOURCE_MIXOUT);
2078
vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0],
2079
ADB_SPDIFOUT(0));
2080
vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1],
2081
ADB_SPDIFOUT(1));
2082
#endif
2083
// Connect WT
2084
#ifndef CHIP_AU8810
2085
vortex_wt_connect(vortex, en);
2086
#endif
2087
// A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.
2088
#ifndef CHIP_AU8820
2089
vortex_Vort3D_connect(vortex, en);
2090
#endif
2091
// Connect I2S
2092
2093
// Connect DSP interface for SQ3500 turbo (not here i think...)
2094
2095
// Connect AC98 modem codec
2096
2097
}
2098
2099
/*
2100
Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes
2101
are deallocated.
2102
dma: DMA engine routes to be deallocated when dma >= 0.
2103
nr_ch: Number of channels to be de/allocated.
2104
dir: direction of stream. Uses same values as substream->stream.
2105
type: Type of audio output/source (codec, spdif, i2s, dsp, etc)
2106
Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2107
*/
2108
static int
2109
vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2110
int type, int subdev)
2111
{
2112
stream_t *stream;
2113
int i, en;
2114
struct pcm_vol *p;
2115
2116
if (dma >= 0) {
2117
en = 0;
2118
vortex_adb_checkinout(vortex,
2119
vortex->dma_adb[dma].resources, en,
2120
VORTEX_RESOURCE_DMA);
2121
} else {
2122
en = 1;
2123
dma = vortex_adb_checkinout(vortex, NULL, en,
2124
VORTEX_RESOURCE_DMA);
2125
if (dma < 0)
2126
return -EBUSY;
2127
}
2128
2129
stream = &vortex->dma_adb[dma];
2130
stream->dma = dma;
2131
stream->dir = dir;
2132
stream->type = type;
2133
2134
/* PLAYBACK ROUTES. */
2135
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
2136
int src[4], mix[4], ch_top;
2137
#ifndef CHIP_AU8820
2138
int a3d = 0;
2139
#endif
2140
/* Get SRC and MIXER hardware resources. */
2141
if (stream->type != VORTEX_PCM_SPDIF) {
2142
for (i = 0; i < nr_ch; i++) {
2143
src[i] = vortex_adb_checkinout(vortex,
2144
stream->resources, en,
2145
VORTEX_RESOURCE_SRC);
2146
if (src[i] < 0) {
2147
memset(stream->resources, 0,
2148
sizeof(stream->resources));
2149
return -EBUSY;
2150
}
2151
if (stream->type != VORTEX_PCM_A3D) {
2152
mix[i] = vortex_adb_checkinout(vortex,
2153
stream->resources,
2154
en,
2155
VORTEX_RESOURCE_MIXIN);
2156
if (mix[i] < 0) {
2157
memset(stream->resources,
2158
0,
2159
sizeof(stream->resources));
2160
return -EBUSY;
2161
}
2162
}
2163
}
2164
}
2165
#ifndef CHIP_AU8820
2166
if (stream->type == VORTEX_PCM_A3D) {
2167
a3d = vortex_adb_checkinout(vortex,
2168
stream->resources, en,
2169
VORTEX_RESOURCE_A3D);
2170
if (a3d < 0) {
2171
memset(stream->resources, 0,
2172
sizeof(stream->resources));
2173
dev_err(vortex->card->dev,
2174
"out of A3D sources. Sorry\n");
2175
return -EBUSY;
2176
}
2177
/* (De)Initialize A3D hardware source. */
2178
vortex_Vort3D_InitializeSource(&vortex->a3d[a3d], en,
2179
vortex);
2180
}
2181
/* Make SPDIF out exclusive to "spdif" device when in use. */
2182
if ((stream->type == VORTEX_PCM_SPDIF) && (en)) {
2183
vortex_route(vortex, 0, 0x14,
2184
ADB_MIXOUT(vortex->mixspdif[0]),
2185
ADB_SPDIFOUT(0));
2186
vortex_route(vortex, 0, 0x14,
2187
ADB_MIXOUT(vortex->mixspdif[1]),
2188
ADB_SPDIFOUT(1));
2189
}
2190
#endif
2191
/* Make playback routes. */
2192
for (i = 0; i < nr_ch; i++) {
2193
if (stream->type == VORTEX_PCM_ADB) {
2194
vortex_connection_adbdma_src(vortex, en,
2195
src[nr_ch - 1],
2196
dma,
2197
src[i]);
2198
vortex_connection_src_mixin(vortex, en,
2199
0x11, src[i],
2200
mix[i]);
2201
vortex_connection_mixin_mix(vortex, en,
2202
mix[i],
2203
MIX_PLAYB(i), 0);
2204
#ifndef CHIP_AU8820
2205
vortex_connection_mixin_mix(vortex, en,
2206
mix[i],
2207
MIX_SPDIF(i % 2), 0);
2208
vortex_mix_setinputvolumebyte(vortex,
2209
MIX_SPDIF(i % 2),
2210
mix[i],
2211
MIX_DEFIGAIN);
2212
#endif
2213
}
2214
#ifndef CHIP_AU8820
2215
if (stream->type == VORTEX_PCM_A3D) {
2216
vortex_connection_adbdma_src(vortex, en,
2217
src[nr_ch - 1],
2218
dma,
2219
src[i]);
2220
vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));
2221
/* XTalk test. */
2222
//vortex_route(vortex, en, 0x11, dma, ADB_XTALKIN(i?9:4));
2223
//vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_XTALKIN(i?4:9));
2224
}
2225
if (stream->type == VORTEX_PCM_SPDIF)
2226
vortex_route(vortex, en, 0x14,
2227
ADB_DMA(stream->dma),
2228
ADB_SPDIFOUT(i));
2229
#endif
2230
}
2231
if (stream->type != VORTEX_PCM_SPDIF && stream->type != VORTEX_PCM_A3D) {
2232
ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
2233
for (i = nr_ch; i < ch_top; i++) {
2234
vortex_connection_mixin_mix(vortex, en,
2235
mix[i % nr_ch],
2236
MIX_PLAYB(i), 0);
2237
#ifndef CHIP_AU8820
2238
vortex_connection_mixin_mix(vortex, en,
2239
mix[i % nr_ch],
2240
MIX_SPDIF(i % 2),
2241
0);
2242
vortex_mix_setinputvolumebyte(vortex,
2243
MIX_SPDIF(i % 2),
2244
mix[i % nr_ch],
2245
MIX_DEFIGAIN);
2246
#endif
2247
}
2248
if (stream->type == VORTEX_PCM_ADB && en) {
2249
p = &vortex->pcm_vol[subdev];
2250
p->dma = dma;
2251
for (i = 0; i < nr_ch; i++)
2252
p->mixin[i] = mix[i];
2253
for (i = 0; i < ch_top; i++)
2254
p->vol[i] = 0;
2255
}
2256
}
2257
#ifndef CHIP_AU8820
2258
else {
2259
if (nr_ch == 1 && stream->type == VORTEX_PCM_SPDIF)
2260
vortex_route(vortex, en, 0x14,
2261
ADB_DMA(stream->dma),
2262
ADB_SPDIFOUT(1));
2263
}
2264
/* Reconnect SPDIF out when "spdif" device is down. */
2265
if ((stream->type == VORTEX_PCM_SPDIF) && (!en)) {
2266
vortex_route(vortex, 1, 0x14,
2267
ADB_MIXOUT(vortex->mixspdif[0]),
2268
ADB_SPDIFOUT(0));
2269
vortex_route(vortex, 1, 0x14,
2270
ADB_MIXOUT(vortex->mixspdif[1]),
2271
ADB_SPDIFOUT(1));
2272
}
2273
#endif
2274
/* CAPTURE ROUTES. */
2275
} else {
2276
int src[2], mix[2];
2277
2278
if (nr_ch < 1)
2279
return -EINVAL;
2280
2281
/* Get SRC and MIXER hardware resources. */
2282
for (i = 0; i < nr_ch; i++) {
2283
mix[i] = vortex_adb_checkinout(vortex,
2284
stream->resources, en,
2285
VORTEX_RESOURCE_MIXOUT);
2286
if (mix[i] < 0) {
2287
memset(stream->resources, 0,
2288
sizeof(stream->resources));
2289
return -EBUSY;
2290
}
2291
src[i] = vortex_adb_checkinout(vortex,
2292
stream->resources, en,
2293
VORTEX_RESOURCE_SRC);
2294
if (src[i] < 0) {
2295
memset(stream->resources, 0,
2296
sizeof(stream->resources));
2297
return -EBUSY;
2298
}
2299
}
2300
2301
/* Make capture routes. */
2302
vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0);
2303
vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]);
2304
if (nr_ch == 1) {
2305
vortex_connection_mixin_mix(vortex, en,
2306
MIX_CAPT(1), mix[0], 0);
2307
vortex_connection_src_adbdma(vortex, en,
2308
src[0],
2309
src[0], dma);
2310
} else {
2311
vortex_connection_mixin_mix(vortex, en,
2312
MIX_CAPT(1), mix[1], 0);
2313
vortex_connection_mix_src(vortex, en, 0x11, mix[1],
2314
src[1]);
2315
vortex_connection_src_src_adbdma(vortex, en,
2316
src[1], src[0],
2317
src[1], dma);
2318
}
2319
}
2320
vortex->dma_adb[dma].nr_ch = nr_ch;
2321
2322
#if 0
2323
/* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
2324
if (nr_ch < 4) {
2325
/* Copy stereo to rear channel (surround) */
2326
snd_ac97_write_cache(vortex->codec,
2327
AC97_SIGMATEL_DAC2INVERT,
2328
snd_ac97_read(vortex->codec,
2329
AC97_SIGMATEL_DAC2INVERT)
2330
| 4);
2331
} else {
2332
/* Allow separate front and rear channels. */
2333
snd_ac97_write_cache(vortex->codec,
2334
AC97_SIGMATEL_DAC2INVERT,
2335
snd_ac97_read(vortex->codec,
2336
AC97_SIGMATEL_DAC2INVERT)
2337
& ~((u32)
2338
4));
2339
}
2340
#endif
2341
return dma;
2342
}
2343
2344
/*
2345
Set the SampleRate of the SRC's attached to the given DMA engine.
2346
*/
2347
static void
2348
vortex_adb_setsrc(vortex_t * vortex, int adbdma, unsigned int rate, int dir)
2349
{
2350
stream_t *stream = &(vortex->dma_adb[adbdma]);
2351
int i, cvrt;
2352
2353
/* dir=1:play ; dir=0:rec */
2354
if (dir)
2355
cvrt = SRC_RATIO(rate, 48000);
2356
else
2357
cvrt = SRC_RATIO(48000, rate);
2358
2359
/* Setup SRC's */
2360
for (i = 0; i < NR_SRC; i++) {
2361
if (stream->resources[VORTEX_RESOURCE_SRC] & (1 << i))
2362
vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 1, cvrt, dir);
2363
}
2364
}
2365
2366
// Timer and ISR functions.
2367
2368
static void vortex_settimer(vortex_t * vortex, int period)
2369
{
2370
//set the timer period to <period> 48000ths of a second.
2371
hwwrite(vortex->mmio, VORTEX_IRQ_STAT, period);
2372
}
2373
2374
#if 0
2375
static void vortex_enable_timer_int(vortex_t * card)
2376
{
2377
hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2378
hwread(card->mmio, VORTEX_IRQ_CTRL) | IRQ_TIMER | 0x60);
2379
}
2380
2381
static void vortex_disable_timer_int(vortex_t * card)
2382
{
2383
hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2384
hwread(card->mmio, VORTEX_IRQ_CTRL) & ~IRQ_TIMER);
2385
}
2386
2387
#endif
2388
static void vortex_enable_int(vortex_t * card)
2389
{
2390
// CAsp4ISR__EnableVortexInt_void_
2391
hwwrite(card->mmio, VORTEX_CTRL,
2392
hwread(card->mmio, VORTEX_CTRL) | CTRL_IRQ_ENABLE);
2393
hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2394
(hwread(card->mmio, VORTEX_IRQ_CTRL) & 0xffffefc0) | 0x24);
2395
}
2396
2397
static void vortex_disable_int(vortex_t * card)
2398
{
2399
hwwrite(card->mmio, VORTEX_CTRL,
2400
hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
2401
}
2402
2403
static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2404
{
2405
vortex_t *vortex = dev_id;
2406
int i, handled;
2407
u32 source;
2408
2409
//check if the interrupt is ours.
2410
if (!(hwread(vortex->mmio, VORTEX_STAT) & 0x1))
2411
return IRQ_NONE;
2412
2413
// This is the Interrupt Enable flag we set before (consistency check).
2414
if (!(hwread(vortex->mmio, VORTEX_CTRL) & CTRL_IRQ_ENABLE))
2415
return IRQ_NONE;
2416
2417
source = hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2418
// Reset IRQ flags.
2419
hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, source);
2420
hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2421
// Is at least one IRQ flag set?
2422
if (source == 0) {
2423
dev_err(vortex->card->dev, "missing irq source\n");
2424
return IRQ_NONE;
2425
}
2426
2427
handled = 0;
2428
// Attend every interrupt source.
2429
if (unlikely(source & IRQ_ERR_MASK)) {
2430
if (source & IRQ_FATAL) {
2431
dev_err(vortex->card->dev, "IRQ fatal error\n");
2432
}
2433
if (source & IRQ_PARITY) {
2434
dev_err(vortex->card->dev, "IRQ parity error\n");
2435
}
2436
if (source & IRQ_REG) {
2437
dev_err(vortex->card->dev, "IRQ reg error\n");
2438
}
2439
if (source & IRQ_FIFO) {
2440
dev_err(vortex->card->dev, "IRQ fifo error\n");
2441
}
2442
if (source & IRQ_DMA) {
2443
dev_err(vortex->card->dev, "IRQ dma error\n");
2444
}
2445
handled = 1;
2446
}
2447
if (source & IRQ_PCMOUT) {
2448
/* ALSA period acknowledge. */
2449
spin_lock(&vortex->lock);
2450
for (i = 0; i < NR_ADB; i++) {
2451
if (vortex->dma_adb[i].fifo_status == FIFO_START) {
2452
if (!vortex_adbdma_bufshift(vortex, i))
2453
continue;
2454
spin_unlock(&vortex->lock);
2455
snd_pcm_period_elapsed(vortex->dma_adb[i].
2456
substream);
2457
spin_lock(&vortex->lock);
2458
}
2459
}
2460
#ifndef CHIP_AU8810
2461
for (i = 0; i < NR_WT; i++) {
2462
if (vortex->dma_wt[i].fifo_status == FIFO_START) {
2463
/* FIXME: we ignore the return value from
2464
* vortex_wtdma_bufshift() below as the delta
2465
* calculation seems not working for wavetable
2466
* by some reason
2467
*/
2468
vortex_wtdma_bufshift(vortex, i);
2469
spin_unlock(&vortex->lock);
2470
snd_pcm_period_elapsed(vortex->dma_wt[i].
2471
substream);
2472
spin_lock(&vortex->lock);
2473
}
2474
}
2475
#endif
2476
spin_unlock(&vortex->lock);
2477
handled = 1;
2478
}
2479
//Acknowledge the Timer interrupt
2480
if (source & IRQ_TIMER) {
2481
hwread(vortex->mmio, VORTEX_IRQ_STAT);
2482
handled = 1;
2483
}
2484
if ((source & IRQ_MIDI) && vortex->rmidi) {
2485
snd_mpu401_uart_interrupt(vortex->irq,
2486
vortex->rmidi->private_data);
2487
handled = 1;
2488
}
2489
2490
if (!handled) {
2491
dev_err(vortex->card->dev, "unknown irq source %x\n", source);
2492
}
2493
return IRQ_RETVAL(handled);
2494
}
2495
2496
/* Codec */
2497
2498
#define POLL_COUNT 1000
2499
static void vortex_codec_init(vortex_t * vortex)
2500
{
2501
int i;
2502
2503
for (i = 0; i < 32; i++) {
2504
/* the windows driver writes -i, so we write -i */
2505
hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2506
msleep(2);
2507
}
2508
if (0) {
2509
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
2510
msleep(1);
2511
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2512
msleep(1);
2513
} else {
2514
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2515
msleep(2);
2516
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2517
msleep(2);
2518
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
2519
msleep(2);
2520
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2521
msleep(2);
2522
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2523
msleep(2);
2524
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2525
}
2526
for (i = 0; i < 32; i++) {
2527
hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2528
msleep(5);
2529
}
2530
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
2531
msleep(1);
2532
/* Enable codec channels 0 and 1. */
2533
hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2534
hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
2535
}
2536
2537
static void
2538
vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data)
2539
{
2540
2541
vortex_t *card = (vortex_t *) codec->private_data;
2542
unsigned int lifeboat = 0;
2543
2544
/* wait for transactions to clear */
2545
while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2546
udelay(100);
2547
if (lifeboat++ > POLL_COUNT) {
2548
dev_err(card->card->dev, "ac97 codec stuck busy\n");
2549
return;
2550
}
2551
}
2552
/* write register */
2553
hwwrite(card->mmio, VORTEX_CODEC_IO,
2554
((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2555
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
2556
VORTEX_CODEC_WRITE |
2557
(codec->num << VORTEX_CODEC_ID_SHIFT) );
2558
2559
/* Flush Caches. */
2560
hwread(card->mmio, VORTEX_CODEC_IO);
2561
}
2562
2563
static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr)
2564
{
2565
2566
vortex_t *card = (vortex_t *) codec->private_data;
2567
u32 read_addr, data;
2568
unsigned lifeboat = 0;
2569
2570
/* wait for transactions to clear */
2571
while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2572
udelay(100);
2573
if (lifeboat++ > POLL_COUNT) {
2574
dev_err(card->card->dev, "ac97 codec stuck busy\n");
2575
return 0xffff;
2576
}
2577
}
2578
/* set up read address */
2579
read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2580
(codec->num << VORTEX_CODEC_ID_SHIFT) ;
2581
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
2582
2583
/* wait for address */
2584
do {
2585
udelay(100);
2586
data = hwread(card->mmio, VORTEX_CODEC_IO);
2587
if (lifeboat++ > POLL_COUNT) {
2588
dev_err(card->card->dev,
2589
"ac97 address never arrived\n");
2590
return 0xffff;
2591
}
2592
} while ((data & VORTEX_CODEC_ADDMASK) !=
2593
(addr << VORTEX_CODEC_ADDSHIFT));
2594
2595
/* return data. */
2596
return (u16) (data & VORTEX_CODEC_DATMASK);
2597
}
2598
2599
/* SPDIF support */
2600
2601
static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode)
2602
{
2603
int i, this_38 = 0, this_04 = 0, this_08 = 0, this_0c = 0;
2604
2605
/* CAsp4Spdif::InitializeSpdifHardware(void) */
2606
hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS,
2607
hwread(vortex->mmio, VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
2608
//for (i=0x291D4; i<0x29200; i+=4)
2609
for (i = 0; i < 11; i++)
2610
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1 + (i << 2), 0);
2611
//hwwrite(vortex->mmio, 0x29190, hwread(vortex->mmio, 0x29190) | 0xc0000);
2612
hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2613
hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_SPDIF);
2614
2615
/* CAsp4Spdif::ProgramSRCInHardware(enum SPDIF_SR,enum SPDIFMODE) */
2616
if (this_04 && this_08) {
2617
int edi;
2618
2619
i = (((0x5DC00000 / spdif_sr) + 1) >> 1);
2620
if (i > 0x800) {
2621
if (i < 0x1ffff)
2622
edi = (i >> 1);
2623
else
2624
edi = 0x1ffff;
2625
} else {
2626
edi = 0x800;
2627
}
2628
/* this_04 and this_08 are the CASp4Src's (samplerate converters) */
2629
vortex_src_setupchannel(vortex, this_04, edi, 0, 1,
2630
this_0c, 1, 0, edi, 1);
2631
vortex_src_setupchannel(vortex, this_08, edi, 0, 1,
2632
this_0c, 1, 0, edi, 1);
2633
}
2634
2635
i = spdif_sr;
2636
spdif_sr |= 0x8c;
2637
switch (i) {
2638
case 32000:
2639
this_38 &= 0xFFFFFFFE;
2640
this_38 &= 0xFFFFFFFD;
2641
this_38 &= 0xF3FFFFFF;
2642
this_38 |= 0x03000000; /* set 32khz samplerate */
2643
this_38 &= 0xFFFFFF3F;
2644
spdif_sr &= 0xFFFFFFFD;
2645
spdif_sr |= 1;
2646
break;
2647
case 44100:
2648
this_38 &= 0xFFFFFFFE;
2649
this_38 &= 0xFFFFFFFD;
2650
this_38 &= 0xF0FFFFFF;
2651
this_38 |= 0x03000000;
2652
this_38 &= 0xFFFFFF3F;
2653
spdif_sr &= 0xFFFFFFFC;
2654
break;
2655
case 48000:
2656
if (spdif_mode == 1) {
2657
this_38 &= 0xFFFFFFFE;
2658
this_38 &= 0xFFFFFFFD;
2659
this_38 &= 0xF2FFFFFF;
2660
this_38 |= 0x02000000; /* set 48khz samplerate */
2661
this_38 &= 0xFFFFFF3F;
2662
} else {
2663
/* J. Gordon Wolfe: I think this stuff is for AC3 */
2664
this_38 |= 0x00000003;
2665
this_38 &= 0xFFFFFFBF;
2666
this_38 |= 0x80;
2667
}
2668
spdif_sr |= 2;
2669
spdif_sr &= 0xFFFFFFFE;
2670
break;
2671
2672
}
2673
/* looks like the next 2 lines transfer a 16-bit value into 2 8-bit
2674
registers. seems to be for the standard IEC/SPDIF initialization
2675
stuff */
2676
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
2677
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
2678
hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
2679
}
2680
2681
/* Initialization */
2682
2683
static int vortex_core_init(vortex_t *vortex)
2684
{
2685
2686
dev_info(vortex->card->dev, "init started\n");
2687
/* Hardware Init. */
2688
hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
2689
msleep(5);
2690
hwwrite(vortex->mmio, VORTEX_CTRL,
2691
hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
2692
msleep(5);
2693
/* Reset IRQ flags */
2694
hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
2695
hwread(vortex->mmio, VORTEX_IRQ_STAT);
2696
2697
vortex_codec_init(vortex);
2698
2699
#ifdef CHIP_AU8830
2700
hwwrite(vortex->mmio, VORTEX_CTRL,
2701
hwread(vortex->mmio, VORTEX_CTRL) | 0x1000000);
2702
#endif
2703
2704
/* Init audio engine. */
2705
vortex_adbdma_init(vortex);
2706
hwwrite(vortex->mmio, VORTEX_ENGINE_CTRL, 0x0); //, 0xc83c7e58, 0xc5f93e58
2707
vortex_adb_init(vortex);
2708
/* Init processing blocks. */
2709
vortex_fifo_init(vortex);
2710
vortex_mixer_init(vortex);
2711
vortex_srcblock_init(vortex);
2712
#ifndef CHIP_AU8820
2713
vortex_eq_init(vortex);
2714
vortex_spdif_init(vortex, 48000, 1);
2715
vortex_Vort3D_enable(vortex);
2716
#endif
2717
#ifndef CHIP_AU8810
2718
vortex_wt_init(vortex);
2719
#endif
2720
// Moved to au88x0.c
2721
//vortex_connect_default(vortex, 1);
2722
2723
vortex_settimer(vortex, 0x90);
2724
// Enable Interrupts.
2725
// vortex_enable_int() must be first !!
2726
// hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2727
// vortex_enable_int(vortex);
2728
//vortex_enable_timer_int(vortex);
2729
//vortex_disable_timer_int(vortex);
2730
2731
dev_info(vortex->card->dev, "init.... done.\n");
2732
spin_lock_init(&vortex->lock);
2733
2734
return 0;
2735
}
2736
2737
static int vortex_core_shutdown(vortex_t * vortex)
2738
{
2739
2740
dev_info(vortex->card->dev, "shutdown started\n");
2741
#ifndef CHIP_AU8820
2742
vortex_eq_free(vortex);
2743
vortex_Vort3D_disable(vortex);
2744
#endif
2745
//vortex_disable_timer_int(vortex);
2746
vortex_disable_int(vortex);
2747
vortex_connect_default(vortex, 0);
2748
/* Reset all DMA fifos. */
2749
vortex_fifo_init(vortex);
2750
/* Erase all audio routes. */
2751
vortex_adb_init(vortex);
2752
2753
/* Disable MPU401 */
2754
//hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, hwread(vortex->mmio, VORTEX_IRQ_CTRL) & ~IRQ_MIDI);
2755
//hwwrite(vortex->mmio, VORTEX_CTRL, hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_EN);
2756
2757
hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2758
hwwrite(vortex->mmio, VORTEX_CTRL, 0);
2759
msleep(5);
2760
hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
2761
2762
dev_info(vortex->card->dev, "shutdown.... done.\n");
2763
return 0;
2764
}
2765
2766
/* Alsa support. */
2767
2768
static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v)
2769
{
2770
int fmt;
2771
2772
switch (alsafmt) {
2773
case SNDRV_PCM_FORMAT_U8:
2774
fmt = 0x1;
2775
break;
2776
case SNDRV_PCM_FORMAT_MU_LAW:
2777
fmt = 0x2;
2778
break;
2779
case SNDRV_PCM_FORMAT_A_LAW:
2780
fmt = 0x3;
2781
break;
2782
case SNDRV_PCM_FORMAT_SPECIAL:
2783
fmt = 0x4; /* guess. */
2784
break;
2785
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
2786
fmt = 0x5; /* guess. */
2787
break;
2788
case SNDRV_PCM_FORMAT_S16_LE:
2789
fmt = 0x8;
2790
break;
2791
case SNDRV_PCM_FORMAT_S16_BE:
2792
fmt = 0x9; /* check this... */
2793
break;
2794
default:
2795
fmt = 0x8;
2796
dev_err(v->card->dev,
2797
"format unsupported %d\n", alsafmt);
2798
break;
2799
}
2800
return fmt;
2801
}
2802
2803
/* Some not yet useful translations. */
2804
#if 0
2805
typedef enum {
2806
ASPFMTLINEAR16 = 0, /* 0x8 */
2807
ASPFMTLINEAR8, /* 0x1 */
2808
ASPFMTULAW, /* 0x2 */
2809
ASPFMTALAW, /* 0x3 */
2810
ASPFMTSPORT, /* ? */
2811
ASPFMTSPDIF, /* ? */
2812
} ASPENCODING;
2813
2814
static int
2815
vortex_translateformat(vortex_t * vortex, char bits, char nch, int encod)
2816
{
2817
int a, this_194;
2818
2819
if ((bits != 8) && (bits != 16))
2820
return -1;
2821
2822
switch (encod) {
2823
case 0:
2824
if (bits == 0x10)
2825
a = 8; // 16 bit
2826
break;
2827
case 1:
2828
if (bits == 8)
2829
a = 1; // 8 bit
2830
break;
2831
case 2:
2832
a = 2; // U_LAW
2833
break;
2834
case 3:
2835
a = 3; // A_LAW
2836
break;
2837
}
2838
switch (nch) {
2839
case 1:
2840
this_194 = 0;
2841
break;
2842
case 2:
2843
this_194 = 1;
2844
break;
2845
case 4:
2846
this_194 = 1;
2847
break;
2848
case 6:
2849
this_194 = 1;
2850
break;
2851
}
2852
return (a);
2853
}
2854
2855
static void vortex_cdmacore_setformat(vortex_t * vortex, int bits, int nch)
2856
{
2857
short int d, this_148;
2858
2859
d = ((bits >> 3) * nch);
2860
this_148 = 0xbb80 / d;
2861
}
2862
#endif
2863
2864