linux/sound/pci/au88x0/au88x0_core.c
<<
>>
Prefs
   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 (mjander@users.sourceforge.cl)
  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.
  86static int mchannels[NR_MIXIN];
  87static int rampchs[NR_MIXIN];
  88
  89static 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}
  94static 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
 101static void
 102vortex_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
 111static 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
 119static int
 120vortex_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
 138static unsigned int vortex_mix_boost6db(unsigned char vol)
 139{
 140        return (vol + 8);       /* WOW! what a complex function! */
 141}
 142
 143static 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
 166static int
 167vortex_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
 179static void
 180vortex_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
 193static void
 194vortex_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
 212static void
 213vortex_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
 237static void
 238vortex_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
 246static void
 247vortex_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
 257static void
 258vortex_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
 270static int
 271vortex_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
 298static int
 299vortex_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
 377static 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
 443static 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
 449static 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
 455static 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
 466static 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
 473static void
 474vortex_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
 486static int
 487vortex_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
 504static 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
 516static void
 517vortex_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
 536static int
 537vortex_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*/
 571static 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
 640static 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
 666static int
 667vortex_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
 698static int
 699vortex_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
 778static void
 779vortex_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
 788static 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
 800static 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
 807static void
 808vortex_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
 879static 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
 889static 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
 901static 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
 908static void
 909vortex_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
1035static 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
1077static void vortex_adbdma_init(vortex_t * vortex)
1078{
1079}
1080
1081static 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
1089static 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
1098static void
1099vortex_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        //printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1);
1139        hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0);
1140        hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1);
1141
1142        vortex_adbdma_setfirstbuffer(vortex, adbdma);
1143        vortex_adbdma_setstartbuffer(vortex, adbdma, 0);
1144}
1145
1146static void
1147vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
1148                      int fmt, int d, u32 offset)
1149{
1150        stream_t *dma = &vortex->dma_adb[adbdma];
1151
1152        dma->dma_unknown = d;
1153        dma->dma_ctrl =
1154            ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1155        /* Enable PCMOUT interrupts. */
1156        dma->dma_ctrl =
1157            (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1158
1159        dma->dma_ctrl =
1160            (dma->dma_ctrl & ~DIR_MASK) | ((dir << DIR_SHIFT) & DIR_MASK);
1161        dma->dma_ctrl =
1162            (dma->dma_ctrl & ~FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1163
1164        hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1165                dma->dma_ctrl);
1166        hwread(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2));
1167}
1168
1169static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
1170{
1171        stream_t *dma = &vortex->dma_adb[adbdma];
1172        int page, p, pp, delta, i;
1173
1174        page =
1175            (hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)) &
1176             ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
1177        if (dma->nr_periods >= 4)
1178                delta = (page - dma->period_real) & 3;
1179        else {
1180                delta = (page - dma->period_real);
1181                if (delta < 0)
1182                        delta += dma->nr_periods;
1183        }
1184        if (delta == 0)
1185                return 0;
1186
1187        /* refresh hw page table */
1188        if (dma->nr_periods > 4) {
1189                for (i = 0; i < delta; i++) {
1190                        /* p: audio buffer page index */
1191                        p = dma->period_virt + i + 4;
1192                        if (p >= dma->nr_periods)
1193                                p -= dma->nr_periods;
1194                        /* pp: hardware DMA page index. */
1195                        pp = dma->period_real + i;
1196                        if (pp >= 4)
1197                                pp -= 4;
1198                        //hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
1199                        hwwrite(vortex->mmio,
1200                                VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1201                                snd_pcm_sgbuf_get_addr(dma->substream,
1202                                dma->period_bytes * p));
1203                        /* Force write thru cache. */
1204                        hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
1205                               (((adbdma << 2) + pp) << 2));
1206                }
1207        }
1208        dma->period_virt += delta;
1209        dma->period_real = page;
1210        if (dma->period_virt >= dma->nr_periods)
1211                dma->period_virt -= dma->nr_periods;
1212        if (delta != 1)
1213                printk(KERN_INFO "vortex: %d virt=%d, real=%d, delta=%d\n",
1214                       adbdma, dma->period_virt, dma->period_real, delta);
1215
1216        return delta;
1217}
1218
1219
1220static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
1221        stream_t *dma = &vortex->dma_adb[adbdma];
1222        int p, pp, i;
1223
1224        /* refresh hw page table */
1225        for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
1226                /* p: audio buffer page index */
1227                p = dma->period_virt + i;
1228                if (p >= dma->nr_periods)
1229                        p -= dma->nr_periods;
1230                /* pp: hardware DMA page index. */
1231                pp = dma->period_real + i;
1232                if (dma->nr_periods < 4) {
1233                        if (pp >= dma->nr_periods)
1234                                pp -= dma->nr_periods;
1235                }
1236                else {
1237                        if (pp >= 4)
1238                                pp -= 4;
1239                }
1240                hwwrite(vortex->mmio,
1241                        VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1242                        snd_pcm_sgbuf_get_addr(dma->substream,
1243                                               dma->period_bytes * p));
1244                /* Force write thru cache. */
1245                hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
1246        }
1247}
1248
1249static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
1250{
1251        stream_t *dma = &vortex->dma_adb[adbdma];
1252        int temp;
1253
1254        temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
1255        temp = (dma->period_virt * dma->period_bytes) + (temp & POS_MASK);
1256        return (temp);
1257}
1258
1259static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
1260{
1261        int this_8 = 0 /*empty */ , this_4 = 0 /*priority */ ;
1262        stream_t *dma = &vortex->dma_adb[adbdma];
1263
1264        switch (dma->fifo_status) {
1265        case FIFO_START:
1266                vortex_fifo_setadbvalid(vortex, adbdma,
1267                                        dma->fifo_enabled ? 1 : 0);
1268                break;
1269        case FIFO_STOP:
1270                this_8 = 1;
1271                hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1272                        dma->dma_ctrl);
1273                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1274                                       this_4, this_8,
1275                                       dma->fifo_enabled ? 1 : 0, 0);
1276                break;
1277        case FIFO_PAUSE:
1278                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1279                                       this_4, this_8,
1280                                       dma->fifo_enabled ? 1 : 0, 0);
1281                break;
1282        }
1283        dma->fifo_status = FIFO_START;
1284}
1285
1286static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma)
1287{
1288        stream_t *dma = &vortex->dma_adb[adbdma];
1289
1290        int this_8 = 1, this_4 = 0;
1291        switch (dma->fifo_status) {
1292        case FIFO_STOP:
1293                hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1294                        dma->dma_ctrl);
1295                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1296                                       this_4, this_8,
1297                                       dma->fifo_enabled ? 1 : 0, 0);
1298                break;
1299        case FIFO_PAUSE:
1300                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1301                                       this_4, this_8,
1302                                       dma->fifo_enabled ? 1 : 0, 0);
1303                break;
1304        }
1305        dma->fifo_status = FIFO_START;
1306}
1307
1308static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma)
1309{
1310        stream_t *dma = &vortex->dma_adb[adbdma];
1311
1312        int this_8 = 0, this_4 = 0;
1313        switch (dma->fifo_status) {
1314        case FIFO_START:
1315                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1316                                       this_4, this_8, 0, 0);
1317                break;
1318        case FIFO_STOP:
1319                hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1320                        dma->dma_ctrl);
1321                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1322                                       this_4, this_8, 0, 0);
1323                break;
1324        }
1325        dma->fifo_status = FIFO_PAUSE;
1326}
1327
1328#if 0                           // Using pause instead
1329static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma)
1330{
1331        stream_t *dma = &vortex->dma_adb[adbdma];
1332
1333        int this_4 = 0, this_8 = 0;
1334        if (dma->fifo_status == FIFO_START)
1335                vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1336                                       this_4, this_8, 0, 0);
1337        else if (dma->fifo_status == FIFO_STOP)
1338                return;
1339        dma->fifo_status = FIFO_STOP;
1340        dma->fifo_enabled = 0;
1341}
1342
1343#endif
1344/* WTDMA */
1345
1346#ifndef CHIP_AU8810
1347static void vortex_wtdma_setfirstbuffer(vortex_t * vortex, int wtdma)
1348{
1349        //int this_7c=dma_ctrl;
1350        stream_t *dma = &vortex->dma_wt[wtdma];
1351
1352        hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1353}
1354
1355static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
1356{
1357        stream_t *dma = &vortex->dma_wt[wtdma];
1358        //hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2), sb << ((0x1f-(wtdma&0xf)*2)));
1359        hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2),
1360                sb << ((0xf - (wtdma & 0xf)) * 2));
1361        dma->period_real = dma->period_virt = sb;
1362}
1363
1364static void
1365vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
1366                        int psize, int count)
1367{
1368        stream_t *dma = &vortex->dma_wt[wtdma];
1369
1370        dma->period_bytes = psize;
1371        dma->nr_periods = count;
1372
1373        dma->cfg0 = 0;
1374        dma->cfg1 = 0;
1375        switch (count) {
1376                /* Four or more pages */
1377        default:
1378        case 4:
1379                dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
1380                hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
1381                        snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
1382                /* 3 pages */
1383        case 3:
1384                dma->cfg0 |= 0x12000000;
1385                dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1386                hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4)  + 0x8,
1387                        snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
1388                /* 2 pages */
1389        case 2:
1390                dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
1391                hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
1392                        snd_pcm_sgbuf_get_addr(dma->substream, psize));
1393                /* 1 page */
1394        case 1:
1395                dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1396                hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
1397                        snd_pcm_sgbuf_get_addr(dma->substream, 0));
1398                break;
1399        }
1400        hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
1401        hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG1 + (wtdma << 3), dma->cfg1);
1402
1403        vortex_wtdma_setfirstbuffer(vortex, wtdma);
1404        vortex_wtdma_setstartbuffer(vortex, wtdma, 0);
1405}
1406
1407static void
1408vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,
1409                     /*int e, */ u32 offset)
1410{
1411        stream_t *dma = &vortex->dma_wt[wtdma];
1412
1413        //dma->this_08 = e;
1414        dma->dma_unknown = d;
1415        dma->dma_ctrl = 0;
1416        dma->dma_ctrl =
1417            ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1418        /* PCMOUT interrupt */
1419        dma->dma_ctrl =
1420            (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1421        /* Always playback. */
1422        dma->dma_ctrl |= (1 << DIR_SHIFT);
1423        /* Audio Format */
1424        dma->dma_ctrl =
1425            (dma->dma_ctrl & FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1426        /* Write into hardware */
1427        hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1428}
1429
1430static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
1431{
1432        stream_t *dma = &vortex->dma_wt[wtdma];
1433        int page, p, pp, delta, i;
1434
1435        page =
1436            (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
1437             WT_SUBBUF_MASK)
1438            >> WT_SUBBUF_SHIFT;
1439        if (dma->nr_periods >= 4)
1440                delta = (page - dma->period_real) & 3;
1441        else {
1442                delta = (page - dma->period_real);
1443                if (delta < 0)
1444                        delta += dma->nr_periods;
1445        }
1446        if (delta == 0)
1447                return 0;
1448
1449        /* refresh hw page table */
1450        if (dma->nr_periods > 4) {
1451                for (i = 0; i < delta; i++) {
1452                        /* p: audio buffer page index */
1453                        p = dma->period_virt + i + 4;
1454                        if (p >= dma->nr_periods)
1455                                p -= dma->nr_periods;
1456                        /* pp: hardware DMA page index. */
1457                        pp = dma->period_real + i;
1458                        if (pp >= 4)
1459                                pp -= 4;
1460                        hwwrite(vortex->mmio,
1461                                VORTEX_WTDMA_BUFBASE +
1462                                (((wtdma << 2) + pp) << 2),
1463                                snd_pcm_sgbuf_get_addr(dma->substream,
1464                                                       dma->period_bytes * p));
1465                        /* Force write thru cache. */
1466                        hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
1467                               (((wtdma << 2) + pp) << 2));
1468                }
1469        }
1470        dma->period_virt += delta;
1471        if (dma->period_virt >= dma->nr_periods)
1472                dma->period_virt -= dma->nr_periods;
1473        dma->period_real = page;
1474
1475        if (delta != 1)
1476                printk(KERN_WARNING "vortex: wt virt = %d, delta = %d\n",
1477                       dma->period_virt, delta);
1478
1479        return delta;
1480}
1481
1482#if 0
1483static void
1484vortex_wtdma_getposition(vortex_t * vortex, int wtdma, int *subbuf, int *pos)
1485{
1486        int temp;
1487        temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1488        *subbuf = (temp >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
1489        *pos = temp & POS_MASK;
1490}
1491
1492static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma)
1493{
1494        return ((hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) >>
1495                 POS_SHIFT) & POS_MASK);
1496}
1497#endif
1498static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
1499{
1500        stream_t *dma = &vortex->dma_wt[wtdma];
1501        int temp;
1502
1503        temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1504        //temp = (temp & POS_MASK) + (((temp>>WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK)*(dma->cfg0&POS_MASK));
1505        temp = (temp & POS_MASK) + ((dma->period_virt) * (dma->period_bytes));
1506        return temp;
1507}
1508
1509static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma)
1510{
1511        stream_t *dma = &vortex->dma_wt[wtdma];
1512        int this_8 = 0, this_4 = 0;
1513
1514        switch (dma->fifo_status) {
1515        case FIFO_START:
1516                vortex_fifo_setwtvalid(vortex, wtdma,
1517                                       dma->fifo_enabled ? 1 : 0);
1518                break;
1519        case FIFO_STOP:
1520                this_8 = 1;
1521                hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1522                        dma->dma_ctrl);
1523                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1524                                      this_4, this_8,
1525                                      dma->fifo_enabled ? 1 : 0, 0);
1526                break;
1527        case FIFO_PAUSE:
1528                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1529                                      this_4, this_8,
1530                                      dma->fifo_enabled ? 1 : 0, 0);
1531                break;
1532        }
1533        dma->fifo_status = FIFO_START;
1534}
1535
1536static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma)
1537{
1538        stream_t *dma = &vortex->dma_wt[wtdma];
1539
1540        int this_8 = 0, this_4 = 0;
1541        switch (dma->fifo_status) {
1542        case FIFO_STOP:
1543                hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1544                        dma->dma_ctrl);
1545                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1546                                      this_4, this_8,
1547                                      dma->fifo_enabled ? 1 : 0, 0);
1548                break;
1549        case FIFO_PAUSE:
1550                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1551                                      this_4, this_8,
1552                                      dma->fifo_enabled ? 1 : 0, 0);
1553                break;
1554        }
1555        dma->fifo_status = FIFO_START;
1556}
1557
1558static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma)
1559{
1560        stream_t *dma = &vortex->dma_wt[wtdma];
1561
1562        int this_8 = 0, this_4 = 0;
1563        switch (dma->fifo_status) {
1564        case FIFO_START:
1565                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1566                                      this_4, this_8, 0, 0);
1567                break;
1568        case FIFO_STOP:
1569                hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1570                        dma->dma_ctrl);
1571                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1572                                      this_4, this_8, 0, 0);
1573                break;
1574        }
1575        dma->fifo_status = FIFO_PAUSE;
1576}
1577
1578static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma)
1579{
1580        stream_t *dma = &vortex->dma_wt[wtdma];
1581
1582        int this_4 = 0, this_8 = 0;
1583        if (dma->fifo_status == FIFO_START)
1584                vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1585                                      this_4, this_8, 0, 0);
1586        else if (dma->fifo_status == FIFO_STOP)
1587                return;
1588        dma->fifo_status = FIFO_STOP;
1589        dma->fifo_enabled = 0;
1590}
1591
1592#endif
1593/* ADB Routes */
1594
1595typedef int ADBRamLink;
1596static void vortex_adb_init(vortex_t * vortex)
1597{
1598        int i;
1599        /* it looks like we are writing more than we need to...
1600         * if we write what we are supposed to it breaks things... */
1601        hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);
1602        for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)
1603                hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),
1604                        hwread(vortex->mmio,
1605                               VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);
1606        for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {
1607                hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),
1608                        hwread(vortex->mmio,
1609                               VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);
1610        }
1611}
1612
1613static void vortex_adb_en_sr(vortex_t * vortex, int channel)
1614{
1615        hwwrite(vortex->mmio, VORTEX_ADB_SR,
1616                hwread(vortex->mmio, VORTEX_ADB_SR) | (0x1 << channel));
1617}
1618
1619static void vortex_adb_dis_sr(vortex_t * vortex, int channel)
1620{
1621        hwwrite(vortex->mmio, VORTEX_ADB_SR,
1622                hwread(vortex->mmio, VORTEX_ADB_SR) & ~(0x1 << channel));
1623}
1624
1625static void
1626vortex_adb_addroutes(vortex_t * vortex, unsigned char channel,
1627                     ADBRamLink * route, int rnum)
1628{
1629        int temp, prev, lifeboat = 0;
1630
1631        if ((rnum <= 0) || (route == NULL))
1632                return;
1633        /* Write last routes. */
1634        rnum--;
1635        hwwrite(vortex->mmio,
1636                VORTEX_ADB_RTBASE + ((route[rnum] & ADB_MASK) << 2),
1637                ROUTE_MASK);
1638        while (rnum > 0) {
1639                hwwrite(vortex->mmio,
1640                        VORTEX_ADB_RTBASE +
1641                        ((route[rnum - 1] & ADB_MASK) << 2), route[rnum]);
1642                rnum--;
1643        }
1644        /* Write first route. */
1645        temp =
1646            hwread(vortex->mmio,
1647                   VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1648        if (temp == ADB_MASK) {
1649                /* First entry on this channel. */
1650                hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1651                        route[0]);
1652                vortex_adb_en_sr(vortex, channel);
1653                return;
1654        }
1655        /* Not first entry on this channel. Need to link. */
1656        do {
1657                prev = temp;
1658                temp =
1659                    hwread(vortex->mmio,
1660                           VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK;
1661                if ((lifeboat++) > ADB_MASK) {
1662                        printk(KERN_ERR
1663                               "vortex_adb_addroutes: unending route! 0x%x\n",
1664                               *route);
1665                        return;
1666                }
1667        }
1668        while (temp != ADB_MASK);
1669        hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), route[0]);
1670}
1671
1672static void
1673vortex_adb_delroutes(vortex_t * vortex, unsigned char channel,
1674                     ADBRamLink route0, ADBRamLink route1)
1675{
1676        int temp, lifeboat = 0, prev;
1677
1678        /* Find route. */
1679        temp =
1680            hwread(vortex->mmio,
1681                   VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1682        if (temp == (route0 & ADB_MASK)) {
1683                temp =
1684                    hwread(vortex->mmio,
1685                           VORTEX_ADB_RTBASE + ((route1 & ADB_MASK) << 2));
1686                if ((temp & ADB_MASK) == ADB_MASK)
1687                        vortex_adb_dis_sr(vortex, channel);
1688                hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1689                        temp);
1690                return;
1691        }
1692        do {
1693                prev = temp;
1694                temp =
1695                    hwread(vortex->mmio,
1696                           VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK;
1697                if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) {
1698                        printk(KERN_ERR
1699                               "vortex_adb_delroutes: route not found! 0x%x\n",
1700                               route0);
1701                        return;
1702                }
1703        }
1704        while (temp != (route0 & ADB_MASK));
1705        temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1706        if ((temp & ADB_MASK) == route1)
1707                temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1708        /* Make bridge over deleted route. */
1709        hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), temp);
1710}
1711
1712static void
1713vortex_route(vortex_t * vortex, int en, unsigned char channel,
1714             unsigned char source, unsigned char dest)
1715{
1716        ADBRamLink route;
1717
1718        route = ((source & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1719        if (en) {
1720                vortex_adb_addroutes(vortex, channel, &route, 1);
1721                if ((source < (OFFSET_SRCOUT + NR_SRC))
1722                    && (source >= OFFSET_SRCOUT))
1723                        vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1724                                          channel);
1725                else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1726                         && (source >= OFFSET_MIXOUT))
1727                        vortex_mixer_addWTD(vortex,
1728                                            (source - OFFSET_MIXOUT), channel);
1729        } else {
1730                vortex_adb_delroutes(vortex, channel, route, route);
1731                if ((source < (OFFSET_SRCOUT + NR_SRC))
1732                    && (source >= OFFSET_SRCOUT))
1733                        vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1734                                          channel);
1735                else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1736                         && (source >= OFFSET_MIXOUT))
1737                        vortex_mixer_delWTD(vortex,
1738                                            (source - OFFSET_MIXOUT), channel);
1739        }
1740}
1741
1742#if 0
1743static void
1744vortex_routes(vortex_t * vortex, int en, unsigned char channel,
1745              unsigned char source, unsigned char dest0, unsigned char dest1)
1746{
1747        ADBRamLink route[2];
1748
1749        route[0] = ((source & ADB_MASK) << ADB_SHIFT) | (dest0 & ADB_MASK);
1750        route[1] = ((source & ADB_MASK) << ADB_SHIFT) | (dest1 & ADB_MASK);
1751
1752        if (en) {
1753                vortex_adb_addroutes(vortex, channel, route, 2);
1754                if ((source < (OFFSET_SRCOUT + NR_SRC))
1755                    && (source >= (OFFSET_SRCOUT)))
1756                        vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1757                                          channel);
1758                else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1759                         && (source >= (OFFSET_MIXOUT)))
1760                        vortex_mixer_addWTD(vortex,
1761                                            (source - OFFSET_MIXOUT), channel);
1762        } else {
1763                vortex_adb_delroutes(vortex, channel, route[0], route[1]);
1764                if ((source < (OFFSET_SRCOUT + NR_SRC))
1765                    && (source >= (OFFSET_SRCOUT)))
1766                        vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1767                                          channel);
1768                else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1769                         && (source >= (OFFSET_MIXOUT)))
1770                        vortex_mixer_delWTD(vortex,
1771                                            (source - OFFSET_MIXOUT), channel);
1772        }
1773}
1774
1775#endif
1776/* Route two sources to same target. Sources must be of same class !!! */
1777static void
1778vortex_routeLRT(vortex_t * vortex, int en, unsigned char ch,
1779                unsigned char source0, unsigned char source1,
1780                unsigned char dest)
1781{
1782        ADBRamLink route[2];
1783
1784        route[0] = ((source0 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1785        route[1] = ((source1 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1786
1787        if (dest < 0x10)
1788                route[1] = (route[1] & ~ADB_MASK) | (dest + 0x20);      /* fifo A */
1789
1790        if (en) {
1791                vortex_adb_addroutes(vortex, ch, route, 2);
1792                if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1793                    && (source0 >= OFFSET_SRCOUT)) {
1794                        vortex_src_addWTD(vortex,
1795                                          (source0 - OFFSET_SRCOUT), ch);
1796                        vortex_src_addWTD(vortex,
1797                                          (source1 - OFFSET_SRCOUT), ch);
1798                } else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1799                           && (source0 >= OFFSET_MIXOUT)) {
1800                        vortex_mixer_addWTD(vortex,
1801                                            (source0 - OFFSET_MIXOUT), ch);
1802                        vortex_mixer_addWTD(vortex,
1803                                            (source1 - OFFSET_MIXOUT), ch);
1804                }
1805        } else {
1806                vortex_adb_delroutes(vortex, ch, route[0], route[1]);
1807                if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1808                    && (source0 >= OFFSET_SRCOUT)) {
1809                        vortex_src_delWTD(vortex,
1810                                          (source0 - OFFSET_SRCOUT), ch);
1811                        vortex_src_delWTD(vortex,
1812                                          (source1 - OFFSET_SRCOUT), ch);
1813                } else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1814                           && (source0 >= OFFSET_MIXOUT)) {
1815                        vortex_mixer_delWTD(vortex,
1816                                            (source0 - OFFSET_MIXOUT), ch);
1817                        vortex_mixer_delWTD(vortex,
1818                                            (source1 - OFFSET_MIXOUT), ch);
1819                }
1820        }
1821}
1822
1823/* Connection stuff */
1824
1825// Connect adbdma to src('s).
1826static void
1827vortex_connection_adbdma_src(vortex_t * vortex, int en, unsigned char ch,
1828                             unsigned char adbdma, unsigned char src)
1829{
1830        vortex_route(vortex, en, ch, ADB_DMA(adbdma), ADB_SRCIN(src));
1831}
1832
1833// Connect SRC to mixin.
1834static void
1835vortex_connection_src_mixin(vortex_t * vortex, int en,
1836                            unsigned char channel, unsigned char src,
1837                            unsigned char mixin)
1838{
1839        vortex_route(vortex, en, channel, ADB_SRCOUT(src), ADB_MIXIN(mixin));
1840}
1841
1842// Connect mixin with mix output.
1843static void
1844vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
1845                            unsigned char mix, int a)
1846{
1847        if (en) {
1848                vortex_mix_enableinput(vortex, mix, mixin);
1849                vortex_mix_setinputvolumebyte(vortex, mix, mixin, MIX_DEFIGAIN);        // added to original code.
1850        } else
1851                vortex_mix_disableinput(vortex, mix, mixin, a);
1852}
1853
1854// Connect absolut address to mixin.
1855static void
1856vortex_connection_adb_mixin(vortex_t * vortex, int en,
1857                            unsigned char channel, unsigned char source,
1858                            unsigned char mixin)
1859{
1860        vortex_route(vortex, en, channel, source, ADB_MIXIN(mixin));
1861}
1862
1863static void
1864vortex_connection_src_adbdma(vortex_t * vortex, int en, unsigned char ch,
1865                             unsigned char src, unsigned char adbdma)
1866{
1867        vortex_route(vortex, en, ch, ADB_SRCOUT(src), ADB_DMA(adbdma));
1868}
1869
1870static void
1871vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
1872                                 unsigned char ch, unsigned char src0,
1873                                 unsigned char src1, unsigned char adbdma)
1874{
1875
1876        vortex_routeLRT(vortex, en, ch, ADB_SRCOUT(src0), ADB_SRCOUT(src1),
1877                        ADB_DMA(adbdma));
1878}
1879
1880// mix to absolut address.
1881static void
1882vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
1883                          unsigned char mix, unsigned char dest)
1884{
1885        vortex_route(vortex, en, ch, ADB_MIXOUT(mix), dest);
1886        vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN);    // added to original code.
1887}
1888
1889// mixer to src.
1890static void
1891vortex_connection_mix_src(vortex_t * vortex, int en, unsigned char ch,
1892                          unsigned char mix, unsigned char src)
1893{
1894        vortex_route(vortex, en, ch, ADB_MIXOUT(mix), ADB_SRCIN(src));
1895        vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN);    // added to original code.
1896}
1897
1898#if 0
1899static void
1900vortex_connection_adbdma_src_src(vortex_t * vortex, int en,
1901                                 unsigned char channel,
1902                                 unsigned char adbdma, unsigned char src0,
1903                                 unsigned char src1)
1904{
1905        vortex_routes(vortex, en, channel, ADB_DMA(adbdma),
1906                      ADB_SRCIN(src0), ADB_SRCIN(src1));
1907}
1908
1909// Connect two mix to AdbDma.
1910static void
1911vortex_connection_mix_mix_adbdma(vortex_t * vortex, int en,
1912                                 unsigned char ch, unsigned char mix0,
1913                                 unsigned char mix1, unsigned char adbdma)
1914{
1915
1916        ADBRamLink routes[2];
1917        routes[0] =
1918            (((mix0 +
1919               OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | (adbdma & ADB_MASK);
1920        routes[1] =
1921            (((mix1 + OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | ((adbdma +
1922                                                                   0x20) &
1923                                                                  ADB_MASK);
1924        if (en) {
1925                vortex_adb_addroutes(vortex, ch, routes, 0x2);
1926                vortex_mixer_addWTD(vortex, mix0, ch);
1927                vortex_mixer_addWTD(vortex, mix1, ch);
1928        } else {
1929                vortex_adb_delroutes(vortex, ch, routes[0], routes[1]);
1930                vortex_mixer_delWTD(vortex, mix0, ch);
1931                vortex_mixer_delWTD(vortex, mix1, ch);
1932        }
1933}
1934#endif
1935
1936/* CODEC connect. */
1937
1938static void
1939vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[])
1940{
1941#ifdef CHIP_AU8820
1942        vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1943        vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1944#else
1945#if 1
1946        // Connect front channels through EQ.
1947        vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));
1948        vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));
1949        /* Lower volume, since EQ has some gain. */
1950        vortex_mix_setvolumebyte(vortex, mixers[0], 0);
1951        vortex_mix_setvolumebyte(vortex, mixers[1], 0);
1952        vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));
1953        vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));
1954
1955        /* Check if reg 0x28 has SDAC bit set. */
1956        if (VORTEX_IS_QUAD(vortex)) {
1957                /* Rear channel. Note: ADB_CODECOUT(0+2) and (1+2) is for AC97 modem */
1958                vortex_connection_mix_adb(vortex, en, 0x11, mixers[2],
1959                                          ADB_CODECOUT(0 + 4));
1960                vortex_connection_mix_adb(vortex, en, 0x11, mixers[3],
1961                                          ADB_CODECOUT(1 + 4));
1962                //printk("SDAC detected ");
1963        }
1964#else
1965        // Use plain direct output to codec.
1966        vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1967        vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1968#endif
1969#endif
1970}
1971
1972static void
1973vortex_connect_codecrec(vortex_t * vortex, int en, unsigned char mixin0,
1974                        unsigned char mixin1)
1975{
1976        /*
1977           Enable: 0x1, 0x1
1978           Channel: 0x11, 0x11
1979           ADB Source address: 0x48, 0x49
1980           Destination Asp4Topology_0x9c,0x98
1981         */
1982        vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(0), mixin0);
1983        vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(1), mixin1);
1984}
1985
1986// Higher level ADB audio path (de)allocator.
1987
1988/* Resource manager */
1989static int resnum[VORTEX_RESOURCE_LAST] =
1990    { NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D };
1991/*
1992 Checkout/Checkin resource of given type. 
1993 resmap: resource map to be used. If NULL means that we want to allocate
1994 a DMA resource (root of all other resources of a dma channel).
1995 out: Mean checkout if != 0. Else mean Checkin resource.
1996 restype: Indicates type of resource to be checked in or out.
1997*/
1998static char
1999vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2000{
2001        int i, qty = resnum[restype], resinuse = 0;
2002
2003        if (out) {
2004                /* Gather used resources by all streams. */
2005                for (i = 0; i < NR_ADB; i++) {
2006                        resinuse |= vortex->dma_adb[i].resources[restype];
2007                }
2008                resinuse |= vortex->fixed_res[restype];
2009                /* Find and take free resource. */
2010                for (i = 0; i < qty; i++) {
2011                        if ((resinuse & (1 << i)) == 0) {
2012                                if (resmap != NULL)
2013                                        resmap[restype] |= (1 << i);
2014                                else
2015                                        vortex->dma_adb[i].resources[restype] |= (1 << i);
2016                                //printk("vortex: ResManager: type %d out %d\n", restype, i);
2017                                return i;
2018                        }
2019                }
2020        } else {
2021                if (resmap == NULL)
2022                        return -EINVAL;
2023                /* Checkin first resource of type restype. */
2024                for (i = 0; i < qty; i++) {
2025                        if (resmap[restype] & (1 << i)) {
2026                                resmap[restype] &= ~(1 << i);
2027                                //printk("vortex: ResManager: type %d in %d\n",restype, i);
2028                                return i;
2029                        }
2030                }
2031        }
2032        printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
2033        return -ENOMEM;
2034}
2035
2036/* Default Connections  */
2037static int
2038vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
2039
2040static void vortex_connect_default(vortex_t * vortex, int en)
2041{
2042        // Connect AC97 codec.
2043        vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2044                                  VORTEX_RESOURCE_MIXOUT);
2045        vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2046                                  VORTEX_RESOURCE_MIXOUT);
2047        if (VORTEX_IS_QUAD(vortex)) {
2048                vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2049                                          VORTEX_RESOURCE_MIXOUT);
2050                vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2051                                          VORTEX_RESOURCE_MIXOUT);
2052        }
2053        vortex_connect_codecplay(vortex, en, vortex->mixplayb);
2054
2055        vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2056                                  VORTEX_RESOURCE_MIXIN);
2057        vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2058                                  VORTEX_RESOURCE_MIXIN);
2059        vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1));
2060
2061        // Connect SPDIF
2062#ifndef CHIP_AU8820
2063        vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2064                                  VORTEX_RESOURCE_MIXOUT);
2065        vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
2066                                  VORTEX_RESOURCE_MIXOUT);
2067        vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0],
2068                                  ADB_SPDIFOUT(0));
2069        vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1],
2070                                  ADB_SPDIFOUT(1));
2071#endif
2072        // Connect WT
2073#ifndef CHIP_AU8810
2074        vortex_wt_connect(vortex, en);
2075#endif
2076        // A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.
2077#ifndef CHIP_AU8820
2078        vortex_Vort3D_connect(vortex, en);
2079#endif
2080        // Connect I2S
2081
2082        // Connect DSP interface for SQ3500 turbo (not here i think...)
2083
2084        // Connect AC98 modem codec
2085        
2086}
2087
2088/*
2089  Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes
2090  are deallocated.
2091  dma: DMA engine routes to be deallocated when dma >= 0.
2092  nr_ch: Number of channels to be de/allocated.
2093  dir: direction of stream. Uses same values as substream->stream.
2094  type: Type of audio output/source (codec, spdif, i2s, dsp, etc)
2095  Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2096*/
2097static int
2098vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
2099{
2100        stream_t *stream;
2101        int i, en;
2102        
2103        if ((nr_ch == 3)
2104            || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
2105                return -EBUSY;
2106
2107        if (dma >= 0) {
2108                en = 0;
2109                vortex_adb_checkinout(vortex,
2110                                      vortex->dma_adb[dma].resources, en,
2111                                      VORTEX_RESOURCE_DMA);
2112        } else {
2113                en = 1;
2114                if ((dma =
2115                     vortex_adb_checkinout(vortex, NULL, en,
2116                                           VORTEX_RESOURCE_DMA)) < 0)
2117                        return -EBUSY;
2118        }
2119
2120        stream = &vortex->dma_adb[dma];
2121        stream->dma = dma;
2122        stream->dir = dir;
2123        stream->type = type;
2124
2125        /* PLAYBACK ROUTES. */
2126        if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
2127                int src[4], mix[4], ch_top;
2128#ifndef CHIP_AU8820
2129                int a3d = 0;
2130#endif
2131                /* Get SRC and MIXER hardware resources. */
2132                if (stream->type != VORTEX_PCM_SPDIF) {
2133                        for (i = 0; i < nr_ch; i++) {
2134                                if ((src[i] = vortex_adb_checkinout(vortex,
2135                                                           stream->resources, en,
2136                                                           VORTEX_RESOURCE_SRC)) < 0) {
2137                                        memset(stream->resources, 0,
2138                                               sizeof(unsigned char) *
2139                                               VORTEX_RESOURCE_LAST);
2140                                        return -EBUSY;
2141                                }
2142                                if (stream->type != VORTEX_PCM_A3D) {
2143                                        if ((mix[i] = vortex_adb_checkinout(vortex,
2144                                                                   stream->resources,
2145                                                                   en,
2146                                                                   VORTEX_RESOURCE_MIXIN)) < 0) {
2147                                                memset(stream->resources,
2148                                                       0,
2149                                                       sizeof(unsigned char) * VORTEX_RESOURCE_LAST);
2150                                                return -EBUSY;
2151                                        }
2152                                }
2153                        }
2154                }
2155#ifndef CHIP_AU8820
2156                if (stream->type == VORTEX_PCM_A3D) {
2157                        if ((a3d =
2158                             vortex_adb_checkinout(vortex,
2159                                                   stream->resources, en,
2160                                                   VORTEX_RESOURCE_A3D)) < 0) {
2161                                memset(stream->resources, 0,
2162                                       sizeof(unsigned char) *
2163                                       VORTEX_RESOURCE_LAST);
2164                                printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
2165                                return -EBUSY;
2166                        }
2167                        /* (De)Initialize A3D hardware source. */
2168                        vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en);
2169                }
2170                /* Make SPDIF out exclusive to "spdif" device when in use. */
2171                if ((stream->type == VORTEX_PCM_SPDIF) && (en)) {
2172                        vortex_route(vortex, 0, 0x14,
2173                                     ADB_MIXOUT(vortex->mixspdif[0]),
2174                                     ADB_SPDIFOUT(0));
2175                        vortex_route(vortex, 0, 0x14,
2176                                     ADB_MIXOUT(vortex->mixspdif[1]),
2177                                     ADB_SPDIFOUT(1));
2178                }
2179#endif
2180                /* Make playback routes. */
2181                for (i = 0; i < nr_ch; i++) {
2182                        if (stream->type == VORTEX_PCM_ADB) {
2183                                vortex_connection_adbdma_src(vortex, en,
2184                                                             src[nr_ch - 1],
2185                                                             dma,
2186                                                             src[i]);
2187                                vortex_connection_src_mixin(vortex, en,
2188                                                            0x11, src[i],
2189                                                            mix[i]);
2190                                vortex_connection_mixin_mix(vortex, en,
2191                                                            mix[i],
2192                                                            MIX_PLAYB(i), 0);
2193#ifndef CHIP_AU8820
2194                                vortex_connection_mixin_mix(vortex, en,
2195                                                            mix[i],
2196                                                            MIX_SPDIF(i % 2), 0);
2197                                vortex_mix_setinputvolumebyte(vortex,
2198                                                              MIX_SPDIF(i % 2),
2199                                                              mix[i],
2200                                                              MIX_DEFIGAIN);
2201#endif
2202                        }
2203#ifndef CHIP_AU8820
2204                        if (stream->type == VORTEX_PCM_A3D) {
2205                                vortex_connection_adbdma_src(vortex, en,
2206                                                             src[nr_ch - 1], 
2207                                                                 dma,
2208                                                             src[i]);
2209                                vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));
2210                                /* XTalk test. */
2211                                //vortex_route(vortex, en, 0x11, dma, ADB_XTALKIN(i?9:4));
2212                                //vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_XTALKIN(i?4:9));
2213                        }
2214                        if (stream->type == VORTEX_PCM_SPDIF)
2215                                vortex_route(vortex, en, 0x14,
2216                                             ADB_DMA(stream->dma),
2217                                             ADB_SPDIFOUT(i));
2218#endif
2219                }
2220                if (stream->type != VORTEX_PCM_SPDIF && stream->type != VORTEX_PCM_A3D) {
2221                        ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
2222                        for (i = nr_ch; i < ch_top; i++) {
2223                                vortex_connection_mixin_mix(vortex, en,
2224                                                            mix[i % nr_ch],
2225                                                            MIX_PLAYB(i), 0);
2226#ifndef CHIP_AU8820
2227                                vortex_connection_mixin_mix(vortex, en,
2228                                                            mix[i % nr_ch],
2229                                                            MIX_SPDIF(i % 2),
2230                                                                0);
2231                                vortex_mix_setinputvolumebyte(vortex,
2232                                                              MIX_SPDIF(i % 2),
2233                                                              mix[i % nr_ch],
2234                                                              MIX_DEFIGAIN);
2235#endif
2236                        }
2237                }
2238#ifndef CHIP_AU8820
2239                else {
2240                        if (nr_ch == 1 && stream->type == VORTEX_PCM_SPDIF)
2241                                vortex_route(vortex, en, 0x14,
2242                                             ADB_DMA(stream->dma),
2243                                             ADB_SPDIFOUT(1));
2244                }
2245                /* Reconnect SPDIF out when "spdif" device is down. */
2246                if ((stream->type == VORTEX_PCM_SPDIF) && (!en)) {
2247                        vortex_route(vortex, 1, 0x14,
2248                                     ADB_MIXOUT(vortex->mixspdif[0]),
2249                                     ADB_SPDIFOUT(0));
2250                        vortex_route(vortex, 1, 0x14,
2251                                     ADB_MIXOUT(vortex->mixspdif[1]),
2252                                     ADB_SPDIFOUT(1));
2253                }
2254#endif
2255        /* CAPTURE ROUTES. */
2256        } else {
2257                int src[2], mix[2];
2258
2259                /* Get SRC and MIXER hardware resources. */
2260                for (i = 0; i < nr_ch; i++) {
2261                        if ((mix[i] =
2262                             vortex_adb_checkinout(vortex,
2263                                                   stream->resources, en,
2264                                                   VORTEX_RESOURCE_MIXOUT))
2265                            < 0) {
2266                                memset(stream->resources, 0,
2267                                       sizeof(unsigned char) *
2268                                       VORTEX_RESOURCE_LAST);
2269                                return -EBUSY;
2270                        }
2271                        if ((src[i] =
2272                             vortex_adb_checkinout(vortex,
2273                                                   stream->resources, en,
2274                                                   VORTEX_RESOURCE_SRC)) < 0) {
2275                                memset(stream->resources, 0,
2276                                       sizeof(unsigned char) *
2277                                       VORTEX_RESOURCE_LAST);
2278                                return -EBUSY;
2279                        }
2280                }
2281
2282                /* Make capture routes. */
2283                vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0);
2284                vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]);
2285                if (nr_ch == 1) {
2286                        vortex_connection_mixin_mix(vortex, en,
2287                                                    MIX_CAPT(1), mix[0], 0);
2288                        vortex_connection_src_adbdma(vortex, en,
2289                                                     src[0],
2290                                                     src[0], dma);
2291                } else {
2292                        vortex_connection_mixin_mix(vortex, en,
2293                                                    MIX_CAPT(1), mix[1], 0);
2294                        vortex_connection_mix_src(vortex, en, 0x11, mix[1],
2295                                                  src[1]);
2296                        vortex_connection_src_src_adbdma(vortex, en,
2297                                                         src[1], src[0],
2298                                                         src[1], dma);
2299                }
2300        }
2301        vortex->dma_adb[dma].nr_ch = nr_ch;
2302
2303#if 0
2304        /* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
2305        if (nr_ch < 4) {
2306                /* Copy stereo to rear channel (surround) */
2307                snd_ac97_write_cache(vortex->codec,
2308                                     AC97_SIGMATEL_DAC2INVERT,
2309                                     snd_ac97_read(vortex->codec,
2310                                                   AC97_SIGMATEL_DAC2INVERT)
2311                                     | 4);
2312        } else {
2313                /* Allow separate front and rear channels. */
2314                snd_ac97_write_cache(vortex->codec,
2315                                     AC97_SIGMATEL_DAC2INVERT,
2316                                     snd_ac97_read(vortex->codec,
2317                                                   AC97_SIGMATEL_DAC2INVERT)
2318                                     & ~((u32)
2319                                         4));
2320        }
2321#endif
2322        return dma;
2323}
2324
2325/*
2326 Set the SampleRate of the SRC's attached to the given DMA engine.
2327 */
2328static void
2329vortex_adb_setsrc(vortex_t * vortex, int adbdma, unsigned int rate, int dir)
2330{
2331        stream_t *stream = &(vortex->dma_adb[adbdma]);
2332        int i, cvrt;
2333
2334        /* dir=1:play ; dir=0:rec */
2335        if (dir)
2336                cvrt = SRC_RATIO(rate, 48000);
2337        else
2338                cvrt = SRC_RATIO(48000, rate);
2339
2340        /* Setup SRC's */
2341        for (i = 0; i < NR_SRC; i++) {
2342                if (stream->resources[VORTEX_RESOURCE_SRC] & (1 << i))
2343                        vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 1, cvrt, dir);
2344        }
2345}
2346
2347// Timer and ISR functions.
2348
2349static void vortex_settimer(vortex_t * vortex, int period)
2350{
2351        //set the timer period to <period> 48000ths of a second.
2352        hwwrite(vortex->mmio, VORTEX_IRQ_STAT, period);
2353}
2354
2355#if 0
2356static void vortex_enable_timer_int(vortex_t * card)
2357{
2358        hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2359                hwread(card->mmio, VORTEX_IRQ_CTRL) | IRQ_TIMER | 0x60);
2360}
2361
2362static void vortex_disable_timer_int(vortex_t * card)
2363{
2364        hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2365                hwread(card->mmio, VORTEX_IRQ_CTRL) & ~IRQ_TIMER);
2366}
2367
2368#endif
2369static void vortex_enable_int(vortex_t * card)
2370{
2371        // CAsp4ISR__EnableVortexInt_void_
2372        hwwrite(card->mmio, VORTEX_CTRL,
2373                hwread(card->mmio, VORTEX_CTRL) | CTRL_IRQ_ENABLE);
2374        hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2375                (hwread(card->mmio, VORTEX_IRQ_CTRL) & 0xffffefc0) | 0x24);
2376}
2377
2378static void vortex_disable_int(vortex_t * card)
2379{
2380        hwwrite(card->mmio, VORTEX_CTRL,
2381                hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
2382}
2383
2384static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2385{
2386        vortex_t *vortex = dev_id;
2387        int i, handled;
2388        u32 source;
2389
2390        //check if the interrupt is ours.
2391        if (!(hwread(vortex->mmio, VORTEX_STAT) & 0x1))
2392                return IRQ_NONE;
2393
2394        // This is the Interrupt Enable flag we set before (consistency check).
2395        if (!(hwread(vortex->mmio, VORTEX_CTRL) & CTRL_IRQ_ENABLE))
2396                return IRQ_NONE;
2397
2398        source = hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2399        // Reset IRQ flags.
2400        hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, source);
2401        hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2402        // Is at least one IRQ flag set?
2403        if (source == 0) {
2404                printk(KERN_ERR "vortex: missing irq source\n");
2405                return IRQ_NONE;
2406        }
2407
2408        handled = 0;
2409        // Attend every interrupt source.
2410        if (unlikely(source & IRQ_ERR_MASK)) {
2411                if (source & IRQ_FATAL) {
2412                        printk(KERN_ERR "vortex: IRQ fatal error\n");
2413                }
2414                if (source & IRQ_PARITY) {
2415                        printk(KERN_ERR "vortex: IRQ parity error\n");
2416                }
2417                if (source & IRQ_REG) {
2418                        printk(KERN_ERR "vortex: IRQ reg error\n");
2419                }
2420                if (source & IRQ_FIFO) {
2421                        printk(KERN_ERR "vortex: IRQ fifo error\n");
2422                }
2423                if (source & IRQ_DMA) {
2424                        printk(KERN_ERR "vortex: IRQ dma error\n");
2425                }
2426                handled = 1;
2427        }
2428        if (source & IRQ_PCMOUT) {
2429                /* ALSA period acknowledge. */
2430                spin_lock(&vortex->lock);
2431                for (i = 0; i < NR_ADB; i++) {
2432                        if (vortex->dma_adb[i].fifo_status == FIFO_START) {
2433                                if (vortex_adbdma_bufshift(vortex, i)) ;
2434                                spin_unlock(&vortex->lock);
2435                                snd_pcm_period_elapsed(vortex->dma_adb[i].
2436                                                       substream);
2437                                spin_lock(&vortex->lock);
2438                        }
2439                }
2440#ifndef CHIP_AU8810
2441                for (i = 0; i < NR_WT; i++) {
2442                        if (vortex->dma_wt[i].fifo_status == FIFO_START) {
2443                                if (vortex_wtdma_bufshift(vortex, i)) ;
2444                                spin_unlock(&vortex->lock);
2445                                snd_pcm_period_elapsed(vortex->dma_wt[i].
2446                                                       substream);
2447                                spin_lock(&vortex->lock);
2448                        }
2449                }
2450#endif
2451                spin_unlock(&vortex->lock);
2452                handled = 1;
2453        }
2454        //Acknowledge the Timer interrupt
2455        if (source & IRQ_TIMER) {
2456                hwread(vortex->mmio, VORTEX_IRQ_STAT);
2457                handled = 1;
2458        }
2459        if (source & IRQ_MIDI) {
2460                snd_mpu401_uart_interrupt(vortex->irq,
2461                                          vortex->rmidi->private_data);
2462                handled = 1;
2463        }
2464
2465        if (!handled) {
2466                printk(KERN_ERR "vortex: unknown irq source %x\n", source);
2467        }
2468        return IRQ_RETVAL(handled);
2469}
2470
2471/* Codec */
2472
2473#define POLL_COUNT 1000
2474static void vortex_codec_init(vortex_t * vortex)
2475{
2476        int i;
2477
2478        for (i = 0; i < 32; i++) {
2479                /* the windows driver writes -i, so we write -i */
2480                hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2481                msleep(2);
2482        }
2483        if (0) {
2484                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
2485                msleep(1);
2486                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2487                msleep(1);
2488        } else {
2489                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2490                msleep(2);
2491                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2492                msleep(2);
2493                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
2494                msleep(2);
2495                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2496                msleep(2);
2497                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2498                msleep(2);
2499                hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2500        }
2501        for (i = 0; i < 32; i++) {
2502                hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2503                msleep(5);
2504        }
2505        hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
2506        msleep(1);
2507        /* Enable codec channels 0 and 1. */
2508        hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2509                hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
2510}
2511
2512static void
2513vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data)
2514{
2515
2516        vortex_t *card = (vortex_t *) codec->private_data;
2517        unsigned int lifeboat = 0;
2518
2519        /* wait for transactions to clear */
2520        while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2521                udelay(100);
2522                if (lifeboat++ > POLL_COUNT) {
2523                        printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
2524                        return;
2525                }
2526        }
2527        /* write register */
2528        hwwrite(card->mmio, VORTEX_CODEC_IO,
2529                ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2530                ((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
2531                VORTEX_CODEC_WRITE |
2532                (codec->num << VORTEX_CODEC_ID_SHIFT) );
2533
2534        /* Flush Caches. */
2535        hwread(card->mmio, VORTEX_CODEC_IO);
2536}
2537
2538static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr)
2539{
2540
2541        vortex_t *card = (vortex_t *) codec->private_data;
2542        u32 read_addr, data;
2543        unsigned lifeboat = 0;
2544
2545        /* wait for transactions to clear */
2546        while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2547                udelay(100);
2548                if (lifeboat++ > POLL_COUNT) {
2549                        printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
2550                        return 0xffff;
2551                }
2552        }
2553        /* set up read address */
2554        read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2555                (codec->num << VORTEX_CODEC_ID_SHIFT) ;
2556        hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
2557
2558        /* wait for address */
2559        do {
2560                udelay(100);
2561                data = hwread(card->mmio, VORTEX_CODEC_IO);
2562                if (lifeboat++ > POLL_COUNT) {
2563                        printk(KERN_ERR "vortex: ac97 address never arrived\n");
2564                        return 0xffff;
2565                }
2566        } while ((data & VORTEX_CODEC_ADDMASK) !=
2567                 (addr << VORTEX_CODEC_ADDSHIFT));
2568
2569        /* return data. */
2570        return (u16) (data & VORTEX_CODEC_DATMASK);
2571}
2572
2573/* SPDIF support  */
2574
2575static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode)
2576{
2577        int i, this_38 = 0, this_04 = 0, this_08 = 0, this_0c = 0;
2578
2579        /* CAsp4Spdif::InitializeSpdifHardware(void) */
2580        hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS,
2581                hwread(vortex->mmio, VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
2582        //for (i=0x291D4; i<0x29200; i+=4)
2583        for (i = 0; i < 11; i++)
2584                hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1 + (i << 2), 0);
2585        //hwwrite(vortex->mmio, 0x29190, hwread(vortex->mmio, 0x29190) | 0xc0000);
2586        hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2587                hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_SPDIF);
2588
2589        /* CAsp4Spdif::ProgramSRCInHardware(enum  SPDIF_SR,enum  SPDIFMODE) */
2590        if (this_04 && this_08) {
2591                int edi;
2592
2593                i = (((0x5DC00000 / spdif_sr) + 1) >> 1);
2594                if (i > 0x800) {
2595                        if (i < 0x1ffff)
2596                                edi = (i >> 1);
2597                        else
2598                                edi = 0x1ffff;
2599                } else {
2600                        i = edi = 0x800;
2601                }
2602                /* this_04 and this_08 are the CASp4Src's (samplerate converters) */
2603                vortex_src_setupchannel(vortex, this_04, edi, 0, 1,
2604                                        this_0c, 1, 0, edi, 1);
2605                vortex_src_setupchannel(vortex, this_08, edi, 0, 1,
2606                                        this_0c, 1, 0, edi, 1);
2607        }
2608
2609        i = spdif_sr;
2610        spdif_sr |= 0x8c;
2611        switch (i) {
2612        case 32000:
2613                this_38 &= 0xFFFFFFFE;
2614                this_38 &= 0xFFFFFFFD;
2615                this_38 &= 0xF3FFFFFF;
2616                this_38 |= 0x03000000;  /* set 32khz samplerate */
2617                this_38 &= 0xFFFFFF3F;
2618                spdif_sr &= 0xFFFFFFFD;
2619                spdif_sr |= 1;
2620                break;
2621        case 44100:
2622                this_38 &= 0xFFFFFFFE;
2623                this_38 &= 0xFFFFFFFD;
2624                this_38 &= 0xF0FFFFFF;
2625                this_38 |= 0x03000000;
2626                this_38 &= 0xFFFFFF3F;
2627                spdif_sr &= 0xFFFFFFFC;
2628                break;
2629        case 48000:
2630                if (spdif_mode == 1) {
2631                        this_38 &= 0xFFFFFFFE;
2632                        this_38 &= 0xFFFFFFFD;
2633                        this_38 &= 0xF2FFFFFF;
2634                        this_38 |= 0x02000000;  /* set 48khz samplerate */
2635                        this_38 &= 0xFFFFFF3F;
2636                } else {
2637                        /* J. Gordon Wolfe: I think this stuff is for AC3 */
2638                        this_38 |= 0x00000003;
2639                        this_38 &= 0xFFFFFFBF;
2640                        this_38 |= 0x80;
2641                }
2642                spdif_sr |= 2;
2643                spdif_sr &= 0xFFFFFFFE;
2644                break;
2645
2646        }
2647        /* looks like the next 2 lines transfer a 16-bit value into 2 8-bit 
2648           registers. seems to be for the standard IEC/SPDIF initialization 
2649           stuff */
2650        hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
2651        hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
2652        hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
2653}
2654
2655/* Initialization */
2656
2657static int __devinit vortex_core_init(vortex_t * vortex)
2658{
2659
2660        printk(KERN_INFO "Vortex: init.... ");
2661        /* Hardware Init. */
2662        hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
2663        msleep(5);
2664        hwwrite(vortex->mmio, VORTEX_CTRL,
2665                hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
2666        msleep(5);
2667        /* Reset IRQ flags */
2668        hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
2669        hwread(vortex->mmio, VORTEX_IRQ_STAT);
2670
2671        vortex_codec_init(vortex);
2672
2673#ifdef CHIP_AU8830
2674        hwwrite(vortex->mmio, VORTEX_CTRL,
2675                hwread(vortex->mmio, VORTEX_CTRL) | 0x1000000);
2676#endif
2677
2678        /* Init audio engine. */
2679        vortex_adbdma_init(vortex);
2680        hwwrite(vortex->mmio, VORTEX_ENGINE_CTRL, 0x0); //, 0xc83c7e58, 0xc5f93e58
2681        vortex_adb_init(vortex);
2682        /* Init processing blocks. */
2683        vortex_fifo_init(vortex);
2684        vortex_mixer_init(vortex);
2685        vortex_srcblock_init(vortex);
2686#ifndef CHIP_AU8820
2687        vortex_eq_init(vortex);
2688        vortex_spdif_init(vortex, 48000, 1);
2689        vortex_Vort3D_enable(vortex);
2690#endif
2691#ifndef CHIP_AU8810
2692        vortex_wt_init(vortex);
2693#endif
2694        // Moved to au88x0.c
2695        //vortex_connect_default(vortex, 1);
2696
2697        vortex_settimer(vortex, 0x90);
2698        // Enable Interrupts.
2699        // vortex_enable_int() must be first !!
2700        //  hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2701        // vortex_enable_int(vortex);
2702        //vortex_enable_timer_int(vortex);
2703        //vortex_disable_timer_int(vortex);
2704
2705        printk(KERN_INFO "done.\n");
2706        spin_lock_init(&vortex->lock);
2707
2708        return 0;
2709}
2710
2711static int vortex_core_shutdown(vortex_t * vortex)
2712{
2713
2714        printk(KERN_INFO "Vortex: shutdown...");
2715#ifndef CHIP_AU8820
2716        vortex_eq_free(vortex);
2717        vortex_Vort3D_disable(vortex);
2718#endif
2719        //vortex_disable_timer_int(vortex);
2720        vortex_disable_int(vortex);
2721        vortex_connect_default(vortex, 0);
2722        /* Reset all DMA fifos. */
2723        vortex_fifo_init(vortex);
2724        /* Erase all audio routes. */
2725        vortex_adb_init(vortex);
2726
2727        /* Disable MPU401 */
2728        //hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, hwread(vortex->mmio, VORTEX_IRQ_CTRL) & ~IRQ_MIDI);
2729        //hwwrite(vortex->mmio, VORTEX_CTRL, hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_EN);
2730
2731        hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2732        hwwrite(vortex->mmio, VORTEX_CTRL, 0);
2733        msleep(5);
2734        hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
2735
2736        printk(KERN_INFO "done.\n");
2737        return 0;
2738}
2739
2740/* Alsa support. */
2741
2742static int vortex_alsafmt_aspfmt(int alsafmt)
2743{
2744        int fmt;
2745
2746        switch (alsafmt) {
2747        case SNDRV_PCM_FORMAT_U8:
2748                fmt = 0x1;
2749                break;
2750        case SNDRV_PCM_FORMAT_MU_LAW:
2751                fmt = 0x2;
2752                break;
2753        case SNDRV_PCM_FORMAT_A_LAW:
2754                fmt = 0x3;
2755                break;
2756        case SNDRV_PCM_FORMAT_SPECIAL:
2757                fmt = 0x4;      /* guess. */
2758                break;
2759        case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
2760                fmt = 0x5;      /* guess. */
2761                break;
2762        case SNDRV_PCM_FORMAT_S16_LE:
2763                fmt = 0x8;
2764                break;
2765        case SNDRV_PCM_FORMAT_S16_BE:
2766                fmt = 0x9;      /* check this... */
2767                break;
2768        default:
2769                fmt = 0x8;
2770                printk(KERN_ERR "vortex: format unsupported %d\n", alsafmt);
2771                break;
2772        }
2773        return fmt;
2774}
2775
2776/* Some not yet useful translations. */
2777#if 0
2778typedef enum {
2779        ASPFMTLINEAR16 = 0,     /* 0x8 */
2780        ASPFMTLINEAR8,          /* 0x1 */
2781        ASPFMTULAW,             /* 0x2 */
2782        ASPFMTALAW,             /* 0x3 */
2783        ASPFMTSPORT,            /* ? */
2784        ASPFMTSPDIF,            /* ? */
2785} ASPENCODING;
2786
2787static int
2788vortex_translateformat(vortex_t * vortex, char bits, char nch, int encod)
2789{
2790        int a, this_194;
2791
2792        if ((bits != 8) || (bits != 16))
2793                return -1;
2794
2795        switch (encod) {
2796        case 0:
2797                if (bits == 0x10)
2798                        a = 8;  // 16 bit
2799                break;
2800        case 1:
2801                if (bits == 8)
2802                        a = 1;  // 8 bit
2803                break;
2804        case 2:
2805                a = 2;          // U_LAW
2806                break;
2807        case 3:
2808                a = 3;          // A_LAW
2809                break;
2810        }
2811        switch (nch) {
2812        case 1:
2813                this_194 = 0;
2814                break;
2815        case 2:
2816                this_194 = 1;
2817                break;
2818        case 4:
2819                this_194 = 1;
2820                break;
2821        case 6:
2822                this_194 = 1;
2823                break;
2824        }
2825        return (a);
2826}
2827
2828static void vortex_cdmacore_setformat(vortex_t * vortex, int bits, int nch)
2829{
2830        short int d, this_148;
2831
2832        d = ((bits >> 3) * nch);
2833        this_148 = 0xbb80 / d;
2834}
2835#endif
2836