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