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