📄 korg1212.c
字号:
// -------------------------------------------------------------------------------- // Initialize the routing and volume tables, then update the card's state. // -------------------------------------------------------------------------------- udelay(INTERCOMMAND_DELAY); for (channel = 0; channel < kAudioChannels; channel++) { korg1212->sharedBufferPtr->volumeData[channel] = k1212MaxVolume; //korg1212->sharedBufferPtr->routeData[channel] = channel; korg1212->sharedBufferPtr->routeData[channel] = 8 + (channel & 1); } snd_korg1212_WriteADCSensitivity(korg1212); udelay(INTERCOMMAND_DELAY); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate, ClockSourceSelector[korg1212->clkSrcRate], 0, 0, 0); if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n", rc, stateName[korg1212->cardState]); rc = snd_korg1212_TurnOnIdleMonitor(korg1212); snd_korg1212_setCardState(korg1212, K1212_STATE_READY); if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Monitor On - RC = %d [%s]\n", rc, stateName[korg1212->cardState]); snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE);}static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs){ u32 doorbellValue; struct snd_korg1212 *korg1212 = dev_id; if(irq != korg1212->irq) return IRQ_NONE; doorbellValue = readl(korg1212->inDoorbellPtr); if (!doorbellValue) return IRQ_NONE; spin_lock(&korg1212->lock); writel(doorbellValue, korg1212->inDoorbellPtr); korg1212->irqcount++; korg1212->inIRQ++; switch (doorbellValue) { case K1212_DB_DSPDownloadDone: K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]); if (korg1212->cardState == K1212_STATE_DSP_IN_PROCESS) { korg1212->dsp_is_loaded = 1; wake_up(&korg1212->wait); } break; // ------------------------------------------------------------------------ // an error occurred - stop the card // ------------------------------------------------------------------------ case K1212_DB_DMAERROR: K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]); snd_printk(KERN_ERR "korg1212: DMA Error\n"); korg1212->errorcnt++; korg1212->totalerrorcnt++; korg1212->sharedBufferPtr->cardCommand = 0; snd_korg1212_setCardState(korg1212, K1212_STATE_ERRORSTOP); break; // ------------------------------------------------------------------------ // the card has stopped by our request. Clear the command word and signal // the semaphore in case someone is waiting for this. // ------------------------------------------------------------------------ case K1212_DB_CARDSTOPPED: K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]); korg1212->sharedBufferPtr->cardCommand = 0; break; default: K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n", korg1212->irqcount, doorbellValue, korg1212->currentBuffer, stateName[korg1212->cardState]); if ((korg1212->cardState > K1212_STATE_SETUP) || korg1212->idleMonitorOn) { korg1212->currentBuffer++; if (korg1212->currentBuffer >= kNumBuffers) korg1212->currentBuffer = 0; if (!korg1212->running) break; if (korg1212->capture_substream) { spin_unlock(&korg1212->lock); snd_pcm_period_elapsed(korg1212->capture_substream); spin_lock(&korg1212->lock); } if (korg1212->playback_substream) { spin_unlock(&korg1212->lock); snd_pcm_period_elapsed(korg1212->playback_substream); spin_lock(&korg1212->lock); } } break; } korg1212->inIRQ--; spin_unlock(&korg1212->lock); return IRQ_HANDLED;}static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212){ int rc; K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is starting... [%s]\n", stateName[korg1212->cardState]); // --------------------------------------------------------------- // verify the state of the card before proceeding. // --------------------------------------------------------------- if (korg1212->cardState >= K1212_STATE_DSP_IN_PROCESS) return 1; snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS); memcpy(korg1212->dma_dsp.area, dspCode, korg1212->dspCodeSize); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload, UpperWordSwap(korg1212->dma_dsp.addr), 0, 0, 0); if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n", rc, stateName[korg1212->cardState]); korg1212->dsp_is_loaded = 0; wait_event_timeout(korg1212->wait, korg1212->dsp_is_loaded, HZ * CARD_BOOT_TIMEOUT); if (! korg1212->dsp_is_loaded ) return -EBUSY; /* timeout */ snd_korg1212_OnDSPDownloadComplete(korg1212); return 0;}static struct snd_pcm_hardware snd_korg1212_playback_info ={ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000), .rate_min = 44100, .rate_max = 48000, .channels_min = K1212_MIN_CHANNELS, .channels_max = K1212_MAX_CHANNELS, .buffer_bytes_max = K1212_MAX_BUF_SIZE, .period_bytes_min = K1212_MIN_CHANNELS * 2 * kPlayBufferFrames, .period_bytes_max = K1212_MAX_CHANNELS * 2 * kPlayBufferFrames, .periods_min = K1212_PERIODS, .periods_max = K1212_PERIODS, .fifo_size = 0,};static struct snd_pcm_hardware snd_korg1212_capture_info ={ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000), .rate_min = 44100, .rate_max = 48000, .channels_min = K1212_MIN_CHANNELS, .channels_max = K1212_MAX_CHANNELS, .buffer_bytes_max = K1212_MAX_BUF_SIZE, .period_bytes_min = K1212_MIN_CHANNELS * 2 * kPlayBufferFrames, .period_bytes_max = K1212_MAX_CHANNELS * 2 * kPlayBufferFrames, .periods_min = K1212_PERIODS, .periods_max = K1212_PERIODS, .fifo_size = 0,};static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int count, int offset, int size){ struct KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos; int i; K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count); snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); for (i=0; i < count; i++) {#if K1212_DEBUG_LEVEL > 0 if ( (void *) dst < (void *) korg1212->playDataBufsPtr || (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) { printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n", dst, i); return -EFAULT; }#endif memset((void*) dst + offset, 0, size); dst++; } return 0;}static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, int pos, int count, int offset, int size){ struct KorgAudioFrame * src = korg1212->recordDataBufsPtr[0].bufferData + pos; int i, rc; K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", pos, offset, size); snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); for (i=0; i < count; i++) {#if K1212_DEBUG_LEVEL > 0 if ( (void *) src < (void *) korg1212->recordDataBufsPtr || (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) { printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i); return -EFAULT; }#endif rc = copy_to_user(dst + offset, src, size); if (rc) { K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i); return -EFAULT; } src++; dst += size; } return 0;}static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *src, int pos, int count, int offset, int size){ struct KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos; int i, rc; K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count); snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); for (i=0; i < count; i++) {#if K1212_DEBUG_LEVEL > 0 if ( (void *) dst < (void *) korg1212->playDataBufsPtr || (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) { printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i); return -EFAULT; }#endif rc = copy_from_user((void*) dst + offset, src, size); if (rc) { K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i); return -EFAULT; } dst++; src += size; } return 0;}static void snd_korg1212_free_pcm(struct snd_pcm *pcm){ struct snd_korg1212 *korg1212 = pcm->private_data; K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n", stateName[korg1212->cardState]); korg1212->pcm = NULL;}static int snd_korg1212_playback_open(struct snd_pcm_substream *substream){ unsigned long flags; struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n", stateName[korg1212->cardState]); snd_pcm_set_sync(substream); // ??? snd_korg1212_OpenCard(korg1212); runtime->hw = snd_korg1212_playback_info; snd_pcm_set_runtime_buffer(substream, &korg1212->dma_play); spin_lock_irqsave(&korg1212->lock, flags); korg1212->playback_substream = substream; korg1212->playback_pid = current->pid; korg1212->periodsize = K1212_PERIODS; korg1212->channels = K1212_CHANNELS; korg1212->errorcnt = 0; spin_unlock_irqrestore(&korg1212->lock, flags); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames); return 0;}static int snd_korg1212_capture_open(struct snd_pcm_substream *substream){ unsigned long flags; struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n", stateName[korg1212->cardState]); snd_pcm_set_sync(substream); snd_korg1212_OpenCard(korg1212); runtime->hw = snd_korg1212_capture_info; snd_pcm_set_runtime_buffer(substream, &korg1212->dma_rec); spin_lock_irqsave(&korg1212->lock, flags); korg1212->capture_substream = substream; korg1212->capture_pid = current->pid; korg1212->periodsize = K1212_PERIODS; korg1212->channels = K1212_CHANNELS; spin_unlock_irqrestore(&korg1212->lock, flags); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames); return 0;}static int snd_korg1212_playback_close(struct snd_pcm_substream *substream){ unsigned long flags; struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n", stateName[korg1212->cardState]); snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -