linux/sound/oss/msnd_pinnacle.c
<<
>>
Prefs
   1/*********************************************************************
   2 *
   3 * Turtle Beach MultiSound Sound Card Driver for Linux
   4 * Linux 2.0/2.2 Version
   5 *
   6 * msnd_pinnacle.c / msnd_classic.c
   7 *
   8 * -- If MSND_CLASSIC is defined:
   9 *
  10 *     -> driver for Turtle Beach Classic/Monterey/Tahiti
  11 *
  12 * -- Else
  13 *
  14 *     -> driver for Turtle Beach Pinnacle/Fiji
  15 *
  16 * Copyright (C) 1998 Andrew Veliath
  17 *
  18 * This program is free software; you can redistribute it and/or modify
  19 * it under the terms of the GNU General Public License as published by
  20 * the Free Software Foundation; either version 2 of the License, or
  21 * (at your option) any later version.
  22 *
  23 * This program is distributed in the hope that it will be useful,
  24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26 * GNU General Public License for more details.
  27 *
  28 * You should have received a copy of the GNU General Public License
  29 * along with this program; if not, write to the Free Software
  30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  31 *
  32 * 12-3-2000  Modified IO port validation  Steve Sycamore
  33 *
  34 ********************************************************************/
  35
  36#include <linux/kernel.h>
  37#include <linux/module.h>
  38#include <linux/slab.h>
  39#include <linux/types.h>
  40#include <linux/delay.h>
  41#include <linux/init.h>
  42#include <linux/interrupt.h>
  43#include <linux/smp_lock.h>
  44#include <asm/irq.h>
  45#include <asm/io.h>
  46#include "sound_config.h"
  47#include "sound_firmware.h"
  48#ifdef MSND_CLASSIC
  49# ifndef __alpha__
  50#  define SLOWIO
  51# endif
  52#endif
  53#include "msnd.h"
  54#ifdef MSND_CLASSIC
  55#  ifdef CONFIG_MSNDCLAS_HAVE_BOOT
  56#    define HAVE_DSPCODEH
  57#  endif
  58#  include "msnd_classic.h"
  59#  define LOGNAME                       "msnd_classic"
  60#else
  61#  ifdef CONFIG_MSNDPIN_HAVE_BOOT
  62#    define HAVE_DSPCODEH
  63#  endif
  64#  include "msnd_pinnacle.h"
  65#  define LOGNAME                       "msnd_pinnacle"
  66#endif
  67
  68#ifndef CONFIG_MSND_WRITE_NDELAY
  69#  define CONFIG_MSND_WRITE_NDELAY      1
  70#endif
  71
  72#define get_play_delay_jiffies(size)    ((size) * HZ *                  \
  73                                         dev.play_sample_size / 8 /     \
  74                                         dev.play_sample_rate /         \
  75                                         dev.play_channels)
  76
  77#define get_rec_delay_jiffies(size)     ((size) * HZ *                  \
  78                                         dev.rec_sample_size / 8 /      \
  79                                         dev.rec_sample_rate /          \
  80                                         dev.rec_channels)
  81
  82static multisound_dev_t                 dev;
  83
  84#ifndef HAVE_DSPCODEH
  85static char                             *dspini, *permini;
  86static int                              sizeof_dspini, sizeof_permini;
  87#endif
  88
  89static int                              dsp_full_reset(void);
  90static void                             dsp_write_flush(void);
  91
  92static __inline__ int chk_send_dsp_cmd(multisound_dev_t *dev, register BYTE cmd)
  93{
  94        if (msnd_send_dsp_cmd(dev, cmd) == 0)
  95                return 0;
  96        dsp_full_reset();
  97        return msnd_send_dsp_cmd(dev, cmd);
  98}
  99
 100static void reset_play_queue(void)
 101{
 102        int n;
 103        LPDAQD lpDAQ;
 104
 105        dev.last_playbank = -1;
 106        writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wHead);
 107        writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wTail);
 108
 109        for (n = 0, lpDAQ = dev.base + DAPQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
 110                writew(PCTODSP_BASED((DWORD)(DAP_BUFF_SIZE * n)), lpDAQ + DAQDS_wStart);
 111                writew(0, lpDAQ + DAQDS_wSize);
 112                writew(1, lpDAQ + DAQDS_wFormat);
 113                writew(dev.play_sample_size, lpDAQ + DAQDS_wSampleSize);
 114                writew(dev.play_channels, lpDAQ + DAQDS_wChannels);
 115                writew(dev.play_sample_rate, lpDAQ + DAQDS_wSampleRate);
 116                writew(HIMT_PLAY_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
 117                writew(n, lpDAQ + DAQDS_wFlags);
 118        }
 119}
 120
 121static void reset_record_queue(void)
 122{
 123        int n;
 124        LPDAQD lpDAQ;
 125        unsigned long flags;
 126
 127        dev.last_recbank = 2;
 128        writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DARQ + JQS_wHead);
 129        writew(PCTODSP_OFFSET(dev.last_recbank * DAQDS__size), dev.DARQ + JQS_wTail);
 130
 131        /* Critical section: bank 1 access */
 132        spin_lock_irqsave(&dev.lock, flags);
 133        msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
 134        memset_io(dev.base, 0, DAR_BUFF_SIZE * 3);
 135        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
 136        spin_unlock_irqrestore(&dev.lock, flags);
 137
 138        for (n = 0, lpDAQ = dev.base + DARQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
 139                writew(PCTODSP_BASED((DWORD)(DAR_BUFF_SIZE * n)) + 0x4000, lpDAQ + DAQDS_wStart);
 140                writew(DAR_BUFF_SIZE, lpDAQ + DAQDS_wSize);
 141                writew(1, lpDAQ + DAQDS_wFormat);
 142                writew(dev.rec_sample_size, lpDAQ + DAQDS_wSampleSize);
 143                writew(dev.rec_channels, lpDAQ + DAQDS_wChannels);
 144                writew(dev.rec_sample_rate, lpDAQ + DAQDS_wSampleRate);
 145                writew(HIMT_RECORD_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
 146                writew(n, lpDAQ + DAQDS_wFlags);
 147        }
 148}
 149
 150static void reset_queues(void)
 151{
 152        if (dev.mode & FMODE_WRITE) {
 153                msnd_fifo_make_empty(&dev.DAPF);
 154                reset_play_queue();
 155        }
 156        if (dev.mode & FMODE_READ) {
 157                msnd_fifo_make_empty(&dev.DARF);
 158                reset_record_queue();
 159        }
 160}
 161
 162static int dsp_set_format(struct file *file, int val)
 163{
 164        int data, i;
 165        LPDAQD lpDAQ, lpDARQ;
 166
 167        lpDAQ = dev.base + DAPQ_DATA_BUFF;
 168        lpDARQ = dev.base + DARQ_DATA_BUFF;
 169
 170        switch (val) {
 171        case AFMT_U8:
 172        case AFMT_S16_LE:
 173                data = val;
 174                break;
 175        default:
 176                data = DEFSAMPLESIZE;
 177                break;
 178        }
 179
 180        for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
 181                if (file->f_mode & FMODE_WRITE)
 182                        writew(data, lpDAQ + DAQDS_wSampleSize);
 183                if (file->f_mode & FMODE_READ)
 184                        writew(data, lpDARQ + DAQDS_wSampleSize);
 185        }
 186        if (file->f_mode & FMODE_WRITE)
 187                dev.play_sample_size = data;
 188        if (file->f_mode & FMODE_READ)
 189                dev.rec_sample_size = data;
 190
 191        return data;
 192}
 193
 194static int dsp_get_frag_size(void)
 195{
 196        int size;
 197        size = dev.fifosize / 4;
 198        if (size > 32 * 1024)
 199                size = 32 * 1024;
 200        return size;
 201}
 202
 203static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 204{
 205        int val, i, data, tmp;
 206        LPDAQD lpDAQ, lpDARQ;
 207        audio_buf_info abinfo;
 208        unsigned long flags;
 209        int __user *p = (int __user *)arg;
 210
 211        lpDAQ = dev.base + DAPQ_DATA_BUFF;
 212        lpDARQ = dev.base + DARQ_DATA_BUFF;
 213
 214        switch (cmd) {
 215        case SNDCTL_DSP_SUBDIVIDE:
 216        case SNDCTL_DSP_SETFRAGMENT:
 217        case SNDCTL_DSP_SETDUPLEX:
 218        case SNDCTL_DSP_POST:
 219                return 0;
 220
 221        case SNDCTL_DSP_GETIPTR:
 222        case SNDCTL_DSP_GETOPTR:
 223        case SNDCTL_DSP_MAPINBUF:
 224        case SNDCTL_DSP_MAPOUTBUF:
 225                return -EINVAL;
 226
 227        case SNDCTL_DSP_GETOSPACE:
 228                if (!(file->f_mode & FMODE_WRITE))
 229                        return -EINVAL;
 230                spin_lock_irqsave(&dev.lock, flags);
 231                abinfo.fragsize = dsp_get_frag_size();
 232                abinfo.bytes = dev.DAPF.n - dev.DAPF.len;
 233                abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
 234                abinfo.fragments = abinfo.bytes / abinfo.fragsize;
 235                spin_unlock_irqrestore(&dev.lock, flags);
 236                return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 237
 238        case SNDCTL_DSP_GETISPACE:
 239                if (!(file->f_mode & FMODE_READ))
 240                        return -EINVAL;
 241                spin_lock_irqsave(&dev.lock, flags);
 242                abinfo.fragsize = dsp_get_frag_size();
 243                abinfo.bytes = dev.DARF.n - dev.DARF.len;
 244                abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
 245                abinfo.fragments = abinfo.bytes / abinfo.fragsize;
 246                spin_unlock_irqrestore(&dev.lock, flags);
 247                return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 248
 249        case SNDCTL_DSP_RESET:
 250                dev.nresets = 0;
 251                reset_queues();
 252                return 0;
 253
 254        case SNDCTL_DSP_SYNC:
 255                dsp_write_flush();
 256                return 0;
 257
 258        case SNDCTL_DSP_GETBLKSIZE:
 259                tmp = dsp_get_frag_size();
 260                if (put_user(tmp, p))
 261                        return -EFAULT;
 262                return 0;
 263
 264        case SNDCTL_DSP_GETFMTS:
 265                val = AFMT_S16_LE | AFMT_U8;
 266                if (put_user(val, p))
 267                        return -EFAULT;
 268                return 0;
 269
 270        case SNDCTL_DSP_SETFMT:
 271                if (get_user(val, p))
 272                        return -EFAULT;
 273
 274                if (file->f_mode & FMODE_WRITE)
 275                        data = val == AFMT_QUERY
 276                                ? dev.play_sample_size
 277                                : dsp_set_format(file, val);
 278                else
 279                        data = val == AFMT_QUERY
 280                                ? dev.rec_sample_size
 281                                : dsp_set_format(file, val);
 282
 283                if (put_user(data, p))
 284                        return -EFAULT;
 285                return 0;
 286
 287        case SNDCTL_DSP_NONBLOCK:
 288                if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) &&
 289                    file->f_mode & FMODE_WRITE)
 290                        dev.play_ndelay = 1;
 291                if (file->f_mode & FMODE_READ)
 292                        dev.rec_ndelay = 1;
 293                return 0;
 294
 295        case SNDCTL_DSP_GETCAPS:
 296                val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
 297                if (put_user(val, p))
 298                        return -EFAULT;
 299                return 0;
 300
 301        case SNDCTL_DSP_SPEED:
 302                if (get_user(val, p))
 303                        return -EFAULT;
 304
 305                if (val < 8000)
 306                        val = 8000;
 307
 308                if (val > 48000)
 309                        val = 48000;
 310
 311                data = val;
 312
 313                for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
 314                        if (file->f_mode & FMODE_WRITE)
 315                                writew(data, lpDAQ + DAQDS_wSampleRate);
 316                        if (file->f_mode & FMODE_READ)
 317                                writew(data, lpDARQ + DAQDS_wSampleRate);
 318                }
 319                if (file->f_mode & FMODE_WRITE)
 320                        dev.play_sample_rate = data;
 321                if (file->f_mode & FMODE_READ)
 322                        dev.rec_sample_rate = data;
 323
 324                if (put_user(data, p))
 325                        return -EFAULT;
 326                return 0;
 327
 328        case SNDCTL_DSP_CHANNELS:
 329        case SNDCTL_DSP_STEREO:
 330                if (get_user(val, p))
 331                        return -EFAULT;
 332
 333                if (cmd == SNDCTL_DSP_CHANNELS) {
 334                        switch (val) {
 335                        case 1:
 336                        case 2:
 337                                data = val;
 338                                break;
 339                        default:
 340                                val = data = 2;
 341                                break;
 342                        }
 343                } else {
 344                        switch (val) {
 345                        case 0:
 346                                data = 1;
 347                                break;
 348                        default:
 349                                val = 1;
 350                        case 1:
 351                                data = 2;
 352                                break;
 353                        }
 354                }
 355
 356                for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
 357                        if (file->f_mode & FMODE_WRITE)
 358                                writew(data, lpDAQ + DAQDS_wChannels);
 359                        if (file->f_mode & FMODE_READ)
 360                                writew(data, lpDARQ + DAQDS_wChannels);
 361                }
 362                if (file->f_mode & FMODE_WRITE)
 363                        dev.play_channels = data;
 364                if (file->f_mode & FMODE_READ)
 365                        dev.rec_channels = data;
 366
 367                if (put_user(val, p))
 368                        return -EFAULT;
 369                return 0;
 370        }
 371
 372        return -EINVAL;
 373}
 374
 375static int mixer_get(int d)
 376{
 377        if (d > 31)
 378                return -EINVAL;
 379
 380        switch (d) {
 381        case SOUND_MIXER_VOLUME:
 382        case SOUND_MIXER_PCM:
 383        case SOUND_MIXER_LINE:
 384        case SOUND_MIXER_IMIX:
 385        case SOUND_MIXER_LINE1:
 386#ifndef MSND_CLASSIC
 387        case SOUND_MIXER_MIC:
 388        case SOUND_MIXER_SYNTH:
 389#endif
 390                return (dev.left_levels[d] >> 8) * 100 / 0xff | 
 391                        (((dev.right_levels[d] >> 8) * 100 / 0xff) << 8);
 392        default:
 393                return 0;
 394        }
 395}
 396
 397#define update_volm(a,b)                                                \
 398        writew((dev.left_levels[a] >> 1) *                              \
 399               readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff,  \
 400               dev.SMA + SMA_##b##Left);                                \
 401        writew((dev.right_levels[a] >> 1)  *                    \
 402               readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \
 403               dev.SMA + SMA_##b##Right);
 404
 405#define update_potm(d,s,ar)                                             \
 406        writeb((dev.left_levels[d] >> 8) *                              \
 407               readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff,  \
 408               dev.SMA + SMA_##s##Left);                                \
 409        writeb((dev.right_levels[d] >> 8) *                             \
 410               readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \
 411               dev.SMA + SMA_##s##Right);                               \
 412        if (msnd_send_word(&dev, 0, 0, ar) == 0)                        \
 413                chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 414
 415#define update_pot(d,s,ar)                              \
 416        writeb(dev.left_levels[d] >> 8,         \
 417               dev.SMA + SMA_##s##Left);                \
 418        writeb(dev.right_levels[d] >> 8,                \
 419               dev.SMA + SMA_##s##Right);               \
 420        if (msnd_send_word(&dev, 0, 0, ar) == 0)        \
 421                chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 422
 423static int mixer_set(int d, int value)
 424{
 425        int left = value & 0x000000ff;
 426        int right = (value & 0x0000ff00) >> 8;
 427        int bLeft, bRight;
 428        int wLeft, wRight;
 429        int updatemaster = 0;
 430
 431        if (d > 31)
 432                return -EINVAL;
 433
 434        bLeft = left * 0xff / 100;
 435        wLeft = left * 0xffff / 100;
 436
 437        bRight = right * 0xff / 100;
 438        wRight = right * 0xffff / 100;
 439
 440        dev.left_levels[d] = wLeft;
 441        dev.right_levels[d] = wRight;
 442
 443        switch (d) {
 444                /* master volume unscaled controls */
 445        case SOUND_MIXER_LINE:                  /* line pot control */
 446                /* scaled by IMIX in digital mix */
 447                writeb(bLeft, dev.SMA + SMA_bInPotPosLeft);
 448                writeb(bRight, dev.SMA + SMA_bInPotPosRight);
 449                if (msnd_send_word(&dev, 0, 0, HDEXAR_IN_SET_POTS) == 0)
 450                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 451                break;
 452#ifndef MSND_CLASSIC
 453        case SOUND_MIXER_MIC:                   /* mic pot control */
 454                /* scaled by IMIX in digital mix */
 455                writeb(bLeft, dev.SMA + SMA_bMicPotPosLeft);
 456                writeb(bRight, dev.SMA + SMA_bMicPotPosRight);
 457                if (msnd_send_word(&dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
 458                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 459                break;
 460#endif
 461        case SOUND_MIXER_VOLUME:                /* master volume */
 462                writew(wLeft, dev.SMA + SMA_wCurrMastVolLeft);
 463                writew(wRight, dev.SMA + SMA_wCurrMastVolRight);
 464                /* fall through */
 465
 466        case SOUND_MIXER_LINE1:                 /* aux pot control */
 467                /* scaled by master volume */
 468                /* fall through */
 469
 470                /* digital controls */
 471        case SOUND_MIXER_SYNTH:                 /* synth vol (dsp mix) */
 472        case SOUND_MIXER_PCM:                   /* pcm vol (dsp mix) */
 473        case SOUND_MIXER_IMIX:                  /* input monitor (dsp mix) */
 474                /* scaled by master volume */
 475                updatemaster = 1;
 476                break;
 477
 478        default:
 479                return 0;
 480        }
 481
 482        if (updatemaster) {
 483                /* update master volume scaled controls */
 484                update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
 485                update_volm(SOUND_MIXER_IMIX, wCurrInVol);
 486#ifndef MSND_CLASSIC
 487                update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
 488#endif
 489                update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
 490        }
 491
 492        return mixer_get(d);
 493}
 494
 495static void mixer_setup(void)
 496{
 497        update_pot(SOUND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS);
 498        update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
 499        update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
 500        update_volm(SOUND_MIXER_IMIX, wCurrInVol);
 501#ifndef MSND_CLASSIC
 502        update_pot(SOUND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS);
 503        update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
 504#endif
 505}
 506
 507static unsigned long set_recsrc(unsigned long recsrc)
 508{
 509        if (dev.recsrc == recsrc)
 510                return dev.recsrc;
 511#ifdef HAVE_NORECSRC
 512        else if (recsrc == 0)
 513                dev.recsrc = 0;
 514#endif
 515        else
 516                dev.recsrc ^= recsrc;
 517
 518#ifndef MSND_CLASSIC
 519        if (dev.recsrc & SOUND_MASK_IMIX) {
 520                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
 521                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 522        }
 523        else if (dev.recsrc & SOUND_MASK_SYNTH) {
 524                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_SYNTH_IN) == 0)
 525                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 526        }
 527        else if ((dev.recsrc & SOUND_MASK_DIGITAL1) && test_bit(F_HAVEDIGITAL, &dev.flags)) {
 528                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_DAT_IN) == 0)
 529                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 530        }
 531        else {
 532#ifdef HAVE_NORECSRC
 533                /* Select no input (?) */
 534                dev.recsrc = 0;
 535#else
 536                dev.recsrc = SOUND_MASK_IMIX;
 537                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
 538                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 539#endif
 540        }
 541#endif /* MSND_CLASSIC */
 542
 543        return dev.recsrc;
 544}
 545
 546static unsigned long force_recsrc(unsigned long recsrc)
 547{
 548        dev.recsrc = 0;
 549        return set_recsrc(recsrc);
 550}
 551
 552#define set_mixer_info()                                                        \
 553                memset(&info, 0, sizeof(info));                                 \
 554                strlcpy(info.id, "MSNDMIXER", sizeof(info.id));                 \
 555                strlcpy(info.name, "MultiSound Mixer", sizeof(info.name));
 556
 557static int mixer_ioctl(unsigned int cmd, unsigned long arg)
 558{
 559        if (cmd == SOUND_MIXER_INFO) {
 560                mixer_info info;
 561                set_mixer_info();
 562                info.modify_counter = dev.mixer_mod_count;
 563                if (copy_to_user((void __user *)arg, &info, sizeof(info)))
 564                        return -EFAULT;
 565                return 0;
 566        } else if (cmd == SOUND_OLD_MIXER_INFO) {
 567                _old_mixer_info info;
 568                set_mixer_info();
 569                if (copy_to_user((void __user *)arg, &info, sizeof(info)))
 570                        return -EFAULT;
 571                return 0;
 572        } else if (cmd == SOUND_MIXER_PRIVATE1) {
 573                dev.nresets = 0;
 574                dsp_full_reset();
 575                return 0;
 576        } else if (((cmd >> 8) & 0xff) == 'M') {
 577                int val = 0;
 578
 579                if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
 580                        switch (cmd & 0xff) {
 581                        case SOUND_MIXER_RECSRC:
 582                                if (get_user(val, (int __user *)arg))
 583                                        return -EFAULT;
 584                                val = set_recsrc(val);
 585                                break;
 586
 587                        default:
 588                                if (get_user(val, (int __user *)arg))
 589                                        return -EFAULT;
 590                                val = mixer_set(cmd & 0xff, val);
 591                                break;
 592                        }
 593                        ++dev.mixer_mod_count;
 594                        return put_user(val, (int __user *)arg);
 595                } else {
 596                        switch (cmd & 0xff) {
 597                        case SOUND_MIXER_RECSRC:
 598                                val = dev.recsrc;
 599                                break;
 600
 601                        case SOUND_MIXER_DEVMASK:
 602                        case SOUND_MIXER_STEREODEVS:
 603                                val =   SOUND_MASK_PCM |
 604                                        SOUND_MASK_LINE |
 605                                        SOUND_MASK_IMIX |
 606                                        SOUND_MASK_LINE1 |
 607#ifndef MSND_CLASSIC
 608                                        SOUND_MASK_MIC |
 609                                        SOUND_MASK_SYNTH |
 610#endif
 611                                        SOUND_MASK_VOLUME;
 612                                break;
 613                                  
 614                        case SOUND_MIXER_RECMASK:
 615#ifdef MSND_CLASSIC
 616                                val =   0;
 617#else
 618                                val =   SOUND_MASK_IMIX |
 619                                        SOUND_MASK_SYNTH;
 620                                if (test_bit(F_HAVEDIGITAL, &dev.flags))
 621                                        val |= SOUND_MASK_DIGITAL1;
 622#endif
 623                                break;
 624                                  
 625                        case SOUND_MIXER_CAPS:
 626                                val =   SOUND_CAP_EXCL_INPUT;
 627                                break;
 628
 629                        default:
 630                                if ((val = mixer_get(cmd & 0xff)) < 0)
 631                                        return -EINVAL;
 632                                break;
 633                        }
 634                }
 635
 636                return put_user(val, (int __user *)arg); 
 637        }
 638
 639        return -EINVAL;
 640}
 641
 642static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 643{
 644        int minor = iminor(inode);
 645
 646        if (cmd == OSS_GETVERSION) {
 647                int sound_version = SOUND_VERSION;
 648                return put_user(sound_version, (int __user *)arg);
 649        }
 650
 651        if (minor == dev.dsp_minor)
 652                return dsp_ioctl(file, cmd, arg);
 653        else if (minor == dev.mixer_minor)
 654                return mixer_ioctl(cmd, arg);
 655
 656        return -EINVAL;
 657}
 658
 659static void dsp_write_flush(void)
 660{
 661        if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags))
 662                return;
 663        set_bit(F_WRITEFLUSH, &dev.flags);
 664        interruptible_sleep_on_timeout(
 665                &dev.writeflush,
 666                get_play_delay_jiffies(dev.DAPF.len));
 667        clear_bit(F_WRITEFLUSH, &dev.flags);
 668        if (!signal_pending(current)) {
 669                current->state = TASK_INTERRUPTIBLE;
 670                schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE));
 671        }
 672        clear_bit(F_WRITING, &dev.flags);
 673}
 674
 675static void dsp_halt(struct file *file)
 676{
 677        if ((file ? file->f_mode : dev.mode) & FMODE_READ) {
 678                clear_bit(F_READING, &dev.flags);
 679                chk_send_dsp_cmd(&dev, HDEX_RECORD_STOP);
 680                msnd_disable_irq(&dev);
 681                if (file) {
 682                        printk(KERN_DEBUG LOGNAME ": Stopping read for %p\n", file);
 683                        dev.mode &= ~FMODE_READ;
 684                }
 685                clear_bit(F_AUDIO_READ_INUSE, &dev.flags);
 686        }
 687        if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {
 688                if (test_bit(F_WRITING, &dev.flags)) {
 689                        dsp_write_flush();
 690                        chk_send_dsp_cmd(&dev, HDEX_PLAY_STOP);
 691                }
 692                msnd_disable_irq(&dev);
 693                if (file) {
 694                        printk(KERN_DEBUG LOGNAME ": Stopping write for %p\n", file);
 695                        dev.mode &= ~FMODE_WRITE;
 696                }
 697                clear_bit(F_AUDIO_WRITE_INUSE, &dev.flags);
 698        }
 699}
 700
 701static int dsp_release(struct file *file)
 702{
 703        dsp_halt(file);
 704        return 0;
 705}
 706
 707static int dsp_open(struct file *file)
 708{
 709        if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {
 710                set_bit(F_AUDIO_WRITE_INUSE, &dev.flags);
 711                clear_bit(F_WRITING, &dev.flags);
 712                msnd_fifo_make_empty(&dev.DAPF);
 713                reset_play_queue();
 714                if (file) {
 715                        printk(KERN_DEBUG LOGNAME ": Starting write for %p\n", file);
 716                        dev.mode |= FMODE_WRITE;
 717                }
 718                msnd_enable_irq(&dev);
 719        }
 720        if ((file ? file->f_mode : dev.mode) & FMODE_READ) {
 721                set_bit(F_AUDIO_READ_INUSE, &dev.flags);
 722                clear_bit(F_READING, &dev.flags);
 723                msnd_fifo_make_empty(&dev.DARF);
 724                reset_record_queue();
 725                if (file) {
 726                        printk(KERN_DEBUG LOGNAME ": Starting read for %p\n", file);
 727                        dev.mode |= FMODE_READ;
 728                }
 729                msnd_enable_irq(&dev);
 730        }
 731        return 0;
 732}
 733
 734static void set_default_play_audio_parameters(void)
 735{
 736        dev.play_sample_size = DEFSAMPLESIZE;
 737        dev.play_sample_rate = DEFSAMPLERATE;
 738        dev.play_channels = DEFCHANNELS;
 739}
 740
 741static void set_default_rec_audio_parameters(void)
 742{
 743        dev.rec_sample_size = DEFSAMPLESIZE;
 744        dev.rec_sample_rate = DEFSAMPLERATE;
 745        dev.rec_channels = DEFCHANNELS;
 746}
 747
 748static void set_default_audio_parameters(void)
 749{
 750        set_default_play_audio_parameters();
 751        set_default_rec_audio_parameters();
 752}
 753
 754static int dev_open(struct inode *inode, struct file *file)
 755{
 756        int minor = iminor(inode);
 757        int err = 0;
 758
 759        if (minor == dev.dsp_minor) {
 760                if ((file->f_mode & FMODE_WRITE &&
 761                     test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
 762                    (file->f_mode & FMODE_READ &&
 763                     test_bit(F_AUDIO_READ_INUSE, &dev.flags)))
 764                        return -EBUSY;
 765
 766                if ((err = dsp_open(file)) >= 0) {
 767                        dev.nresets = 0;
 768                        if (file->f_mode & FMODE_WRITE) {
 769                                set_default_play_audio_parameters();
 770                                if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags))
 771                                        dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
 772                                else
 773                                        dev.play_ndelay = 0;
 774                        }
 775                        if (file->f_mode & FMODE_READ) {
 776                                set_default_rec_audio_parameters();
 777                                dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
 778                        }
 779                }
 780        }
 781        else if (minor == dev.mixer_minor) {
 782                /* nothing */
 783        } else
 784                err = -EINVAL;
 785
 786        return err;
 787}
 788
 789static int dev_release(struct inode *inode, struct file *file)
 790{
 791        int minor = iminor(inode);
 792        int err = 0;
 793
 794        lock_kernel();
 795        if (minor == dev.dsp_minor)
 796                err = dsp_release(file);
 797        else if (minor == dev.mixer_minor) {
 798                /* nothing */
 799        } else
 800                err = -EINVAL;
 801        unlock_kernel();
 802        return err;
 803}
 804
 805static __inline__ int pack_DARQ_to_DARF(register int bank)
 806{
 807        register int size, timeout = 3;
 808        register WORD wTmp;
 809        LPDAQD DAQD;
 810
 811        /* Increment the tail and check for queue wrap */
 812        wTmp = readw(dev.DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
 813        if (wTmp > readw(dev.DARQ + JQS_wSize))
 814                wTmp = 0;
 815        while (wTmp == readw(dev.DARQ + JQS_wHead) && timeout--)
 816                udelay(1);
 817        writew(wTmp, dev.DARQ + JQS_wTail);
 818
 819        /* Get our digital audio queue struct */
 820        DAQD = bank * DAQDS__size + dev.base + DARQ_DATA_BUFF;
 821
 822        /* Get length of data */
 823        size = readw(DAQD + DAQDS_wSize);
 824
 825        /* Read data from the head (unprotected bank 1 access okay
 826           since this is only called inside an interrupt) */
 827        msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
 828        msnd_fifo_write_io(
 829                &dev.DARF,
 830                dev.base + bank * DAR_BUFF_SIZE,
 831                size);
 832        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
 833
 834        return 1;
 835}
 836
 837static __inline__ int pack_DAPF_to_DAPQ(register int start)
 838{
 839        register WORD DAPQ_tail;
 840        register int protect = start, nbanks = 0;
 841        LPDAQD DAQD;
 842
 843        DAPQ_tail = readw(dev.DAPQ + JQS_wTail);
 844        while (DAPQ_tail != readw(dev.DAPQ + JQS_wHead) || start) {
 845                register int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);
 846                register int n;
 847                unsigned long flags;
 848
 849                /* Write the data to the new tail */
 850                if (protect) {
 851                        /* Critical section: protect fifo in non-interrupt */
 852                        spin_lock_irqsave(&dev.lock, flags);
 853                        n = msnd_fifo_read_io(
 854                                &dev.DAPF,
 855                                dev.base + bank_num * DAP_BUFF_SIZE,
 856                                DAP_BUFF_SIZE);
 857                        spin_unlock_irqrestore(&dev.lock, flags);
 858                } else {
 859                        n = msnd_fifo_read_io(
 860                                &dev.DAPF,
 861                                dev.base + bank_num * DAP_BUFF_SIZE,
 862                                DAP_BUFF_SIZE);
 863                }
 864                if (!n)
 865                        break;
 866
 867                if (start)
 868                        start = 0;
 869
 870                /* Get our digital audio queue struct */
 871                DAQD = bank_num * DAQDS__size + dev.base + DAPQ_DATA_BUFF;
 872
 873                /* Write size of this bank */
 874                writew(n, DAQD + DAQDS_wSize);
 875                ++nbanks;
 876
 877                /* Then advance the tail */
 878                DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);
 879                writew(DAPQ_tail, dev.DAPQ + JQS_wTail);
 880                /* Tell the DSP to play the bank */
 881                msnd_send_dsp_cmd(&dev, HDEX_PLAY_START);
 882        }
 883        return nbanks;
 884}
 885
 886static int dsp_read(char __user *buf, size_t len)
 887{
 888        int count = len;
 889        char *page = (char *)__get_free_page(GFP_KERNEL);
 890
 891        if (!page)
 892                return -ENOMEM;
 893
 894        while (count > 0) {
 895                int n, k;
 896                unsigned long flags;
 897
 898                k = PAGE_SIZE;
 899                if (k > count)
 900                        k = count;
 901
 902                /* Critical section: protect fifo in non-interrupt */
 903                spin_lock_irqsave(&dev.lock, flags);
 904                n = msnd_fifo_read(&dev.DARF, page, k);
 905                spin_unlock_irqrestore(&dev.lock, flags);
 906                if (copy_to_user(buf, page, n)) {
 907                        free_page((unsigned long)page);
 908                        return -EFAULT;
 909                }
 910                buf += n;
 911                count -= n;
 912
 913                if (n == k && count)
 914                        continue;
 915
 916                if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
 917                        dev.last_recbank = -1;
 918                        if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
 919                                set_bit(F_READING, &dev.flags);
 920                }
 921
 922                if (dev.rec_ndelay) {
 923                        free_page((unsigned long)page);
 924                        return count == len ? -EAGAIN : len - count;
 925                }
 926
 927                if (count > 0) {
 928                        set_bit(F_READBLOCK, &dev.flags);
 929                        if (!interruptible_sleep_on_timeout(
 930                                &dev.readblock,
 931                                get_rec_delay_jiffies(DAR_BUFF_SIZE)))
 932                                clear_bit(F_READING, &dev.flags);
 933                        clear_bit(F_READBLOCK, &dev.flags);
 934                        if (signal_pending(current)) {
 935                                free_page((unsigned long)page);
 936                                return -EINTR;
 937                        }
 938                }
 939        }
 940        free_page((unsigned long)page);
 941        return len - count;
 942}
 943
 944static int dsp_write(const char __user *buf, size_t len)
 945{
 946        int count = len;
 947        char *page = (char *)__get_free_page(GFP_KERNEL);
 948
 949        if (!page)
 950                return -ENOMEM;
 951
 952        while (count > 0) {
 953                int n, k;
 954                unsigned long flags;
 955
 956                k = PAGE_SIZE;
 957                if (k > count)
 958                        k = count;
 959
 960                if (copy_from_user(page, buf, k)) {
 961                        free_page((unsigned long)page);
 962                        return -EFAULT;
 963                }
 964
 965                /* Critical section: protect fifo in non-interrupt */
 966                spin_lock_irqsave(&dev.lock, flags);
 967                n = msnd_fifo_write(&dev.DAPF, page, k);
 968                spin_unlock_irqrestore(&dev.lock, flags);
 969                buf += n;
 970                count -= n;
 971
 972                if (count && n == k)
 973                        continue;
 974
 975                if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
 976                        dev.last_playbank = -1;
 977                        if (pack_DAPF_to_DAPQ(1) > 0)
 978                                set_bit(F_WRITING, &dev.flags);
 979                }
 980
 981                if (dev.play_ndelay) {
 982                        free_page((unsigned long)page);
 983                        return count == len ? -EAGAIN : len - count;
 984                }
 985
 986                if (count > 0) {
 987                        set_bit(F_WRITEBLOCK, &dev.flags);
 988                        interruptible_sleep_on_timeout(
 989                                &dev.writeblock,
 990                                get_play_delay_jiffies(DAP_BUFF_SIZE));
 991                        clear_bit(F_WRITEBLOCK, &dev.flags);
 992                        if (signal_pending(current)) {
 993                                free_page((unsigned long)page);
 994                                return -EINTR;
 995                        }
 996                }
 997        }
 998
 999        free_page((unsigned long)page);
1000        return len - count;
1001}
1002
1003static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *off)
1004{
1005        int minor = iminor(file->f_path.dentry->d_inode);
1006        if (minor == dev.dsp_minor)
1007                return dsp_read(buf, count);
1008        else
1009                return -EINVAL;
1010}
1011
1012static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
1013{
1014        int minor = iminor(file->f_path.dentry->d_inode);
1015        if (minor == dev.dsp_minor)
1016                return dsp_write(buf, count);
1017        else
1018                return -EINVAL;
1019}
1020
1021static __inline__ void eval_dsp_msg(register WORD wMessage)
1022{
1023        switch (HIBYTE(wMessage)) {
1024        case HIMT_PLAY_DONE:
1025                if (dev.last_playbank == LOBYTE(wMessage) || !test_bit(F_WRITING, &dev.flags))
1026                        break;
1027                dev.last_playbank = LOBYTE(wMessage);
1028
1029                if (pack_DAPF_to_DAPQ(0) <= 0) {
1030                        if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
1031                                if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
1032                                        wake_up_interruptible(&dev.writeflush);
1033                        }
1034                        clear_bit(F_WRITING, &dev.flags);
1035                }
1036
1037                if (test_bit(F_WRITEBLOCK, &dev.flags))
1038                        wake_up_interruptible(&dev.writeblock);
1039                break;
1040
1041        case HIMT_RECORD_DONE:
1042                if (dev.last_recbank == LOBYTE(wMessage))
1043                        break;
1044                dev.last_recbank = LOBYTE(wMessage);
1045
1046                pack_DARQ_to_DARF(dev.last_recbank);
1047
1048                if (test_bit(F_READBLOCK, &dev.flags))
1049                        wake_up_interruptible(&dev.readblock);
1050                break;
1051
1052        case HIMT_DSP:
1053                switch (LOBYTE(wMessage)) {
1054#ifndef MSND_CLASSIC
1055                case HIDSP_PLAY_UNDER:
1056#endif
1057                case HIDSP_INT_PLAY_UNDER:
1058/*                      printk(KERN_DEBUG LOGNAME ": Play underflow\n"); */
1059                        clear_bit(F_WRITING, &dev.flags);
1060                        break;
1061
1062                case HIDSP_INT_RECORD_OVER:
1063/*                      printk(KERN_DEBUG LOGNAME ": Record overflow\n"); */
1064                        clear_bit(F_READING, &dev.flags);
1065                        break;
1066
1067                default:
1068/*                      printk(KERN_DEBUG LOGNAME ": DSP message %d 0x%02x\n",
1069                        LOBYTE(wMessage), LOBYTE(wMessage)); */
1070                        break;
1071                }
1072                break;
1073
1074        case HIMT_MIDI_IN_UCHAR:
1075                if (dev.midi_in_interrupt)
1076                        (*dev.midi_in_interrupt)(&dev);
1077                break;
1078
1079        default:
1080/*              printk(KERN_DEBUG LOGNAME ": HIMT message %d 0x%02x\n", HIBYTE(wMessage), HIBYTE(wMessage)); */
1081                break;
1082        }
1083}
1084
1085static irqreturn_t intr(int irq, void *dev_id)
1086{
1087        /* Send ack to DSP */
1088        msnd_inb(dev.io + HP_RXL);
1089
1090        /* Evaluate queued DSP messages */
1091        while (readw(dev.DSPQ + JQS_wTail) != readw(dev.DSPQ + JQS_wHead)) {
1092                register WORD wTmp;
1093
1094                eval_dsp_msg(readw(dev.pwDSPQData + 2*readw(dev.DSPQ + JQS_wHead)));
1095
1096                if ((wTmp = readw(dev.DSPQ + JQS_wHead) + 1) > readw(dev.DSPQ + JQS_wSize))
1097                        writew(0, dev.DSPQ + JQS_wHead);
1098                else
1099                        writew(wTmp, dev.DSPQ + JQS_wHead);
1100        }
1101        return IRQ_HANDLED;
1102}
1103
1104static const struct file_operations dev_fileops = {
1105        .owner          = THIS_MODULE,
1106        .read           = dev_read,
1107        .write          = dev_write,
1108        .ioctl          = dev_ioctl,
1109        .open           = dev_open,
1110        .release        = dev_release,
1111};
1112
1113static int reset_dsp(void)
1114{
1115        int timeout = 100;
1116
1117        msnd_outb(HPDSPRESET_ON, dev.io + HP_DSPR);
1118        mdelay(1);
1119#ifndef MSND_CLASSIC
1120        dev.info = msnd_inb(dev.io + HP_INFO);
1121#endif
1122        msnd_outb(HPDSPRESET_OFF, dev.io + HP_DSPR);
1123        mdelay(1);
1124        while (timeout-- > 0) {
1125                if (msnd_inb(dev.io + HP_CVR) == HP_CVR_DEF)
1126                        return 0;
1127                mdelay(1);
1128        }
1129        printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
1130
1131        return -EIO;
1132}
1133
1134static int __init probe_multisound(void)
1135{
1136#ifndef MSND_CLASSIC
1137        char *xv, *rev = NULL;
1138        char *pin = "Pinnacle", *fiji = "Fiji";
1139        char *pinfiji = "Pinnacle/Fiji";
1140#endif
1141
1142        if (!request_region(dev.io, dev.numio, "probing")) {
1143                printk(KERN_ERR LOGNAME ": I/O port conflict\n");
1144                return -ENODEV;
1145        }
1146
1147        if (reset_dsp() < 0) {
1148                release_region(dev.io, dev.numio);
1149                return -ENODEV;
1150        }
1151
1152#ifdef MSND_CLASSIC
1153        dev.name = "Classic/Tahiti/Monterey";
1154        printk(KERN_INFO LOGNAME ": %s, "
1155#else
1156        switch (dev.info >> 4) {
1157        case 0xf: xv = "<= 1.15"; break;
1158        case 0x1: xv = "1.18/1.2"; break;
1159        case 0x2: xv = "1.3"; break;
1160        case 0x3: xv = "1.4"; break;
1161        default: xv = "unknown"; break;
1162        }
1163
1164        switch (dev.info & 0x7) {
1165        case 0x0: rev = "I"; dev.name = pin; break;
1166        case 0x1: rev = "F"; dev.name = pin; break;
1167        case 0x2: rev = "G"; dev.name = pin; break;
1168        case 0x3: rev = "H"; dev.name = pin; break;
1169        case 0x4: rev = "E"; dev.name = fiji; break;
1170        case 0x5: rev = "C"; dev.name = fiji; break;
1171        case 0x6: rev = "D"; dev.name = fiji; break;
1172        case 0x7:
1173                rev = "A-B (Fiji) or A-E (Pinnacle)";
1174                dev.name = pinfiji;
1175                break;
1176        }
1177        printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, "
1178#endif /* MSND_CLASSIC */
1179               "I/O 0x%x-0x%x, IRQ %d, memory mapped to %p-%p\n",
1180               dev.name,
1181#ifndef MSND_CLASSIC
1182               rev, xv,
1183#endif
1184               dev.io, dev.io + dev.numio - 1,
1185               dev.irq,
1186               dev.base, dev.base + 0x7fff);
1187
1188        release_region(dev.io, dev.numio);
1189        return 0;
1190}
1191
1192static int init_sma(void)
1193{
1194        static int initted;
1195        WORD mastVolLeft, mastVolRight;
1196        unsigned long flags;
1197
1198#ifdef MSND_CLASSIC
1199        msnd_outb(dev.memid, dev.io + HP_MEMM);
1200#endif
1201        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
1202        if (initted) {
1203                mastVolLeft = readw(dev.SMA + SMA_wCurrMastVolLeft);
1204                mastVolRight = readw(dev.SMA + SMA_wCurrMastVolRight);
1205        } else
1206                mastVolLeft = mastVolRight = 0;
1207        memset_io(dev.base, 0, 0x8000);
1208
1209        /* Critical section: bank 1 access */
1210        spin_lock_irqsave(&dev.lock, flags);
1211        msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
1212        memset_io(dev.base, 0, 0x8000);
1213        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
1214        spin_unlock_irqrestore(&dev.lock, flags);
1215
1216        dev.pwDSPQData = (dev.base + DSPQ_DATA_BUFF);
1217        dev.pwMODQData = (dev.base + MODQ_DATA_BUFF);
1218        dev.pwMIDQData = (dev.base + MIDQ_DATA_BUFF);
1219
1220        /* Motorola 56k shared memory base */
1221        dev.SMA = dev.base + SMA_STRUCT_START;
1222
1223        /* Digital audio play queue */
1224        dev.DAPQ = dev.base + DAPQ_OFFSET;
1225        msnd_init_queue(dev.DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
1226
1227        /* Digital audio record queue */
1228        dev.DARQ = dev.base + DARQ_OFFSET;
1229        msnd_init_queue(dev.DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
1230
1231        /* MIDI out queue */
1232        dev.MODQ = dev.base + MODQ_OFFSET;
1233        msnd_init_queue(dev.MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
1234
1235        /* MIDI in queue */
1236        dev.MIDQ = dev.base + MIDQ_OFFSET;
1237        msnd_init_queue(dev.MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
1238
1239        /* DSP -> host message queue */
1240        dev.DSPQ = dev.base + DSPQ_OFFSET;
1241        msnd_init_queue(dev.DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
1242
1243        /* Setup some DSP values */
1244#ifndef MSND_CLASSIC
1245        writew(1, dev.SMA + SMA_wCurrPlayFormat);
1246        writew(dev.play_sample_size, dev.SMA + SMA_wCurrPlaySampleSize);
1247        writew(dev.play_channels, dev.SMA + SMA_wCurrPlayChannels);
1248        writew(dev.play_sample_rate, dev.SMA + SMA_wCurrPlaySampleRate);
1249#endif
1250        writew(dev.play_sample_rate, dev.SMA + SMA_wCalFreqAtoD);
1251        writew(mastVolLeft, dev.SMA + SMA_wCurrMastVolLeft);
1252        writew(mastVolRight, dev.SMA + SMA_wCurrMastVolRight);
1253#ifndef MSND_CLASSIC
1254        writel(0x00010000, dev.SMA + SMA_dwCurrPlayPitch);
1255        writel(0x00000001, dev.SMA + SMA_dwCurrPlayRate);
1256#endif
1257        writew(0x303, dev.SMA + SMA_wCurrInputTagBits);
1258
1259        initted = 1;
1260
1261        return 0;
1262}
1263
1264static int __init calibrate_adc(WORD srate)
1265{
1266        writew(srate, dev.SMA + SMA_wCalFreqAtoD);
1267        if (dev.calibrate_signal == 0)
1268                writew(readw(dev.SMA + SMA_wCurrHostStatusFlags)
1269                       | 0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
1270        else
1271                writew(readw(dev.SMA + SMA_wCurrHostStatusFlags)
1272                       & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
1273        if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
1274            chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) {
1275                current->state = TASK_INTERRUPTIBLE;
1276                schedule_timeout(HZ / 3);
1277                return 0;
1278        }
1279        printk(KERN_WARNING LOGNAME ": ADC calibration failed\n");
1280
1281        return -EIO;
1282}
1283
1284static int upload_dsp_code(void)
1285{
1286        msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
1287#ifndef HAVE_DSPCODEH
1288        INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE);
1289        if (!INITCODE) {
1290                printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
1291                return -EBUSY;
1292        }
1293
1294        PERMCODESIZE = mod_firmware_load(PERMCODEFILE, &PERMCODE);
1295        if (!PERMCODE) {
1296                printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
1297                vfree(INITCODE);
1298                return -EBUSY;
1299        }
1300#endif
1301        memcpy_toio(dev.base, PERMCODE, PERMCODESIZE);
1302        if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) {
1303                printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
1304                return -ENODEV;
1305        }
1306#ifdef HAVE_DSPCODEH
1307        printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n");
1308#else
1309        printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
1310#endif
1311
1312#ifndef HAVE_DSPCODEH
1313        vfree(INITCODE);
1314        vfree(PERMCODE);
1315#endif
1316
1317        return 0;
1318}
1319
1320#ifdef MSND_CLASSIC
1321static void reset_proteus(void)
1322{
1323        msnd_outb(HPPRORESET_ON, dev.io + HP_PROR);
1324        mdelay(TIME_PRO_RESET);
1325        msnd_outb(HPPRORESET_OFF, dev.io + HP_PROR);
1326        mdelay(TIME_PRO_RESET_DONE);
1327}
1328#endif
1329
1330static int initialize(void)
1331{
1332        int err, timeout;
1333
1334#ifdef MSND_CLASSIC
1335        msnd_outb(HPWAITSTATE_0, dev.io + HP_WAIT);
1336        msnd_outb(HPBITMODE_16, dev.io + HP_BITM);
1337
1338        reset_proteus();
1339#endif
1340        if ((err = init_sma()) < 0) {
1341                printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
1342                return err;
1343        }
1344
1345        if ((err = reset_dsp()) < 0)
1346                return err;
1347
1348        if ((err = upload_dsp_code()) < 0) {
1349                printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n");
1350                return err;
1351        }
1352
1353        timeout = 200;
1354        while (readw(dev.base)) {
1355                mdelay(1);
1356                if (!timeout--) {
1357                        printk(KERN_DEBUG LOGNAME ": DSP reset timeout\n");
1358                        return -EIO;
1359                }
1360        }
1361
1362        mixer_setup();
1363
1364        return 0;
1365}
1366
1367static int dsp_full_reset(void)
1368{
1369        int rv;
1370
1371        if (test_bit(F_RESETTING, &dev.flags) || ++dev.nresets > 10)
1372                return 0;
1373
1374        set_bit(F_RESETTING, &dev.flags);
1375        printk(KERN_INFO LOGNAME ": DSP reset\n");
1376        dsp_halt(NULL);                 /* Unconditionally halt */
1377        if ((rv = initialize()))
1378                printk(KERN_WARNING LOGNAME ": DSP reset failed\n");
1379        force_recsrc(dev.recsrc);
1380        dsp_open(NULL);
1381        clear_bit(F_RESETTING, &dev.flags);
1382
1383        return rv;
1384}
1385
1386static int __init attach_multisound(void)
1387{
1388        int err;
1389
1390        if ((err = request_irq(dev.irq, intr, 0, dev.name, &dev)) < 0) {
1391                printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq);
1392                return err;
1393        }
1394        request_region(dev.io, dev.numio, dev.name);
1395
1396        if ((err = dsp_full_reset()) < 0) {
1397                release_region(dev.io, dev.numio);
1398                free_irq(dev.irq, &dev);
1399                return err;
1400        }
1401
1402        if ((err = msnd_register(&dev)) < 0) {
1403                printk(KERN_ERR LOGNAME ": Unable to register MultiSound\n");
1404                release_region(dev.io, dev.numio);
1405                free_irq(dev.irq, &dev);
1406                return err;
1407        }
1408
1409        if ((dev.dsp_minor = register_sound_dsp(&dev_fileops, -1)) < 0) {
1410                printk(KERN_ERR LOGNAME ": Unable to register DSP operations\n");
1411                msnd_unregister(&dev);
1412                release_region(dev.io, dev.numio);
1413                free_irq(dev.irq, &dev);
1414                return dev.dsp_minor;
1415        }
1416
1417        if ((dev.mixer_minor = register_sound_mixer(&dev_fileops, -1)) < 0) {
1418                printk(KERN_ERR LOGNAME ": Unable to register mixer operations\n");
1419                unregister_sound_mixer(dev.mixer_minor);
1420                msnd_unregister(&dev);
1421                release_region(dev.io, dev.numio);
1422                free_irq(dev.irq, &dev);
1423                return dev.mixer_minor;
1424        }
1425
1426        dev.ext_midi_dev = dev.hdr_midi_dev = -1;
1427
1428        disable_irq(dev.irq);
1429        calibrate_adc(dev.play_sample_rate);
1430#ifndef MSND_CLASSIC
1431        force_recsrc(SOUND_MASK_IMIX);
1432#endif
1433
1434        return 0;
1435}
1436
1437static void __exit unload_multisound(void)
1438{
1439        release_region(dev.io, dev.numio);
1440        free_irq(dev.irq, &dev);
1441        unregister_sound_mixer(dev.mixer_minor);
1442        unregister_sound_dsp(dev.dsp_minor);
1443        msnd_unregister(&dev);
1444}
1445
1446#ifndef MSND_CLASSIC
1447
1448/* Pinnacle/Fiji Logical Device Configuration */
1449
1450static int __init msnd_write_cfg(int cfg, int reg, int value)
1451{
1452        msnd_outb(reg, cfg);
1453        msnd_outb(value, cfg + 1);
1454        if (value != msnd_inb(cfg + 1)) {
1455                printk(KERN_ERR LOGNAME ": msnd_write_cfg: I/O error\n");
1456                return -EIO;
1457        }
1458        return 0;
1459}
1460
1461static int __init msnd_write_cfg_io0(int cfg, int num, WORD io)
1462{
1463        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1464                return -EIO;
1465        if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
1466                return -EIO;
1467        if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
1468                return -EIO;
1469        return 0;
1470}
1471
1472static int __init msnd_write_cfg_io1(int cfg, int num, WORD io)
1473{
1474        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1475                return -EIO;
1476        if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
1477                return -EIO;
1478        if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
1479                return -EIO;
1480        return 0;
1481}
1482
1483static int __init msnd_write_cfg_irq(int cfg, int num, WORD irq)
1484{
1485        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1486                return -EIO;
1487        if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
1488                return -EIO;
1489        if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
1490                return -EIO;
1491        return 0;
1492}
1493
1494static int __init msnd_write_cfg_mem(int cfg, int num, int mem)
1495{
1496        WORD wmem;
1497
1498        mem >>= 8;
1499        mem &= 0xfff;
1500        wmem = (WORD)mem;
1501        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1502                return -EIO;
1503        if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
1504                return -EIO;
1505        if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
1506                return -EIO;
1507        if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
1508                return -EIO;
1509        return 0;
1510}
1511
1512static int __init msnd_activate_logical(int cfg, int num)
1513{
1514        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1515                return -EIO;
1516        if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
1517                return -EIO;
1518        return 0;
1519}
1520
1521static int __init msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
1522{
1523        if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
1524                return -EIO;
1525        if (msnd_write_cfg_io0(cfg, num, io0))
1526                return -EIO;
1527        if (msnd_write_cfg_io1(cfg, num, io1))
1528                return -EIO;
1529        if (msnd_write_cfg_irq(cfg, num, irq))
1530                return -EIO;
1531        if (msnd_write_cfg_mem(cfg, num, mem))
1532                return -EIO;
1533        if (msnd_activate_logical(cfg, num))
1534                return -EIO;
1535        return 0;
1536}
1537
1538typedef struct msnd_pinnacle_cfg_device {
1539        WORD io0, io1, irq;
1540        int mem;
1541} msnd_pinnacle_cfg_t[4];
1542
1543static int __init msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cfg_t device)
1544{
1545        int i;
1546
1547        /* Reset devices if told to */
1548        if (reset) {
1549                printk(KERN_INFO LOGNAME ": Resetting all devices\n");
1550                for (i = 0; i < 4; ++i)
1551                        if (msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0))
1552                                return -EIO;
1553        }
1554
1555        /* Configure specified devices */
1556        for (i = 0; i < 4; ++i) {
1557
1558                switch (i) {
1559                case 0:         /* DSP */
1560                        if (!(device[i].io0 && device[i].irq && device[i].mem))
1561                                continue;
1562                        break;
1563                case 1:         /* MPU */
1564                        if (!(device[i].io0 && device[i].irq))
1565                                continue;
1566                        printk(KERN_INFO LOGNAME
1567                               ": Configuring MPU to I/O 0x%x IRQ %d\n",
1568                               device[i].io0, device[i].irq);
1569                        break;
1570                case 2:         /* IDE */
1571                        if (!(device[i].io0 && device[i].io1 && device[i].irq))
1572                                continue;
1573                        printk(KERN_INFO LOGNAME
1574                               ": Configuring IDE to I/O 0x%x, 0x%x IRQ %d\n",
1575                               device[i].io0, device[i].io1, device[i].irq);
1576                        break;
1577                case 3:         /* Joystick */
1578                        if (!(device[i].io0))
1579                                continue;
1580                        printk(KERN_INFO LOGNAME
1581                               ": Configuring joystick to I/O 0x%x\n",
1582                               device[i].io0);
1583                        break;
1584                }
1585
1586                /* Configure the device */
1587                if (msnd_write_cfg_logical(cfg, i, device[i].io0, device[i].io1, device[i].irq, device[i].mem))
1588                        return -EIO;
1589        }
1590
1591        return 0;
1592}
1593#endif
1594
1595#ifdef MODULE
1596MODULE_AUTHOR                           ("Andrew Veliath <andrewtv@usa.net>");
1597MODULE_DESCRIPTION                      ("Turtle Beach " LONGNAME " Linux Driver");
1598MODULE_LICENSE("GPL");
1599
1600static int io __initdata =              -1;
1601static int irq __initdata =             -1;
1602static int mem __initdata =             -1;
1603static int write_ndelay __initdata =    -1;
1604
1605#ifndef MSND_CLASSIC
1606/* Pinnacle/Fiji non-PnP Config Port */
1607static int cfg __initdata =             -1;
1608
1609/* Extra Peripheral Configuration */
1610static int reset __initdata = 0;
1611static int mpu_io __initdata = 0;
1612static int mpu_irq __initdata = 0;
1613static int ide_io0 __initdata = 0;
1614static int ide_io1 __initdata = 0;
1615static int ide_irq __initdata = 0;
1616static int joystick_io __initdata = 0;
1617
1618/* If we have the digital daugherboard... */
1619static int digital __initdata = 0;
1620#endif
1621
1622static int fifosize __initdata =        DEFFIFOSIZE;
1623static int calibrate_signal __initdata = 0;
1624
1625#else /* not a module */
1626
1627static int write_ndelay __initdata =    -1;
1628
1629#ifdef MSND_CLASSIC
1630static int io __initdata =              CONFIG_MSNDCLAS_IO;
1631static int irq __initdata =             CONFIG_MSNDCLAS_IRQ;
1632static int mem __initdata =             CONFIG_MSNDCLAS_MEM;
1633#else /* Pinnacle/Fiji */
1634
1635static int io __initdata =              CONFIG_MSNDPIN_IO;
1636static int irq __initdata =             CONFIG_MSNDPIN_IRQ;
1637static int mem __initdata =             CONFIG_MSNDPIN_MEM;
1638
1639/* Pinnacle/Fiji non-PnP Config Port */
1640#ifdef CONFIG_MSNDPIN_NONPNP
1641#  ifndef CONFIG_MSNDPIN_CFG
1642#    define CONFIG_MSNDPIN_CFG          0x250
1643#  endif
1644#else
1645#  ifdef CONFIG_MSNDPIN_CFG
1646#    undef CONFIG_MSNDPIN_CFG
1647#  endif
1648#  define CONFIG_MSNDPIN_CFG            -1
1649#endif
1650static int cfg __initdata =             CONFIG_MSNDPIN_CFG;
1651/* If not a module, we don't need to bother with reset=1 */
1652static int reset;
1653
1654/* Extra Peripheral Configuration (Default: Disable) */
1655#ifndef CONFIG_MSNDPIN_MPU_IO
1656#  define CONFIG_MSNDPIN_MPU_IO         0
1657#endif
1658static int mpu_io __initdata =          CONFIG_MSNDPIN_MPU_IO;
1659
1660#ifndef CONFIG_MSNDPIN_MPU_IRQ
1661#  define CONFIG_MSNDPIN_MPU_IRQ        0
1662#endif
1663static int mpu_irq __initdata =         CONFIG_MSNDPIN_MPU_IRQ;
1664
1665#ifndef CONFIG_MSNDPIN_IDE_IO0
1666#  define CONFIG_MSNDPIN_IDE_IO0        0
1667#endif
1668static int ide_io0 __initdata =         CONFIG_MSNDPIN_IDE_IO0;
1669
1670#ifndef CONFIG_MSNDPIN_IDE_IO1
1671#  define CONFIG_MSNDPIN_IDE_IO1        0
1672#endif
1673static int ide_io1 __initdata =         CONFIG_MSNDPIN_IDE_IO1;
1674
1675#ifndef CONFIG_MSNDPIN_IDE_IRQ
1676#  define CONFIG_MSNDPIN_IDE_IRQ        0
1677#endif
1678static int ide_irq __initdata =         CONFIG_MSNDPIN_IDE_IRQ;
1679
1680#ifndef CONFIG_MSNDPIN_JOYSTICK_IO
1681#  define CONFIG_MSNDPIN_JOYSTICK_IO    0
1682#endif
1683static int joystick_io __initdata =     CONFIG_MSNDPIN_JOYSTICK_IO;
1684
1685/* Have SPDIF (Digital) Daughterboard */
1686#ifndef CONFIG_MSNDPIN_DIGITAL
1687#  define CONFIG_MSNDPIN_DIGITAL        0
1688#endif
1689static int digital __initdata =         CONFIG_MSNDPIN_DIGITAL;
1690
1691#endif /* MSND_CLASSIC */
1692
1693#ifndef CONFIG_MSND_FIFOSIZE
1694#  define CONFIG_MSND_FIFOSIZE          DEFFIFOSIZE
1695#endif
1696static int fifosize __initdata =        CONFIG_MSND_FIFOSIZE;
1697
1698#ifndef CONFIG_MSND_CALSIGNAL
1699#  define CONFIG_MSND_CALSIGNAL         0
1700#endif
1701static int
1702calibrate_signal __initdata =           CONFIG_MSND_CALSIGNAL;
1703#endif /* MODULE */
1704
1705module_param                            (io, int, 0);
1706module_param                            (irq, int, 0);
1707module_param                            (mem, int, 0);
1708module_param                            (write_ndelay, int, 0);
1709module_param                            (fifosize, int, 0);
1710module_param                            (calibrate_signal, int, 0);
1711#ifndef MSND_CLASSIC
1712module_param                            (digital, bool, 0);
1713module_param                            (cfg, int, 0);
1714module_param                            (reset, int, 0);
1715module_param                            (mpu_io, int, 0);
1716module_param                            (mpu_irq, int, 0);
1717module_param                            (ide_io0, int, 0);
1718module_param                            (ide_io1, int, 0);
1719module_param                            (ide_irq, int, 0);
1720module_param                            (joystick_io, int, 0);
1721#endif
1722
1723static int __init msnd_init(void)
1724{
1725        int err;
1726#ifndef MSND_CLASSIC
1727        static msnd_pinnacle_cfg_t pinnacle_devs;
1728#endif /* MSND_CLASSIC */
1729
1730        printk(KERN_INFO LOGNAME ": Turtle Beach " LONGNAME " Linux Driver Version "
1731               VERSION ", Copyright (C) 1998 Andrew Veliath\n");
1732
1733        if (io == -1 || irq == -1 || mem == -1)
1734                printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
1735
1736#ifdef MSND_CLASSIC
1737        if (io == -1 ||
1738            !(io == 0x290 ||
1739              io == 0x260 ||
1740              io == 0x250 ||
1741              io == 0x240 ||
1742              io == 0x230 ||
1743              io == 0x220 ||
1744              io == 0x210 ||
1745              io == 0x3e0)) {
1746                printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
1747                return -EINVAL;
1748        }
1749#else
1750        if (io == -1 ||
1751                io < 0x100 ||
1752                io > 0x3e0 ||
1753                (io % 0x10) != 0) {
1754                        printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
1755                        return -EINVAL;
1756        }
1757#endif /* MSND_CLASSIC */
1758
1759        if (irq == -1 ||
1760            !(irq == 5 ||
1761              irq == 7 ||
1762              irq == 9 ||
1763              irq == 10 ||
1764              irq == 11 ||
1765              irq == 12)) {
1766                printk(KERN_ERR LOGNAME ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
1767                return -EINVAL;
1768        }
1769
1770        if (mem == -1 ||
1771            !(mem == 0xb0000 ||
1772              mem == 0xc8000 ||
1773              mem == 0xd0000 ||
1774              mem == 0xd8000 ||
1775              mem == 0xe0000 ||
1776              mem == 0xe8000)) {
1777                printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
1778                       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
1779                return -EINVAL;
1780        }
1781
1782#ifdef MSND_CLASSIC
1783        switch (irq) {
1784        case 5: dev.irqid = HPIRQ_5; break;
1785        case 7: dev.irqid = HPIRQ_7; break;
1786        case 9: dev.irqid = HPIRQ_9; break;
1787        case 10: dev.irqid = HPIRQ_10; break;
1788        case 11: dev.irqid = HPIRQ_11; break;
1789        case 12: dev.irqid = HPIRQ_12; break;
1790        }
1791
1792        switch (mem) {
1793        case 0xb0000: dev.memid = HPMEM_B000; break;
1794        case 0xc8000: dev.memid = HPMEM_C800; break;
1795        case 0xd0000: dev.memid = HPMEM_D000; break;
1796        case 0xd8000: dev.memid = HPMEM_D800; break;
1797        case 0xe0000: dev.memid = HPMEM_E000; break;
1798        case 0xe8000: dev.memid = HPMEM_E800; break;
1799        }
1800#else
1801        if (cfg == -1) {
1802                printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
1803        } else if (cfg != 0x250 && cfg != 0x260 && cfg != 0x270) {
1804                printk(KERN_INFO LOGNAME ": Config port must be 0x250, 0x260 or 0x270 (or unspecified for PnP mode)\n");
1805                return -EINVAL;
1806        } else {
1807                printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%x\n", cfg);
1808
1809                /* DSP */
1810                pinnacle_devs[0].io0 = io;
1811                pinnacle_devs[0].irq = irq;
1812                pinnacle_devs[0].mem = mem;
1813
1814                /* The following are Pinnacle specific */
1815
1816                /* MPU */
1817                pinnacle_devs[1].io0 = mpu_io;
1818                pinnacle_devs[1].irq = mpu_irq;
1819
1820                /* IDE */
1821                pinnacle_devs[2].io0 = ide_io0;
1822                pinnacle_devs[2].io1 = ide_io1;
1823                pinnacle_devs[2].irq = ide_irq;
1824
1825                /* Joystick */
1826                pinnacle_devs[3].io0 = joystick_io;
1827
1828                if (!request_region(cfg, 2, "Pinnacle/Fiji Config")) {
1829                        printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg);
1830                        return -EIO;
1831                }
1832
1833                if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) {
1834                        printk(KERN_ERR LOGNAME ": Device configuration error\n");
1835                        release_region(cfg, 2);
1836                        return -EIO;
1837                }
1838                release_region(cfg, 2);
1839        }
1840#endif /* MSND_CLASSIC */
1841
1842        if (fifosize < 16)
1843                fifosize = 16;
1844
1845        if (fifosize > 1024)
1846                fifosize = 1024;
1847
1848        set_default_audio_parameters();
1849#ifdef MSND_CLASSIC
1850        dev.type = msndClassic;
1851#else
1852        dev.type = msndPinnacle;
1853#endif
1854        dev.io = io;
1855        dev.numio = DSP_NUMIO;
1856        dev.irq = irq;
1857        dev.base = ioremap(mem, 0x8000);
1858        dev.fifosize = fifosize * 1024;
1859        dev.calibrate_signal = calibrate_signal ? 1 : 0;
1860        dev.recsrc = 0;
1861        dev.dspq_data_buff = DSPQ_DATA_BUFF;
1862        dev.dspq_buff_size = DSPQ_BUFF_SIZE;
1863        if (write_ndelay == -1)
1864                write_ndelay = CONFIG_MSND_WRITE_NDELAY;
1865        if (write_ndelay)
1866                clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
1867        else
1868                set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
1869#ifndef MSND_CLASSIC
1870        if (digital)
1871                set_bit(F_HAVEDIGITAL, &dev.flags);
1872#endif
1873        init_waitqueue_head(&dev.writeblock);
1874        init_waitqueue_head(&dev.readblock);
1875        init_waitqueue_head(&dev.writeflush);
1876        msnd_fifo_init(&dev.DAPF);
1877        msnd_fifo_init(&dev.DARF);
1878        spin_lock_init(&dev.lock);
1879        printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize);
1880        if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) {
1881                printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n");
1882                return err;
1883        }
1884
1885        if ((err = msnd_fifo_alloc(&dev.DARF, dev.fifosize)) < 0) {
1886                printk(KERN_ERR LOGNAME ": Couldn't allocate read FIFO\n");
1887                msnd_fifo_free(&dev.DAPF);
1888                return err;
1889        }
1890
1891        if ((err = probe_multisound()) < 0) {
1892                printk(KERN_ERR LOGNAME ": Probe failed\n");
1893                msnd_fifo_free(&dev.DAPF);
1894                msnd_fifo_free(&dev.DARF);
1895                return err;
1896        }
1897
1898        if ((err = attach_multisound()) < 0) {
1899                printk(KERN_ERR LOGNAME ": Attach failed\n");
1900                msnd_fifo_free(&dev.DAPF);
1901                msnd_fifo_free(&dev.DARF);
1902                return err;
1903        }
1904
1905        return 0;
1906}
1907
1908static void __exit msdn_cleanup(void)
1909{
1910        unload_multisound();
1911        msnd_fifo_free(&dev.DAPF);
1912        msnd_fifo_free(&dev.DARF);
1913}
1914
1915module_init(msnd_init);
1916module_exit(msdn_cleanup);
1917