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