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