linux/sound/isa/sb/sb16_main.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   3 *  Routines for control of 16-bit SoundBlaster cards and clones
   4 *  Note: This is very ugly hardware which uses one 8-bit DMA channel and
   5 *        second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't
   6 *        transfer 16-bit samples and 16-bit DMA channels can't transfer
   7 *        8-bit samples. This make full duplex more complicated than
   8 *        can be... People, don't buy these soundcards for full 16-bit
   9 *        duplex!!!
  10 *  Note: 16-bit wide is assigned to first direction which made request.
  11 *        With full duplex - playback is preferred with abstract layer.
  12 *
  13 *  Note: Some chip revisions have hardware bug. Changing capture
  14 *        channel from full-duplex 8bit DMA to 16bit DMA will block
  15 *        16bit DMA transfers from DSP chip (capture) until 8bit transfer
  16 *        to DSP chip (playback) starts. This bug can be avoided with
  17 *        "16bit DMA Allocation" setting set to Playback or Capture.
  18 *
  19 *
  20 *   This program is free software; you can redistribute it and/or modify
  21 *   it under the terms of the GNU General Public License as published by
  22 *   the Free Software Foundation; either version 2 of the License, or
  23 *   (at your option) any later version.
  24 *
  25 *   This program is distributed in the hope that it will be useful,
  26 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28 *   GNU General Public License for more details.
  29 *
  30 *   You should have received a copy of the GNU General Public License
  31 *   along with this program; if not, write to the Free Software
  32 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  33 *
  34 */
  35
  36#include <linux/io.h>
  37#include <asm/dma.h>
  38#include <linux/init.h>
  39#include <linux/time.h>
  40#include <linux/module.h>
  41#include <sound/core.h>
  42#include <sound/sb.h>
  43#include <sound/sb16_csp.h>
  44#include <sound/mpu401.h>
  45#include <sound/control.h>
  46#include <sound/info.h>
  47
  48MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  49MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones");
  50MODULE_LICENSE("GPL");
  51
  52#ifdef CONFIG_SND_SB16_CSP
  53static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
  54{
  55        if (chip->hardware == SB_HW_16CSP) {
  56                struct snd_sb_csp *csp = chip->csp;
  57
  58                if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
  59                        /* manually loaded codec */
  60                        if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) &&
  61                            ((1U << runtime->format) == csp->acc_format)) {
  62                                /* Supported runtime PCM format for playback */
  63                                if (csp->ops.csp_use(csp) == 0) {
  64                                        /* If CSP was successfully acquired */
  65                                        goto __start_CSP;
  66                                }
  67                        } else if ((csp->mode & SNDRV_SB_CSP_MODE_QSOUND) && (csp->q_enabled)) {
  68                                /* QSound decoder is loaded and enabled */
  69                                if ((1 << runtime->format) & (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
  70                                                              SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE)) {
  71                                        /* Only for simple PCM formats */
  72                                        if (csp->ops.csp_use(csp) == 0) {
  73                                                /* If CSP was successfully acquired */
  74                                                goto __start_CSP;
  75                                        }
  76                                }
  77                        }
  78                } else if (csp->ops.csp_use(csp) == 0) {
  79                        /* Acquire CSP and try to autoload hardware codec */
  80                        if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_WRITE)) {
  81                                /* Unsupported format, release CSP */
  82                                csp->ops.csp_unuse(csp);
  83                        } else {
  84                      __start_CSP:
  85                                /* Try to start CSP */
  86                                if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_PLAYBACK_16) ?
  87                                                       SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT,
  88                                                       (runtime->channels > 1) ?
  89                                                       SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) {
  90                                        /* Failed, release CSP */
  91                                        csp->ops.csp_unuse(csp);
  92                                } else {
  93                                        /* Success, CSP acquired and running */
  94                                        chip->open = SNDRV_SB_CSP_MODE_DSP_WRITE;
  95                                }
  96                        }
  97                }
  98        }
  99}
 100
 101static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 102{
 103        if (chip->hardware == SB_HW_16CSP) {
 104                struct snd_sb_csp *csp = chip->csp;
 105
 106                if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 107                        /* manually loaded codec */
 108                        if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) &&
 109                            ((1U << runtime->format) == csp->acc_format)) {
 110                                /* Supported runtime PCM format for capture */
 111                                if (csp->ops.csp_use(csp) == 0) {
 112                                        /* If CSP was successfully acquired */
 113                                        goto __start_CSP;
 114                                }
 115                        }
 116                } else if (csp->ops.csp_use(csp) == 0) {
 117                        /* Acquire CSP and try to autoload hardware codec */
 118                        if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_READ)) {
 119                                /* Unsupported format, release CSP */
 120                                csp->ops.csp_unuse(csp);
 121                        } else {
 122                      __start_CSP:
 123                                /* Try to start CSP */
 124                                if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_CAPTURE_16) ?
 125                                                       SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT,
 126                                                       (runtime->channels > 1) ?
 127                                                       SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) {
 128                                        /* Failed, release CSP */
 129                                        csp->ops.csp_unuse(csp);
 130                                } else {
 131                                        /* Success, CSP acquired and running */
 132                                        chip->open = SNDRV_SB_CSP_MODE_DSP_READ;
 133                                }
 134                        }
 135                }
 136        }
 137}
 138
 139static void snd_sb16_csp_update(struct snd_sb *chip)
 140{
 141        if (chip->hardware == SB_HW_16CSP) {
 142                struct snd_sb_csp *csp = chip->csp;
 143
 144                if (csp->qpos_changed) {
 145                        spin_lock(&chip->reg_lock);
 146                        csp->ops.csp_qsound_transfer (csp);
 147                        spin_unlock(&chip->reg_lock);
 148                }
 149        }
 150}
 151
 152static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 153{
 154        /* CSP decoders (QSound excluded) support only 16bit transfers */
 155        if (chip->hardware == SB_HW_16CSP) {
 156                struct snd_sb_csp *csp = chip->csp;
 157
 158                if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 159                        /* manually loaded codec */
 160                        if (csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) {
 161                                runtime->hw.formats |= csp->acc_format;
 162                        }
 163                } else {
 164                        /* autoloaded codecs */
 165                        runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
 166                                               SNDRV_PCM_FMTBIT_IMA_ADPCM;
 167                }
 168        }
 169}
 170
 171static void snd_sb16_csp_playback_close(struct snd_sb *chip)
 172{
 173        if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) {
 174                struct snd_sb_csp *csp = chip->csp;
 175
 176                if (csp->ops.csp_stop(csp) == 0) {
 177                        csp->ops.csp_unuse(csp);
 178                        chip->open = 0;
 179                }
 180        }
 181}
 182
 183static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 184{
 185        /* CSP coders support only 16bit transfers */
 186        if (chip->hardware == SB_HW_16CSP) {
 187                struct snd_sb_csp *csp = chip->csp;
 188
 189                if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 190                        /* manually loaded codec */
 191                        if (csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) {
 192                                runtime->hw.formats |= csp->acc_format;
 193                        }
 194                } else {
 195                        /* autoloaded codecs */
 196                        runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
 197                                               SNDRV_PCM_FMTBIT_IMA_ADPCM;
 198                }
 199        }
 200}
 201
 202static void snd_sb16_csp_capture_close(struct snd_sb *chip)
 203{
 204        if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) {
 205                struct snd_sb_csp *csp = chip->csp;
 206
 207                if (csp->ops.csp_stop(csp) == 0) {
 208                        csp->ops.csp_unuse(csp);
 209                        chip->open = 0;
 210                }
 211        }
 212}
 213#else
 214#define snd_sb16_csp_playback_prepare(chip, runtime)    /*nop*/
 215#define snd_sb16_csp_capture_prepare(chip, runtime)     /*nop*/
 216#define snd_sb16_csp_update(chip)                       /*nop*/
 217#define snd_sb16_csp_playback_open(chip, runtime)       /*nop*/
 218#define snd_sb16_csp_playback_close(chip)               /*nop*/
 219#define snd_sb16_csp_capture_open(chip, runtime)        /*nop*/
 220#define snd_sb16_csp_capture_close(chip)                /*nop*/
 221#endif
 222
 223
 224static void snd_sb16_setup_rate(struct snd_sb *chip,
 225                                unsigned short rate,
 226                                int channel)
 227{
 228        unsigned long flags;
 229
 230        spin_lock_irqsave(&chip->reg_lock, flags);
 231        if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16))
 232                snd_sb_ack_16bit(chip);
 233        else
 234                snd_sb_ack_8bit(chip);
 235        if (!(chip->mode & SB_RATE_LOCK)) {
 236                chip->locked_rate = rate;
 237                snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_IN);
 238                snd_sbdsp_command(chip, rate >> 8);
 239                snd_sbdsp_command(chip, rate & 0xff);
 240                snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
 241                snd_sbdsp_command(chip, rate >> 8);
 242                snd_sbdsp_command(chip, rate & 0xff);
 243        }
 244        spin_unlock_irqrestore(&chip->reg_lock, flags);
 245}
 246
 247static int snd_sb16_hw_params(struct snd_pcm_substream *substream,
 248                              struct snd_pcm_hw_params *hw_params)
 249{
 250        return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 251}
 252
 253static int snd_sb16_hw_free(struct snd_pcm_substream *substream)
 254{
 255        snd_pcm_lib_free_pages(substream);
 256        return 0;
 257}
 258
 259static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
 260{
 261        unsigned long flags;
 262        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 263        struct snd_pcm_runtime *runtime = substream->runtime;
 264        unsigned char format;
 265        unsigned int size, count, dma;
 266
 267        snd_sb16_csp_playback_prepare(chip, runtime);
 268        if (snd_pcm_format_unsigned(runtime->format) > 0) {
 269                format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO;
 270        } else {
 271                format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO;
 272        }
 273
 274        snd_sb16_setup_rate(chip, runtime->rate, SNDRV_PCM_STREAM_PLAYBACK);
 275        size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
 276        dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
 277        snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
 278
 279        count = snd_pcm_lib_period_bytes(substream);
 280        spin_lock_irqsave(&chip->reg_lock, flags);
 281        if (chip->mode & SB_MODE_PLAYBACK_16) {
 282                count >>= 1;
 283                count--;
 284                snd_sbdsp_command(chip, SB_DSP4_OUT16_AI);
 285                snd_sbdsp_command(chip, format);
 286                snd_sbdsp_command(chip, count & 0xff);
 287                snd_sbdsp_command(chip, count >> 8);
 288                snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
 289        } else {
 290                count--;
 291                snd_sbdsp_command(chip, SB_DSP4_OUT8_AI);
 292                snd_sbdsp_command(chip, format);
 293                snd_sbdsp_command(chip, count & 0xff);
 294                snd_sbdsp_command(chip, count >> 8);
 295                snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
 296        }
 297        spin_unlock_irqrestore(&chip->reg_lock, flags);
 298        return 0;
 299}
 300
 301static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
 302                                     int cmd)
 303{
 304        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 305        int result = 0;
 306
 307        spin_lock(&chip->reg_lock);
 308        switch (cmd) {
 309        case SNDRV_PCM_TRIGGER_START:
 310        case SNDRV_PCM_TRIGGER_RESUME:
 311                chip->mode |= SB_RATE_LOCK_PLAYBACK;
 312                snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
 313                break;
 314        case SNDRV_PCM_TRIGGER_STOP:
 315        case SNDRV_PCM_TRIGGER_SUSPEND:
 316                snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
 317                /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
 318                if (chip->mode & SB_RATE_LOCK_CAPTURE)
 319                        snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
 320                chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
 321                break;
 322        default:
 323                result = -EINVAL;
 324        }
 325        spin_unlock(&chip->reg_lock);
 326        return result;
 327}
 328
 329static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
 330{
 331        unsigned long flags;
 332        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 333        struct snd_pcm_runtime *runtime = substream->runtime;
 334        unsigned char format;
 335        unsigned int size, count, dma;
 336
 337        snd_sb16_csp_capture_prepare(chip, runtime);
 338        if (snd_pcm_format_unsigned(runtime->format) > 0) {
 339                format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO;
 340        } else {
 341                format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO;
 342        }
 343        snd_sb16_setup_rate(chip, runtime->rate, SNDRV_PCM_STREAM_CAPTURE);
 344        size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
 345        dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
 346        snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
 347
 348        count = snd_pcm_lib_period_bytes(substream);
 349        spin_lock_irqsave(&chip->reg_lock, flags);
 350        if (chip->mode & SB_MODE_CAPTURE_16) {
 351                count >>= 1;
 352                count--;
 353                snd_sbdsp_command(chip, SB_DSP4_IN16_AI);
 354                snd_sbdsp_command(chip, format);
 355                snd_sbdsp_command(chip, count & 0xff);
 356                snd_sbdsp_command(chip, count >> 8);
 357                snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
 358        } else {
 359                count--;
 360                snd_sbdsp_command(chip, SB_DSP4_IN8_AI);
 361                snd_sbdsp_command(chip, format);
 362                snd_sbdsp_command(chip, count & 0xff);
 363                snd_sbdsp_command(chip, count >> 8);
 364                snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
 365        }
 366        spin_unlock_irqrestore(&chip->reg_lock, flags);
 367        return 0;
 368}
 369
 370static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
 371                                    int cmd)
 372{
 373        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 374        int result = 0;
 375
 376        spin_lock(&chip->reg_lock);
 377        switch (cmd) {
 378        case SNDRV_PCM_TRIGGER_START:
 379        case SNDRV_PCM_TRIGGER_RESUME:
 380                chip->mode |= SB_RATE_LOCK_CAPTURE;
 381                snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
 382                break;
 383        case SNDRV_PCM_TRIGGER_STOP:
 384        case SNDRV_PCM_TRIGGER_SUSPEND:
 385                snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
 386                /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
 387                if (chip->mode & SB_RATE_LOCK_PLAYBACK)
 388                        snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
 389                chip->mode &= ~SB_RATE_LOCK_CAPTURE;
 390                break;
 391        default:
 392                result = -EINVAL;
 393        }
 394        spin_unlock(&chip->reg_lock);
 395        return result;
 396}
 397
 398irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
 399{
 400        struct snd_sb *chip = dev_id;
 401        unsigned char status;
 402        int ok;
 403
 404        spin_lock(&chip->mixer_lock);
 405        status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
 406        spin_unlock(&chip->mixer_lock);
 407        if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
 408                chip->rmidi_callback(irq, chip->rmidi->private_data);
 409        if (status & SB_IRQTYPE_8BIT) {
 410                ok = 0;
 411                if (chip->mode & SB_MODE_PLAYBACK_8) {
 412                        snd_pcm_period_elapsed(chip->playback_substream);
 413                        snd_sb16_csp_update(chip);
 414                        ok++;
 415                }
 416                if (chip->mode & SB_MODE_CAPTURE_8) {
 417                        snd_pcm_period_elapsed(chip->capture_substream);
 418                        ok++;
 419                }
 420                spin_lock(&chip->reg_lock);
 421                if (!ok)
 422                        snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
 423                snd_sb_ack_8bit(chip);
 424                spin_unlock(&chip->reg_lock);
 425        }
 426        if (status & SB_IRQTYPE_16BIT) {
 427                ok = 0;
 428                if (chip->mode & SB_MODE_PLAYBACK_16) {
 429                        snd_pcm_period_elapsed(chip->playback_substream);
 430                        snd_sb16_csp_update(chip);
 431                        ok++;
 432                }
 433                if (chip->mode & SB_MODE_CAPTURE_16) {
 434                        snd_pcm_period_elapsed(chip->capture_substream);
 435                        ok++;
 436                }
 437                spin_lock(&chip->reg_lock);
 438                if (!ok)
 439                        snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
 440                snd_sb_ack_16bit(chip);
 441                spin_unlock(&chip->reg_lock);
 442        }
 443        return IRQ_HANDLED;
 444}
 445
 446/*
 447
 448 */
 449
 450static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream)
 451{
 452        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 453        unsigned int dma;
 454        size_t ptr;
 455
 456        dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
 457        ptr = snd_dma_pointer(dma, chip->p_dma_size);
 458        return bytes_to_frames(substream->runtime, ptr);
 459}
 460
 461static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream)
 462{
 463        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 464        unsigned int dma;
 465        size_t ptr;
 466
 467        dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
 468        ptr = snd_dma_pointer(dma, chip->c_dma_size);
 469        return bytes_to_frames(substream->runtime, ptr);
 470}
 471
 472/*
 473
 474 */
 475
 476static const struct snd_pcm_hardware snd_sb16_playback =
 477{
 478        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 479                                 SNDRV_PCM_INFO_MMAP_VALID),
 480        .formats =              0,
 481        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
 482        .rate_min =             4000,
 483        .rate_max =             44100,
 484        .channels_min =         1,
 485        .channels_max =         2,
 486        .buffer_bytes_max =     (128*1024),
 487        .period_bytes_min =     64,
 488        .period_bytes_max =     (128*1024),
 489        .periods_min =          1,
 490        .periods_max =          1024,
 491        .fifo_size =            0,
 492};
 493
 494static const struct snd_pcm_hardware snd_sb16_capture =
 495{
 496        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 497                                 SNDRV_PCM_INFO_MMAP_VALID),
 498        .formats =              0,
 499        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
 500        .rate_min =             4000,
 501        .rate_max =             44100,
 502        .channels_min =         1,
 503        .channels_max =         2,
 504        .buffer_bytes_max =     (128*1024),
 505        .period_bytes_min =     64,
 506        .period_bytes_max =     (128*1024),
 507        .periods_min =          1,
 508        .periods_max =          1024,
 509        .fifo_size =            0,
 510};
 511
 512/*
 513 *  open/close
 514 */
 515
 516static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
 517{
 518        unsigned long flags;
 519        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 520        struct snd_pcm_runtime *runtime = substream->runtime;
 521
 522        spin_lock_irqsave(&chip->open_lock, flags);
 523        if (chip->mode & SB_MODE_PLAYBACK) {
 524                spin_unlock_irqrestore(&chip->open_lock, flags);
 525                return -EAGAIN;
 526        }
 527        runtime->hw = snd_sb16_playback;
 528
 529        /* skip if 16 bit DMA was reserved for capture */
 530        if (chip->force_mode16 & SB_MODE_CAPTURE_16)
 531                goto __skip_16bit;
 532
 533        if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_CAPTURE_16)) {
 534                chip->mode |= SB_MODE_PLAYBACK_16;
 535                runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
 536                /* Vibra16X hack */
 537                if (chip->dma16 <= 3) {
 538                        runtime->hw.buffer_bytes_max =
 539                        runtime->hw.period_bytes_max = 64 * 1024;
 540                } else {
 541                        snd_sb16_csp_playback_open(chip, runtime);
 542                }
 543                goto __open_ok;
 544        }
 545
 546      __skip_16bit:
 547        if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_CAPTURE_8)) {
 548                chip->mode |= SB_MODE_PLAYBACK_8;
 549                /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */
 550                if (chip->dma16 < 0) {
 551                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
 552                        chip->mode |= SB_MODE_PLAYBACK_16;
 553                } else {
 554                        runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8;
 555                }
 556                runtime->hw.buffer_bytes_max =
 557                runtime->hw.period_bytes_max = 64 * 1024;
 558                goto __open_ok;
 559        }
 560        spin_unlock_irqrestore(&chip->open_lock, flags);
 561        return -EAGAIN;
 562
 563      __open_ok:
 564        if (chip->hardware == SB_HW_ALS100)
 565                runtime->hw.rate_max = 48000;
 566        if (chip->hardware == SB_HW_CS5530) {
 567                runtime->hw.buffer_bytes_max = 32 * 1024;
 568                runtime->hw.periods_min = 2;
 569                runtime->hw.rate_min = 44100;
 570        }
 571        if (chip->mode & SB_RATE_LOCK)
 572                runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
 573        chip->playback_substream = substream;
 574        spin_unlock_irqrestore(&chip->open_lock, flags);
 575        return 0;
 576}
 577
 578static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
 579{
 580        unsigned long flags;
 581        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 582
 583        snd_sb16_csp_playback_close(chip);
 584        spin_lock_irqsave(&chip->open_lock, flags);
 585        chip->playback_substream = NULL;
 586        chip->mode &= ~SB_MODE_PLAYBACK;
 587        spin_unlock_irqrestore(&chip->open_lock, flags);
 588        return 0;
 589}
 590
 591static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
 592{
 593        unsigned long flags;
 594        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 595        struct snd_pcm_runtime *runtime = substream->runtime;
 596
 597        spin_lock_irqsave(&chip->open_lock, flags);
 598        if (chip->mode & SB_MODE_CAPTURE) {
 599                spin_unlock_irqrestore(&chip->open_lock, flags);
 600                return -EAGAIN;
 601        }
 602        runtime->hw = snd_sb16_capture;
 603
 604        /* skip if 16 bit DMA was reserved for playback */
 605        if (chip->force_mode16 & SB_MODE_PLAYBACK_16)
 606                goto __skip_16bit;
 607
 608        if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_16)) {
 609                chip->mode |= SB_MODE_CAPTURE_16;
 610                runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
 611                /* Vibra16X hack */
 612                if (chip->dma16 <= 3) {
 613                        runtime->hw.buffer_bytes_max =
 614                        runtime->hw.period_bytes_max = 64 * 1024;
 615                } else {
 616                        snd_sb16_csp_capture_open(chip, runtime);
 617                }
 618                goto __open_ok;
 619        }
 620
 621      __skip_16bit:
 622        if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_8)) {
 623                chip->mode |= SB_MODE_CAPTURE_8;
 624                /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */
 625                if (chip->dma16 < 0) {
 626                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
 627                        chip->mode |= SB_MODE_CAPTURE_16;
 628                } else {
 629                        runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8;
 630                }
 631                runtime->hw.buffer_bytes_max =
 632                runtime->hw.period_bytes_max = 64 * 1024;
 633                goto __open_ok;
 634        }
 635        spin_unlock_irqrestore(&chip->open_lock, flags);
 636        return -EAGAIN;
 637
 638      __open_ok:
 639        if (chip->hardware == SB_HW_ALS100)
 640                runtime->hw.rate_max = 48000;
 641        if (chip->hardware == SB_HW_CS5530) {
 642                runtime->hw.buffer_bytes_max = 32 * 1024;
 643                runtime->hw.periods_min = 2;
 644                runtime->hw.rate_min = 44100;
 645        }
 646        if (chip->mode & SB_RATE_LOCK)
 647                runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
 648        chip->capture_substream = substream;
 649        spin_unlock_irqrestore(&chip->open_lock, flags);
 650        return 0;
 651}
 652
 653static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
 654{
 655        unsigned long flags;
 656        struct snd_sb *chip = snd_pcm_substream_chip(substream);
 657
 658        snd_sb16_csp_capture_close(chip);
 659        spin_lock_irqsave(&chip->open_lock, flags);
 660        chip->capture_substream = NULL;
 661        chip->mode &= ~SB_MODE_CAPTURE;
 662        spin_unlock_irqrestore(&chip->open_lock, flags);
 663        return 0;
 664}
 665
 666/*
 667 *  DMA control interface
 668 */
 669
 670static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what)
 671{
 672        if (chip->dma8 < 0 || chip->dma16 < 0) {
 673                if (snd_BUG_ON(what))
 674                        return -EINVAL;
 675                return 0;
 676        }
 677        if (what == 0) {
 678                chip->force_mode16 = 0;
 679        } else if (what == 1) {
 680                chip->force_mode16 = SB_MODE_PLAYBACK_16;
 681        } else if (what == 2) {
 682                chip->force_mode16 = SB_MODE_CAPTURE_16;
 683        } else {
 684                return -EINVAL;
 685        }
 686        return 0;
 687}
 688
 689static int snd_sb16_get_dma_mode(struct snd_sb *chip)
 690{
 691        if (chip->dma8 < 0 || chip->dma16 < 0)
 692                return 0;
 693        switch (chip->force_mode16) {
 694        case SB_MODE_PLAYBACK_16:
 695                return 1;
 696        case SB_MODE_CAPTURE_16:
 697                return 2;
 698        default:
 699                return 0;
 700        }
 701}
 702
 703static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 704{
 705        static const char * const texts[3] = {
 706                "Auto", "Playback", "Capture"
 707        };
 708
 709        return snd_ctl_enum_info(uinfo, 1, 3, texts);
 710}
 711
 712static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 713{
 714        struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
 715        unsigned long flags;
 716        
 717        spin_lock_irqsave(&chip->reg_lock, flags);
 718        ucontrol->value.enumerated.item[0] = snd_sb16_get_dma_mode(chip);
 719        spin_unlock_irqrestore(&chip->reg_lock, flags);
 720        return 0;
 721}
 722
 723static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 724{
 725        struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
 726        unsigned long flags;
 727        unsigned char nval, oval;
 728        int change;
 729        
 730        if ((nval = ucontrol->value.enumerated.item[0]) > 2)
 731                return -EINVAL;
 732        spin_lock_irqsave(&chip->reg_lock, flags);
 733        oval = snd_sb16_get_dma_mode(chip);
 734        change = nval != oval;
 735        snd_sb16_set_dma_mode(chip, nval);
 736        spin_unlock_irqrestore(&chip->reg_lock, flags);
 737        return change;
 738}
 739
 740static const struct snd_kcontrol_new snd_sb16_dma_control = {
 741        .iface = SNDRV_CTL_ELEM_IFACE_CARD,
 742        .name = "16-bit DMA Allocation",
 743        .info = snd_sb16_dma_control_info,
 744        .get = snd_sb16_dma_control_get,
 745        .put = snd_sb16_dma_control_put
 746};
 747
 748/*
 749 *  Initialization part
 750 */
 751 
 752int snd_sb16dsp_configure(struct snd_sb * chip)
 753{
 754        unsigned long flags;
 755        unsigned char irqreg = 0, dmareg = 0, mpureg;
 756        unsigned char realirq, realdma, realmpureg;
 757        /* note: mpu register should be present only on SB16 Vibra soundcards */
 758
 759        // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
 760        spin_lock_irqsave(&chip->mixer_lock, flags);
 761        mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
 762        spin_unlock_irqrestore(&chip->mixer_lock, flags);
 763        switch (chip->irq) {
 764        case 2:
 765        case 9:
 766                irqreg |= SB_IRQSETUP_IRQ9;
 767                break;
 768        case 5:
 769                irqreg |= SB_IRQSETUP_IRQ5;
 770                break;
 771        case 7:
 772                irqreg |= SB_IRQSETUP_IRQ7;
 773                break;
 774        case 10:
 775                irqreg |= SB_IRQSETUP_IRQ10;
 776                break;
 777        default:
 778                return -EINVAL;
 779        }
 780        if (chip->dma8 >= 0) {
 781                switch (chip->dma8) {
 782                case 0:
 783                        dmareg |= SB_DMASETUP_DMA0;
 784                        break;
 785                case 1:
 786                        dmareg |= SB_DMASETUP_DMA1;
 787                        break;
 788                case 3:
 789                        dmareg |= SB_DMASETUP_DMA3;
 790                        break;
 791                default:
 792                        return -EINVAL;
 793                }
 794        }
 795        if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) {
 796                switch (chip->dma16) {
 797                case 5:
 798                        dmareg |= SB_DMASETUP_DMA5;
 799                        break;
 800                case 6:
 801                        dmareg |= SB_DMASETUP_DMA6;
 802                        break;
 803                case 7:
 804                        dmareg |= SB_DMASETUP_DMA7;
 805                        break;
 806                default:
 807                        return -EINVAL;
 808                }
 809        }
 810        switch (chip->mpu_port) {
 811        case 0x300:
 812                mpureg |= 0x04;
 813                break;
 814        case 0x330:
 815                mpureg |= 0x00;
 816                break;
 817        default:
 818                mpureg |= 0x02; /* disable MPU */
 819        }
 820        spin_lock_irqsave(&chip->mixer_lock, flags);
 821
 822        snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
 823        realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
 824
 825        snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
 826        realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
 827
 828        snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
 829        realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
 830
 831        spin_unlock_irqrestore(&chip->mixer_lock, flags);
 832        if ((~realirq) & irqreg || (~realdma) & dmareg) {
 833                snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
 834                snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
 835                snd_printk(KERN_ERR "SB16 [0x%lx]:    got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
 836                return -ENODEV;
 837        }
 838        return 0;
 839}
 840
 841static const struct snd_pcm_ops snd_sb16_playback_ops = {
 842        .open =         snd_sb16_playback_open,
 843        .close =        snd_sb16_playback_close,
 844        .ioctl =        snd_pcm_lib_ioctl,
 845        .hw_params =    snd_sb16_hw_params,
 846        .hw_free =      snd_sb16_hw_free,
 847        .prepare =      snd_sb16_playback_prepare,
 848        .trigger =      snd_sb16_playback_trigger,
 849        .pointer =      snd_sb16_playback_pointer,
 850};
 851
 852static const struct snd_pcm_ops snd_sb16_capture_ops = {
 853        .open =         snd_sb16_capture_open,
 854        .close =        snd_sb16_capture_close,
 855        .ioctl =        snd_pcm_lib_ioctl,
 856        .hw_params =    snd_sb16_hw_params,
 857        .hw_free =      snd_sb16_hw_free,
 858        .prepare =      snd_sb16_capture_prepare,
 859        .trigger =      snd_sb16_capture_trigger,
 860        .pointer =      snd_sb16_capture_pointer,
 861};
 862
 863int snd_sb16dsp_pcm(struct snd_sb *chip, int device)
 864{
 865        struct snd_card *card = chip->card;
 866        struct snd_pcm *pcm;
 867        int err;
 868
 869        if ((err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm)) < 0)
 870                return err;
 871        sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
 872        pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 873        pcm->private_data = chip;
 874        chip->pcm = pcm;
 875
 876        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops);
 877        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops);
 878
 879        if (chip->dma16 >= 0 && chip->dma8 != chip->dma16)
 880                snd_ctl_add(card, snd_ctl_new1(&snd_sb16_dma_control, chip));
 881        else
 882                pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 883
 884        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 885                                              snd_dma_isa_data(),
 886                                              64*1024, 128*1024);
 887        return 0;
 888}
 889
 890const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction)
 891{
 892        return direction == SNDRV_PCM_STREAM_PLAYBACK ?
 893                &snd_sb16_playback_ops : &snd_sb16_capture_ops;
 894}
 895
 896EXPORT_SYMBOL(snd_sb16dsp_pcm);
 897EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops);
 898EXPORT_SYMBOL(snd_sb16dsp_configure);
 899EXPORT_SYMBOL(snd_sb16dsp_interrupt);
 900
 901/*
 902 *  INIT part
 903 */
 904
 905static int __init alsa_sb16_init(void)
 906{
 907        return 0;
 908}
 909
 910static void __exit alsa_sb16_exit(void)
 911{
 912}
 913
 914module_init(alsa_sb16_init)
 915module_exit(alsa_sb16_exit)
 916