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