^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Routines for GF1 DMA control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sound/gus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static void snd_gf1_dma_ack(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) snd_gf1_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static void snd_gf1_dma_program(struct snd_gus_card * gus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned long buf_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) unsigned int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned char dma_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int address_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) snd_printdd("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) addr, buf_addr, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (gus->gf1.dma1 > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (gus->gf1.enh_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) address = addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (addr & 0x1f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) snd_printd("snd_gf1_dma_transfer: unaligned address (0x%x)?\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) address = (addr & 0x000c0000) | ((addr & 0x0003ffff) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) address = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) dma_cmd = SNDRV_GF1_DMA_ENABLE | (unsigned short) cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) dma_cmd |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (dma_cmd & SNDRV_GF1_DMA_16BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) count &= ~1; /* align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (gus->gf1.dma1 > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dma_cmd |= SNDRV_GF1_DMA_WIDTH16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) count &= ~1; /* align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) snd_gf1_dma_ack(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) snd_printk(KERN_DEBUG "address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) address << 1, count, dma_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (gus->gf1.enh_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) address_high = ((address >> 16) & 0x000000f0) | (address & 0x0000000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) snd_gf1_write16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW, (unsigned short) (address >> 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH, (unsigned char) address_high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) snd_gf1_write16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW, (unsigned short) (address >> 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL, dma_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct snd_gf1_dma_block *snd_gf1_dma_next_block(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct snd_gf1_dma_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* PCM block have bigger priority than synthesizer one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (gus->gf1.dma_data_pcm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) block = gus->gf1.dma_data_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (gus->gf1.dma_data_pcm_last == block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) gus->gf1.dma_data_pcm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) gus->gf1.dma_data_pcm_last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) gus->gf1.dma_data_pcm = block->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) } else if (gus->gf1.dma_data_synth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) block = gus->gf1.dma_data_synth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (gus->gf1.dma_data_synth_last == block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) gus->gf1.dma_data_synth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) gus->gf1.dma_data_synth_last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) gus->gf1.dma_data_synth = block->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) block = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) gus->gf1.dma_ack = block->ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) gus->gf1.dma_private_data = block->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct snd_gf1_dma_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) snd_gf1_dma_ack(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (gus->gf1.dma_ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) gus->gf1.dma_ack(gus, gus->gf1.dma_private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) spin_lock(&gus->dma_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (gus->gf1.dma_data_pcm == NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) gus->gf1.dma_data_synth == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) gus->gf1.dma_ack = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) gus->gf1.dma_flags &= ~SNDRV_GF1_DMA_TRIGGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) spin_unlock(&gus->dma_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) block = snd_gf1_dma_next_block(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) spin_unlock(&gus->dma_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (!block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) snd_printd(KERN_DEBUG "program dma (IRQ) - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) block->addr, block->buf_addr, block->count, block->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int snd_gf1_dma_init(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mutex_lock(&gus->dma_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) gus->gf1.dma_shared++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (gus->gf1.dma_shared > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mutex_unlock(&gus->dma_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) gus->gf1.dma_data_pcm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) gus->gf1.dma_data_pcm_last =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) gus->gf1.dma_data_synth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) gus->gf1.dma_data_synth_last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mutex_unlock(&gus->dma_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int snd_gf1_dma_done(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct snd_gf1_dma_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mutex_lock(&gus->dma_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) gus->gf1.dma_shared--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!gus->gf1.dma_shared) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) snd_dma_disable(gus->gf1.dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_DMA_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) snd_gf1_dma_ack(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) while ((block = gus->gf1.dma_data_pcm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) gus->gf1.dma_data_pcm = block->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) while ((block = gus->gf1.dma_data_synth)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) gus->gf1.dma_data_synth = block->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) gus->gf1.dma_data_pcm_last =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) gus->gf1.dma_data_synth_last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mutex_unlock(&gus->dma_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct snd_gf1_dma_block * __block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int atomic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int synth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct snd_gf1_dma_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *block = *__block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) block->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) snd_printdd("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) block->addr, (long) block->buffer, block->count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) block->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) snd_printdd("gus->gf1.dma_data_pcm_last = 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) (long)gus->gf1.dma_data_pcm_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) snd_printdd("gus->gf1.dma_data_pcm = 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) (long)gus->gf1.dma_data_pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) spin_lock_irqsave(&gus->dma_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (synth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (gus->gf1.dma_data_synth_last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) gus->gf1.dma_data_synth_last->next = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) gus->gf1.dma_data_synth_last = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) gus->gf1.dma_data_synth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) gus->gf1.dma_data_synth_last = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (gus->gf1.dma_data_pcm_last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) gus->gf1.dma_data_pcm_last->next = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) gus->gf1.dma_data_pcm_last = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) gus->gf1.dma_data_pcm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) gus->gf1.dma_data_pcm_last = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (!(gus->gf1.dma_flags & SNDRV_GF1_DMA_TRIGGER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) gus->gf1.dma_flags |= SNDRV_GF1_DMA_TRIGGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) block = snd_gf1_dma_next_block(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) spin_unlock_irqrestore(&gus->dma_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (block == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) spin_unlock_irqrestore(&gus->dma_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }