linux-old/drivers/sound/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 * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $
  33 *
  34 * 12-3-2000  Modified IO port validation  Steve Sycamore
  35 *
  36 *
  37 * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $
  38 *
  39 ********************************************************************/
  40
  41#include <linux/kernel.h>
  42#include <linux/config.h>
  43#include <linux/version.h>
  44#include <linux/module.h>
  45#include <linux/slab.h>
  46#include <linux/types.h>
  47#include <linux/delay.h>
  48#include <linux/init.h>
  49#include <linux/smp_lock.h>
  50#include <asm/irq.h>
  51#include <asm/io.h>
  52#include "sound_config.h"
  53#include "sound_firmware.h"
  54#ifdef MSND_CLASSIC
  55# ifndef __alpha__
  56#  define SLOWIO
  57# endif
  58#endif
  59#include "msnd.h"
  60#ifdef MSND_CLASSIC
  61#  ifdef CONFIG_MSNDCLAS_HAVE_BOOT
  62#    define HAVE_DSPCODEH
  63#  endif
  64#  include "msnd_classic.h"
  65#  define LOGNAME                       "msnd_classic"
  66#else
  67#  ifdef CONFIG_MSNDPIN_HAVE_BOOT
  68#    define HAVE_DSPCODEH
  69#  endif
  70#  include "msnd_pinnacle.h"
  71#  define LOGNAME                       "msnd_pinnacle"
  72#endif
  73
  74#ifndef CONFIG_MSND_WRITE_NDELAY
  75#  define CONFIG_MSND_WRITE_NDELAY      1
  76#endif
  77
  78#define get_play_delay_jiffies(size)    ((size) * HZ *                  \
  79                                         dev.play_sample_size / 8 /     \
  80                                         dev.play_sample_rate /         \
  81                                         dev.play_channels)
  82
  83#define get_rec_delay_jiffies(size)     ((size) * HZ *                  \
  84                                         dev.rec_sample_size / 8 /      \
  85                                         dev.rec_sample_rate /          \
  86                                         dev.rec_channels)
  87
  88static multisound_dev_t                 dev;
  89
  90#ifndef HAVE_DSPCODEH
  91static char                             *dspini, *permini;
  92static int                              sizeof_dspini, sizeof_permini;
  93#endif
  94
  95static int                              dsp_full_reset(void);
  96static void                             dsp_write_flush(void);
  97
  98static __inline__ int chk_send_dsp_cmd(multisound_dev_t *dev, register BYTE cmd)
  99{
 100        if (msnd_send_dsp_cmd(dev, cmd) == 0)
 101                return 0;
 102        dsp_full_reset();
 103        return msnd_send_dsp_cmd(dev, cmd);
 104}
 105
 106static void reset_play_queue(void)
 107{
 108        int n;
 109        LPDAQD lpDAQ;
 110
 111        dev.last_playbank = -1;
 112        isa_writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wHead);
 113        isa_writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wTail);
 114
 115        for (n = 0, lpDAQ = dev.base + DAPQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
 116                isa_writew(PCTODSP_BASED((DWORD)(DAP_BUFF_SIZE * n)), lpDAQ + DAQDS_wStart);
 117                isa_writew(0, lpDAQ + DAQDS_wSize);
 118                isa_writew(1, lpDAQ + DAQDS_wFormat);
 119                isa_writew(dev.play_sample_size, lpDAQ + DAQDS_wSampleSize);
 120                isa_writew(dev.play_channels, lpDAQ + DAQDS_wChannels);
 121                isa_writew(dev.play_sample_rate, lpDAQ + DAQDS_wSampleRate);
 122                isa_writew(HIMT_PLAY_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
 123                isa_writew(n, lpDAQ + DAQDS_wFlags);
 124        }
 125}
 126
 127static void reset_record_queue(void)
 128{
 129        int n;
 130        LPDAQD lpDAQ;
 131        unsigned long flags;
 132
 133        dev.last_recbank = 2;
 134        isa_writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DARQ + JQS_wHead);
 135        isa_writew(PCTODSP_OFFSET(dev.last_recbank * DAQDS__size), dev.DARQ + JQS_wTail);
 136
 137        /* Critical section: bank 1 access */
 138        spin_lock_irqsave(&dev.lock, flags);
 139        outb(HPBLKSEL_1, dev.io + HP_BLKS);
 140        isa_memset_io(dev.base, 0, DAR_BUFF_SIZE * 3);
 141        outb(HPBLKSEL_0, dev.io + HP_BLKS);
 142        spin_unlock_irqrestore(&dev.lock, flags);
 143
 144        for (n = 0, lpDAQ = dev.base + DARQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
 145                isa_writew(PCTODSP_BASED((DWORD)(DAR_BUFF_SIZE * n)) + 0x4000, lpDAQ + DAQDS_wStart);
 146                isa_writew(DAR_BUFF_SIZE, lpDAQ + DAQDS_wSize);
 147                isa_writew(1, lpDAQ + DAQDS_wFormat);
 148                isa_writew(dev.rec_sample_size, lpDAQ + DAQDS_wSampleSize);
 149                isa_writew(dev.rec_channels, lpDAQ + DAQDS_wChannels);
 150                isa_writew(dev.rec_sample_rate, lpDAQ + DAQDS_wSampleRate);
 151                isa_writew(HIMT_RECORD_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
 152                isa_writew(n, lpDAQ + DAQDS_wFlags);
 153        }
 154}
 155
 156static void reset_queues(void)
 157{
 158        if (dev.mode & FMODE_WRITE) {
 159                msnd_fifo_make_empty(&dev.DAPF);
 160                reset_play_queue();
 161        }
 162        if (dev.mode & FMODE_READ) {
 163                msnd_fifo_make_empty(&dev.DARF);
 164                reset_record_queue();
 165        }
 166}
 167
 168static int dsp_set_format(struct file *file, int val)
 169{
 170        int data, i;
 171        LPDAQD lpDAQ, lpDARQ;
 172
 173        lpDAQ = dev.base + DAPQ_DATA_BUFF;
 174        lpDARQ = dev.base + DARQ_DATA_BUFF;
 175
 176        switch (val) {
 177        case AFMT_U8:
 178        case AFMT_S16_LE:
 179                data = val;
 180                break;
 181        default:
 182                data = DEFSAMPLESIZE;
 183                break;
 184        }
 185
 186        for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
 187                if (file->f_mode & FMODE_WRITE)
 188                        isa_writew(data, lpDAQ + DAQDS_wSampleSize);
 189                if (file->f_mode & FMODE_READ)
 190                        isa_writew(data, lpDARQ + DAQDS_wSampleSize);
 191        }
 192        if (file->f_mode & FMODE_WRITE)
 193                dev.play_sample_size = data;
 194        if (file->f_mode & FMODE_READ)
 195                dev.rec_sample_size = data;
 196
 197        return data;
 198}
 199
 200static int dsp_get_frag_size(void)
 201{
 202        int size;
 203        size = dev.fifosize / 4;
 204        if (size > 32 * 1024)
 205                size = 32 * 1024;
 206        return size;
 207}
 208
 209static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 210{
 211        int val, i, data, tmp;
 212        LPDAQD lpDAQ, lpDARQ;
 213        audio_buf_info abinfo;
 214        unsigned long flags;
 215
 216        lpDAQ = dev.base + DAPQ_DATA_BUFF;
 217        lpDARQ = dev.base + DARQ_DATA_BUFF;
 218
 219        switch (cmd) {
 220        case SNDCTL_DSP_SUBDIVIDE:
 221        case SNDCTL_DSP_SETFRAGMENT:
 222        case SNDCTL_DSP_SETDUPLEX:
 223        case SNDCTL_DSP_POST:
 224                return 0;
 225
 226        case SNDCTL_DSP_GETIPTR:
 227        case SNDCTL_DSP_GETOPTR:
 228        case SNDCTL_DSP_MAPINBUF:
 229        case SNDCTL_DSP_MAPOUTBUF:
 230                return -EINVAL;
 231
 232        case SNDCTL_DSP_GETOSPACE:
 233                if (!(file->f_mode & FMODE_WRITE))
 234                        return -EINVAL;
 235                spin_lock_irqsave(&dev.lock, flags);
 236                abinfo.fragsize = dsp_get_frag_size();
 237                abinfo.bytes = dev.DAPF.n - dev.DAPF.len;
 238                abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
 239                abinfo.fragments = abinfo.bytes / abinfo.fragsize;
 240                spin_unlock_irqrestore(&dev.lock, flags);
 241                return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 242
 243        case SNDCTL_DSP_GETISPACE:
 244                if (!(file->f_mode & FMODE_READ))
 245                        return -EINVAL;
 246                spin_lock_irqsave(&dev.lock, flags);
 247                abinfo.fragsize = dsp_get_frag_size();
 248                abinfo.bytes = dev.DARF.n - dev.DARF.len;
 249                abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
 250                abinfo.fragments = abinfo.bytes / abinfo.fragsize;
 251                spin_unlock_irqrestore(&dev.lock, flags);
 252                return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 253
 254        case SNDCTL_DSP_RESET:
 255                dev.nresets = 0;
 256                reset_queues();
 257                return 0;
 258
 259        case SNDCTL_DSP_SYNC:
 260                dsp_write_flush();
 261                return 0;
 262
 263        case SNDCTL_DSP_GETBLKSIZE:
 264                tmp = dsp_get_frag_size();
 265                if (put_user(tmp, (int *)arg))
 266                        return -EFAULT;
 267                return 0;
 268
 269        case SNDCTL_DSP_GETFMTS:
 270                val = AFMT_S16_LE | AFMT_U8;
 271                if (put_user(val, (int *)arg))
 272                        return -EFAULT;
 273                return 0;
 274
 275        case SNDCTL_DSP_SETFMT:
 276                if (get_user(val, (int *)arg))
 277                        return -EFAULT;
 278
 279                if (file->f_mode & FMODE_WRITE)
 280                        data = val == AFMT_QUERY
 281                                ? dev.play_sample_size
 282                                : dsp_set_format(file, val);
 283                else
 284                        data = val == AFMT_QUERY
 285                                ? dev.rec_sample_size
 286                                : dsp_set_format(file, val);
 287
 288                if (put_user(data, (int *)arg))
 289                        return -EFAULT;
 290                return 0;
 291
 292        case SNDCTL_DSP_NONBLOCK:
 293                if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) &&
 294                    file->f_mode & FMODE_WRITE)
 295                        dev.play_ndelay = 1;
 296                if (file->f_mode & FMODE_READ)
 297                        dev.rec_ndelay = 1;
 298                return 0;
 299
 300        case SNDCTL_DSP_GETCAPS:
 301                val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
 302                if (put_user(val, (int *)arg))
 303                        return -EFAULT;
 304                return 0;
 305
 306        case SNDCTL_DSP_SPEED:
 307                if (get_user(val, (int *)arg))
 308                        return -EFAULT;
 309
 310                if (val < 8000)
 311                        val = 8000;
 312
 313                if (val > 48000)
 314                        val = 48000;
 315
 316                data = val;
 317
 318                for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
 319                        if (file->f_mode & FMODE_WRITE)
 320                                isa_writew(data, lpDAQ + DAQDS_wSampleRate);
 321                        if (file->f_mode & FMODE_READ)
 322                                isa_writew(data, lpDARQ + DAQDS_wSampleRate);
 323                }
 324                if (file->f_mode & FMODE_WRITE)
 325                        dev.play_sample_rate = data;
 326                if (file->f_mode & FMODE_READ)
 327                        dev.rec_sample_rate = data;
 328
 329                if (put_user(data, (int *)arg))
 330                        return -EFAULT;
 331                return 0;
 332
 333        case SNDCTL_DSP_CHANNELS:
 334        case SNDCTL_DSP_STEREO:
 335                if (get_user(val, (int *)arg))
 336                        return -EFAULT;
 337
 338                if (cmd == SNDCTL_DSP_CHANNELS) {
 339                        switch (val) {
 340                        case 1:
 341                        case 2:
 342                                data = val;
 343                                break;
 344                        default:
 345                                val = data = 2;
 346                                break;
 347                        }
 348                } else {
 349                        switch (val) {
 350                        case 0:
 351                                data = 1;
 352                                break;
 353                        default:
 354                                val = 1;
 355                        case 1:
 356                                data = 2;
 357                                break;
 358                        }
 359                }
 360
 361                for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
 362                        if (file->f_mode & FMODE_WRITE)
 363                                isa_writew(data, lpDAQ + DAQDS_wChannels);
 364                        if (file->f_mode & FMODE_READ)
 365                                isa_writew(data, lpDARQ + DAQDS_wChannels);
 366                }
 367                if (file->f_mode & FMODE_WRITE)
 368                        dev.play_channels = data;
 369                if (file->f_mode & FMODE_READ)
 370                        dev.rec_channels = data;
 371
 372                if (put_user(val, (int *)arg))
 373                        return -EFAULT;
 374                return 0;
 375        }
 376
 377        return -EINVAL;
 378}
 379
 380static int mixer_get(int d)
 381{
 382        if (d > 31)
 383                return -EINVAL;
 384
 385        switch (d) {
 386        case SOUND_MIXER_VOLUME:
 387        case SOUND_MIXER_PCM:
 388        case SOUND_MIXER_LINE:
 389        case SOUND_MIXER_IMIX:
 390        case SOUND_MIXER_LINE1:
 391#ifndef MSND_CLASSIC
 392        case SOUND_MIXER_MIC:
 393        case SOUND_MIXER_SYNTH:
 394#endif
 395                return (dev.left_levels[d] >> 8) * 100 / 0xff | 
 396                        (((dev.right_levels[d] >> 8) * 100 / 0xff) << 8);
 397        default:
 398                return 0;
 399        }
 400}
 401
 402#define update_volm(a,b)                                                \
 403        isa_writew((dev.left_levels[a] >> 1) *                          \
 404               isa_readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff,      \
 405               dev.SMA + SMA_##b##Left);                                \
 406        isa_writew((dev.right_levels[a] >> 1)  *                        \
 407               isa_readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff,     \
 408               dev.SMA + SMA_##b##Right);
 409
 410#define update_potm(d,s,ar)                                             \
 411        isa_writeb((dev.left_levels[d] >> 8) *                          \
 412               isa_readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff,      \
 413               dev.SMA + SMA_##s##Left);                                \
 414        isa_writeb((dev.right_levels[d] >> 8) *                         \
 415               isa_readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff,     \
 416               dev.SMA + SMA_##s##Right);                               \
 417        if (msnd_send_word(&dev, 0, 0, ar) == 0)                        \
 418                chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 419
 420#define update_pot(d,s,ar)                              \
 421        isa_writeb(dev.left_levels[d] >> 8,             \
 422               dev.SMA + SMA_##s##Left);                \
 423        isa_writeb(dev.right_levels[d] >> 8,            \
 424               dev.SMA + SMA_##s##Right);               \
 425        if (msnd_send_word(&dev, 0, 0, ar) == 0)        \
 426                chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 427
 428static int mixer_set(int d, int value)
 429{
 430        int left = value & 0x000000ff;
 431        int right = (value & 0x0000ff00) >> 8;
 432        int bLeft, bRight;
 433        int wLeft, wRight;
 434        int updatemaster = 0;
 435
 436        if (d > 31)
 437                return -EINVAL;
 438
 439        bLeft = left * 0xff / 100;
 440        wLeft = left * 0xffff / 100;
 441
 442        bRight = right * 0xff / 100;
 443        wRight = right * 0xffff / 100;
 444
 445        dev.left_levels[d] = wLeft;
 446        dev.right_levels[d] = wRight;
 447
 448        switch (d) {
 449                /* master volume unscaled controls */
 450        case SOUND_MIXER_LINE:                  /* line pot control */
 451                /* scaled by IMIX in digital mix */
 452                isa_writeb(bLeft, dev.SMA + SMA_bInPotPosLeft);
 453                isa_writeb(bRight, dev.SMA + SMA_bInPotPosRight);
 454                if (msnd_send_word(&dev, 0, 0, HDEXAR_IN_SET_POTS) == 0)
 455                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 456                break;
 457#ifndef MSND_CLASSIC
 458        case SOUND_MIXER_MIC:                   /* mic pot control */
 459                /* scaled by IMIX in digital mix */
 460                isa_writeb(bLeft, dev.SMA + SMA_bMicPotPosLeft);
 461                isa_writeb(bRight, dev.SMA + SMA_bMicPotPosRight);
 462                if (msnd_send_word(&dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
 463                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 464                break;
 465#endif
 466        case SOUND_MIXER_VOLUME:                /* master volume */
 467                isa_writew(wLeft, dev.SMA + SMA_wCurrMastVolLeft);
 468                isa_writew(wRight, dev.SMA + SMA_wCurrMastVolRight);
 469                /* fall through */
 470
 471        case SOUND_MIXER_LINE1:                 /* aux pot control */
 472                /* scaled by master volume */
 473                /* fall through */
 474
 475                /* digital controls */
 476        case SOUND_MIXER_SYNTH:                 /* synth vol (dsp mix) */
 477        case SOUND_MIXER_PCM:                   /* pcm vol (dsp mix) */
 478        case SOUND_MIXER_IMIX:                  /* input monitor (dsp mix) */
 479                /* scaled by master volume */
 480                updatemaster = 1;
 481                break;
 482
 483        default:
 484                return 0;
 485        }
 486
 487        if (updatemaster) {
 488                /* update master volume scaled controls */
 489                update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
 490                update_volm(SOUND_MIXER_IMIX, wCurrInVol);
 491#ifndef MSND_CLASSIC
 492                update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
 493#endif
 494                update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
 495        }
 496
 497        return mixer_get(d);
 498}
 499
 500static void mixer_setup(void)
 501{
 502        update_pot(SOUND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS);
 503        update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
 504        update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
 505        update_volm(SOUND_MIXER_IMIX, wCurrInVol);
 506#ifndef MSND_CLASSIC
 507        update_pot(SOUND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS);
 508        update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
 509#endif
 510}
 511
 512static unsigned long set_recsrc(unsigned long recsrc)
 513{
 514        if (dev.recsrc == recsrc)
 515                return dev.recsrc;
 516#ifdef HAVE_NORECSRC
 517        else if (recsrc == 0)
 518                dev.recsrc = 0;
 519#endif
 520        else
 521                dev.recsrc ^= recsrc;
 522
 523#ifndef MSND_CLASSIC
 524        if (dev.recsrc & SOUND_MASK_IMIX) {
 525                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
 526                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 527        }
 528        else if (dev.recsrc & SOUND_MASK_SYNTH) {
 529                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_SYNTH_IN) == 0)
 530                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 531        }
 532        else if ((dev.recsrc & SOUND_MASK_DIGITAL1) && test_bit(F_HAVEDIGITAL, &dev.flags)) {
 533                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_DAT_IN) == 0)
 534                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 535        }
 536        else {
 537#ifdef HAVE_NORECSRC
 538                /* Select no input (?) */
 539                dev.recsrc = 0;
 540#else
 541                dev.recsrc = SOUND_MASK_IMIX;
 542                if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
 543                        chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
 544#endif
 545        }
 546#endif /* MSND_CLASSIC */
 547
 548        return dev.recsrc;
 549}
 550
 551static unsigned long force_recsrc(unsigned long recsrc)
 552{
 553        dev.recsrc = 0;
 554        return set_recsrc(recsrc);
 555}
 556
 557#define set_mixer_info()                                                        \
 558                strncpy(info.id, "MSNDMIXER", sizeof(info.id));                 \
 559                strncpy(info.name, "MultiSound Mixer", sizeof(info.name));
 560
 561static int mixer_ioctl(unsigned int cmd, unsigned long arg)
 562{
 563        if (cmd == SOUND_MIXER_INFO) {
 564                mixer_info info;
 565                set_mixer_info();
 566                info.modify_counter = dev.mixer_mod_count;
 567                return copy_to_user((void *)arg, &info, sizeof(info))?-EFAULT:0;
 568        } else if (cmd == SOUND_OLD_MIXER_INFO) {
 569                _old_mixer_info info;
 570                set_mixer_info();
 571                return copy_to_user((void *)arg, &info, sizeof(info))?-EFAULT: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 *)arg))
 583                                        return -EFAULT;
 584                                val = set_recsrc(val);
 585                                break;
 586
 587                        default:
 588                                if (get_user(val, (int *)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 *)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 *)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 = MINOR(inode->i_rdev);
 645
 646        if (cmd == OSS_GETVERSION) {
 647                int sound_version = SOUND_VERSION;
 648                return put_user(sound_version, (int *)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 = MINOR(inode->i_rdev);
 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 = MINOR(inode->i_rdev);
 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 = isa_readw(dev.DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
 813        if (wTmp > isa_readw(dev.DARQ + JQS_wSize))
 814                wTmp = 0;
 815        while (wTmp == isa_readw(dev.DARQ + JQS_wHead) && timeout--)
 816                udelay(1);
 817        isa_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 = isa_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        outb(HPBLKSEL_1, dev.io + HP_BLKS);
 828        msnd_fifo_write(
 829                &dev.DARF,
 830                (char *)(dev.base + bank * DAR_BUFF_SIZE),
 831                size);
 832        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 = isa_readw(dev.DAPQ + JQS_wTail);
 844        while (DAPQ_tail != isa_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(
 854                                &dev.DAPF,
 855                                (char *)(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(
 860                                &dev.DAPF,
 861                                (char *)(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                isa_writew(n, DAQD + DAQDS_wSize);
 875                ++nbanks;
 876
 877                /* Then advance the tail */
 878                DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);
 879                isa_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 *buf, size_t len)
 887{
 888        int count = len;
 889        char *page = (char *)__get_free_page(PAGE_SIZE);
 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 *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 *buf, size_t count, loff_t *off)
1004{
1005        int minor = MINOR(file->f_dentry->d_inode->i_rdev);
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 *buf, size_t count, loff_t *off)
1013{
1014        int minor = MINOR(file->f_dentry->d_inode->i_rdev);
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 void intr(int irq, void *dev_id, struct pt_regs *regs)
1086{
1087        /* Send ack to DSP */
1088        inb(dev.io + HP_RXL);
1089
1090        /* Evaluate queued DSP messages */
1091        while (isa_readw(dev.DSPQ + JQS_wTail) != isa_readw(dev.DSPQ + JQS_wHead)) {
1092                register WORD wTmp;
1093
1094                eval_dsp_msg(isa_readw(dev.pwDSPQData + 2*isa_readw(dev.DSPQ + JQS_wHead)));
1095
1096                if ((wTmp = isa_readw(dev.DSPQ + JQS_wHead) + 1) > isa_readw(dev.DSPQ + JQS_wSize))
1097                        isa_writew(0, dev.DSPQ + JQS_wHead);
1098                else
1099                        isa_writew(wTmp, dev.DSPQ + JQS_wHead);
1100        }
1101}
1102
1103static struct file_operations dev_fileops = {
1104        owner:          THIS_MODULE,
1105        read:           dev_read,
1106        write:          dev_write,
1107        ioctl:          dev_ioctl,
1108        open:           dev_open,
1109        release:        dev_release,
1110};
1111
1112static int reset_dsp(void)
1113{
1114        int timeout = 100;
1115
1116        outb(HPDSPRESET_ON, dev.io + HP_DSPR);
1117        mdelay(1);
1118#ifndef MSND_CLASSIC
1119        dev.info = inb(dev.io + HP_INFO);
1120#endif
1121        outb(HPDSPRESET_OFF, dev.io + HP_DSPR);
1122        mdelay(1);
1123        while (timeout-- > 0) {
1124                if (inb(dev.io + HP_CVR) == HP_CVR_DEF)
1125                        return 0;
1126                mdelay(1);
1127        }
1128        printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
1129
1130        return -EIO;
1131}
1132
1133static int __init probe_multisound(void)
1134{
1135#ifndef MSND_CLASSIC
1136        char *xv, *rev = NULL;
1137        char *pin = "Pinnacle", *fiji = "Fiji";
1138        char *pinfiji = "Pinnacle/Fiji";
1139#endif
1140
1141        if (check_region(dev.io, dev.numio)) {
1142                printk(KERN_ERR LOGNAME ": I/O port conflict\n");
1143                return -ENODEV;
1144        }
1145        request_region(dev.io, dev.numio, "probing");
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 0x%lX-0x%lX\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        outb(dev.memid, dev.io + HP_MEMM);
1200#endif
1201        outb(HPBLKSEL_0, dev.io + HP_BLKS);
1202        if (initted) {
1203                mastVolLeft = isa_readw(dev.SMA + SMA_wCurrMastVolLeft);
1204                mastVolRight = isa_readw(dev.SMA + SMA_wCurrMastVolRight);
1205        } else
1206                mastVolLeft = mastVolRight = 0;
1207        isa_memset_io(dev.base, 0, 0x8000);
1208
1209        /* Critical section: bank 1 access */
1210        spin_lock_irqsave(&dev.lock, flags);
1211        outb(HPBLKSEL_1, dev.io + HP_BLKS);
1212        isa_memset_io(dev.base, 0, 0x8000);
1213        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        isa_writew(1, dev.SMA + SMA_wCurrPlayFormat);
1246        isa_writew(dev.play_sample_size, dev.SMA + SMA_wCurrPlaySampleSize);
1247        isa_writew(dev.play_channels, dev.SMA + SMA_wCurrPlayChannels);
1248        isa_writew(dev.play_sample_rate, dev.SMA + SMA_wCurrPlaySampleRate);
1249#endif
1250        isa_writew(dev.play_sample_rate, dev.SMA + SMA_wCalFreqAtoD);
1251        isa_writew(mastVolLeft, dev.SMA + SMA_wCurrMastVolLeft);
1252        isa_writew(mastVolRight, dev.SMA + SMA_wCurrMastVolRight);
1253#ifndef MSND_CLASSIC
1254        isa_writel(0x00010000, dev.SMA + SMA_dwCurrPlayPitch);
1255        isa_writel(0x00000001, dev.SMA + SMA_dwCurrPlayRate);
1256#endif
1257        isa_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        isa_writew(srate, dev.SMA + SMA_wCalFreqAtoD);
1267        if (dev.calibrate_signal == 0)
1268                isa_writew(isa_readw(dev.SMA + SMA_wCurrHostStatusFlags)
1269                       | 0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
1270        else
1271                isa_writew(isa_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        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        isa_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        outb(HPPRORESET_ON, dev.io + HP_PROR);
1324        mdelay(TIME_PRO_RESET);
1325        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        outb(HPWAITSTATE_0, dev.io + HP_WAIT);
1336        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 (isa_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        outb(reg, cfg);
1453        outb(value, cfg + 1);
1454        if (value != 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
1600MODULE_PARM                             (io, "i");
1601MODULE_PARM                             (irq, "i");
1602MODULE_PARM                             (mem, "i");
1603MODULE_PARM                             (write_ndelay, "i");
1604MODULE_PARM                             (fifosize, "i");
1605MODULE_PARM                             (calibrate_signal, "i");
1606#ifndef MSND_CLASSIC
1607MODULE_PARM                             (digital, "i");
1608MODULE_PARM                             (cfg, "i");
1609MODULE_PARM                             (reset, "i");
1610MODULE_PARM                             (mpu_io, "i");
1611MODULE_PARM                             (mpu_irq, "i");
1612MODULE_PARM                             (ide_io0, "i");
1613MODULE_PARM                             (ide_io1, "i");
1614MODULE_PARM                             (ide_irq, "i");
1615MODULE_PARM                             (joystick_io, "i");
1616#endif
1617
1618static int io __initdata =              -1;
1619static int irq __initdata =             -1;
1620static int mem __initdata =             -1;
1621static int write_ndelay __initdata =    -1;
1622
1623#ifndef MSND_CLASSIC
1624/* Pinnacle/Fiji non-PnP Config Port */
1625static int cfg __initdata =             -1;
1626
1627/* Extra Peripheral Configuration */
1628static int reset __initdata = 0;
1629static int mpu_io __initdata = 0;
1630static int mpu_irq __initdata = 0;
1631static int ide_io0 __initdata = 0;
1632static int ide_io1 __initdata = 0;
1633static int ide_irq __initdata = 0;
1634static int joystick_io __initdata = 0;
1635
1636/* If we have the digital daugherboard... */
1637static int digital __initdata = 0;
1638#endif
1639
1640static int fifosize __initdata =        DEFFIFOSIZE;
1641static int calibrate_signal __initdata = 0;
1642
1643#else /* not a module */
1644
1645static int write_ndelay __initdata =    -1;
1646
1647#ifdef MSND_CLASSIC
1648static int io __initdata =              CONFIG_MSNDCLAS_IO;
1649static int irq __initdata =             CONFIG_MSNDCLAS_IRQ;
1650static int mem __initdata =             CONFIG_MSNDCLAS_MEM;
1651#else /* Pinnacle/Fiji */
1652
1653static int io __initdata =              CONFIG_MSNDPIN_IO;
1654static int irq __initdata =             CONFIG_MSNDPIN_IRQ;
1655static int mem __initdata =             CONFIG_MSNDPIN_MEM;
1656
1657/* Pinnacle/Fiji non-PnP Config Port */
1658#ifdef CONFIG_MSNDPIN_NONPNP
1659#  ifndef CONFIG_MSNDPIN_CFG
1660#    define CONFIG_MSNDPIN_CFG          0x250
1661#  endif
1662#else
1663#  ifdef CONFIG_MSNDPIN_CFG
1664#    undef CONFIG_MSNDPIN_CFG
1665#  endif
1666#  define CONFIG_MSNDPIN_CFG            -1
1667#endif
1668static int cfg __initdata =             CONFIG_MSNDPIN_CFG;
1669/* If not a module, we don't need to bother with reset=1 */
1670static int reset;
1671
1672/* Extra Peripheral Configuration (Default: Disable) */
1673#ifndef CONFIG_MSNDPIN_MPU_IO
1674#  define CONFIG_MSNDPIN_MPU_IO         0
1675#endif
1676static int mpu_io __initdata =          CONFIG_MSNDPIN_MPU_IO;
1677
1678#ifndef CONFIG_MSNDPIN_MPU_IRQ
1679#  define CONFIG_MSNDPIN_MPU_IRQ        0
1680#endif
1681static int mpu_irq __initdata =         CONFIG_MSNDPIN_MPU_IRQ;
1682
1683#ifndef CONFIG_MSNDPIN_IDE_IO0
1684#  define CONFIG_MSNDPIN_IDE_IO0        0
1685#endif
1686static int ide_io0 __initdata =         CONFIG_MSNDPIN_IDE_IO0;
1687
1688#ifndef CONFIG_MSNDPIN_IDE_IO1
1689#  define CONFIG_MSNDPIN_IDE_IO1        0
1690#endif
1691static int ide_io1 __initdata =         CONFIG_MSNDPIN_IDE_IO1;
1692
1693#ifndef CONFIG_MSNDPIN_IDE_IRQ
1694#  define CONFIG_MSNDPIN_IDE_IRQ        0
1695#endif
1696static int ide_irq __initdata =         CONFIG_MSNDPIN_IDE_IRQ;
1697
1698#ifndef CONFIG_MSNDPIN_JOYSTICK_IO
1699#  define CONFIG_MSNDPIN_JOYSTICK_IO    0
1700#endif
1701static int joystick_io __initdata =     CONFIG_MSNDPIN_JOYSTICK_IO;
1702
1703/* Have SPDIF (Digital) Daughterboard */
1704#ifndef CONFIG_MSNDPIN_DIGITAL
1705#  define CONFIG_MSNDPIN_DIGITAL        0
1706#endif
1707static int digital __initdata =         CONFIG_MSNDPIN_DIGITAL;
1708
1709#endif /* MSND_CLASSIC */
1710
1711#ifndef CONFIG_MSND_FIFOSIZE
1712#  define CONFIG_MSND_FIFOSIZE          DEFFIFOSIZE
1713#endif
1714static int fifosize __initdata =        CONFIG_MSND_FIFOSIZE;
1715
1716#ifndef CONFIG_MSND_CALSIGNAL
1717#  define CONFIG_MSND_CALSIGNAL         0
1718#endif
1719static int
1720calibrate_signal __initdata =           CONFIG_MSND_CALSIGNAL;
1721#endif /* MODULE */
1722
1723
1724static int __init msnd_init(void)
1725{
1726        int err;
1727#ifndef MSND_CLASSIC
1728        static msnd_pinnacle_cfg_t pinnacle_devs;
1729#endif /* MSND_CLASSIC */
1730
1731        printk(KERN_INFO LOGNAME ": Turtle Beach " LONGNAME " Linux Driver Version "
1732               VERSION ", Copyright (C) 1998 Andrew Veliath\n");
1733
1734        if (io == -1 || irq == -1 || mem == -1)
1735                printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
1736
1737#ifdef MSND_CLASSIC
1738        if (io == -1 ||
1739            !(io == 0x290 ||
1740              io == 0x260 ||
1741              io == 0x250 ||
1742              io == 0x240 ||
1743              io == 0x230 ||
1744              io == 0x220 ||
1745              io == 0x210 ||
1746              io == 0x3e0)) {
1747                printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
1748                return -EINVAL;
1749        }
1750#else
1751        if (io == -1 ||
1752                io < 0x100 ||
1753                io > 0x3e0 ||
1754                (io % 0x10) != 0) {
1755                        printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
1756                        return -EINVAL;
1757        }
1758#endif /* MSND_CLASSIC */
1759
1760        if (irq == -1 ||
1761            !(irq == 5 ||
1762              irq == 7 ||
1763              irq == 9 ||
1764              irq == 10 ||
1765              irq == 11 ||
1766              irq == 12)) {
1767                printk(KERN_ERR LOGNAME ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
1768                return -EINVAL;
1769        }
1770
1771        if (mem == -1 ||
1772            !(mem == 0xb0000 ||
1773              mem == 0xc8000 ||
1774              mem == 0xd0000 ||
1775              mem == 0xd8000 ||
1776              mem == 0xe0000 ||
1777              mem == 0xe8000)) {
1778                printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
1779                       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
1780                return -EINVAL;
1781        }
1782
1783#ifdef MSND_CLASSIC
1784        switch (irq) {
1785        case 5: dev.irqid = HPIRQ_5; break;
1786        case 7: dev.irqid = HPIRQ_7; break;
1787        case 9: dev.irqid = HPIRQ_9; break;
1788        case 10: dev.irqid = HPIRQ_10; break;
1789        case 11: dev.irqid = HPIRQ_11; break;
1790        case 12: dev.irqid = HPIRQ_12; break;
1791        }
1792
1793        switch (mem) {
1794        case 0xb0000: dev.memid = HPMEM_B000; break;
1795        case 0xc8000: dev.memid = HPMEM_C800; break;
1796        case 0xd0000: dev.memid = HPMEM_D000; break;
1797        case 0xd8000: dev.memid = HPMEM_D800; break;
1798        case 0xe0000: dev.memid = HPMEM_E000; break;
1799        case 0xe8000: dev.memid = HPMEM_E800; break;
1800        }
1801#else
1802        if (cfg == -1) {
1803                printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
1804        } else if (cfg != 0x250 && cfg != 0x260 && cfg != 0x270) {
1805                printk(KERN_INFO LOGNAME ": Config port must be 0x250, 0x260 or 0x270 (or unspecified for PnP mode)\n");
1806                return -EINVAL;
1807        } else {
1808                printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%x\n", cfg);
1809
1810                /* DSP */
1811                pinnacle_devs[0].io0 = io;
1812                pinnacle_devs[0].irq = irq;
1813                pinnacle_devs[0].mem = mem;
1814
1815                /* The following are Pinnacle specific */
1816
1817                /* MPU */
1818                pinnacle_devs[1].io0 = mpu_io;
1819                pinnacle_devs[1].irq = mpu_irq;
1820
1821                /* IDE */
1822                pinnacle_devs[2].io0 = ide_io0;
1823                pinnacle_devs[2].io1 = ide_io1;
1824                pinnacle_devs[2].irq = ide_irq;
1825
1826                /* Joystick */
1827                pinnacle_devs[3].io0 = joystick_io;
1828
1829                if (check_region(cfg, 2)) {
1830                        printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg);
1831                        return -EIO;
1832                }
1833
1834                request_region(cfg, 2, "Pinnacle/Fiji Config");
1835                if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) {
1836                        printk(KERN_ERR LOGNAME ": Device configuration error\n");
1837                        release_region(cfg, 2);
1838                        return -EIO;
1839                }
1840                release_region(cfg, 2);
1841        }
1842#endif /* MSND_CLASSIC */
1843
1844        if (fifosize < 16)
1845                fifosize = 16;
1846
1847        if (fifosize > 1024)
1848                fifosize = 1024;
1849
1850        set_default_audio_parameters();
1851#ifdef MSND_CLASSIC
1852        dev.type = msndClassic;
1853#else
1854        dev.type = msndPinnacle;
1855#endif
1856        dev.io = io;
1857        dev.numio = DSP_NUMIO;
1858        dev.irq = irq;
1859        dev.base = mem;
1860        dev.fifosize = fifosize * 1024;
1861        dev.calibrate_signal = calibrate_signal ? 1 : 0;
1862        dev.recsrc = 0;
1863        dev.dspq_data_buff = DSPQ_DATA_BUFF;
1864        dev.dspq_buff_size = DSPQ_BUFF_SIZE;
1865        if (write_ndelay == -1)
1866                write_ndelay = CONFIG_MSND_WRITE_NDELAY;
1867        if (write_ndelay)
1868                clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
1869        else
1870                set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
1871#ifndef MSND_CLASSIC
1872        if (digital)
1873                set_bit(F_HAVEDIGITAL, &dev.flags);
1874#endif
1875        init_waitqueue_head(&dev.writeblock);
1876        init_waitqueue_head(&dev.readblock);
1877        init_waitqueue_head(&dev.writeflush);
1878        msnd_fifo_init(&dev.DAPF);
1879        msnd_fifo_init(&dev.DARF);
1880        spin_lock_init(&dev.lock);
1881        printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize);
1882        if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) {
1883                printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n");
1884                return err;
1885        }
1886
1887        if ((err = msnd_fifo_alloc(&dev.DARF, dev.fifosize)) < 0) {
1888                printk(KERN_ERR LOGNAME ": Couldn't allocate read FIFO\n");
1889                msnd_fifo_free(&dev.DAPF);
1890                return err;
1891        }
1892
1893        if ((err = probe_multisound()) < 0) {
1894                printk(KERN_ERR LOGNAME ": Probe failed\n");
1895                msnd_fifo_free(&dev.DAPF);
1896                msnd_fifo_free(&dev.DARF);
1897                return err;
1898        }
1899
1900        if ((err = attach_multisound()) < 0) {
1901                printk(KERN_ERR LOGNAME ": Attach failed\n");
1902                msnd_fifo_free(&dev.DAPF);
1903                msnd_fifo_free(&dev.DARF);
1904                return err;
1905        }
1906
1907        return 0;
1908}
1909
1910static void __exit msdn_cleanup(void)
1911{
1912        unload_multisound();
1913        msnd_fifo_free(&dev.DAPF);
1914        msnd_fifo_free(&dev.DARF);
1915}
1916
1917module_init(msnd_init);
1918module_exit(msdn_cleanup);
1919