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