int mv88fx_snd_hw_playback_set(struct mv88fx_snd_chip *chip) { struct mv88fx_snd_stream *audio_stream = chip->stream[PLAYBACK]; struct snd_pcm_substream *substream = audio_stream->substream; struct snd_pcm_runtime *runtime = substream->runtime; MV_AUDIO_PLAYBACK_CTRL pcm_play_ctrl; MV_I2S_PLAYBACK_CTRL i2s_play_ctrl; MV_SPDIF_PLAYBACK_CTRL spdif_play_ctrl; MV_AUDIO_FREQ_DATA dco_ctrl; dco_ctrl.offset = chip->dco_ctrl_offst; switch(audio_stream->rate) { case 44100: dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH; break; case 48000: dco_ctrl.baseFreq = AUDIO_FREQ_48KH; break; case 96000: dco_ctrl.baseFreq = AUDIO_FREQ_96KH; break; default: snd_printk("Requested rate %d is not supported\n", runtime->rate); return -1; } pcm_play_ctrl.burst = (chip->burst == 128)?AUDIO_128BYTE_BURST: AUDIO_32BYTE_BURST; pcm_play_ctrl.loopBack = chip->loopback; if (audio_stream->stereo) { pcm_play_ctrl.monoMode = AUDIO_PLAY_MONO_OFF; } else { switch (audio_stream->mono_mode) { case MONO_LEFT: pcm_play_ctrl.monoMode = AUDIO_PLAY_LEFT_MONO; break; case MONO_RIGHT: pcm_play_ctrl.monoMode = AUDIO_PLAY_RIGHT_MONO; break; case MONO_BOTH: default: pcm_play_ctrl.monoMode = AUDIO_PLAY_BOTH_MONO; break; } } if (audio_stream->format == SAMPLE_16IN16) { pcm_play_ctrl.sampleSize = SAMPLE_16BIT; i2s_play_ctrl.sampleSize = SAMPLE_16BIT; } else if (audio_stream->format == SAMPLE_24IN32) { pcm_play_ctrl.sampleSize = SAMPLE_24BIT; i2s_play_ctrl.sampleSize = SAMPLE_24BIT; } else if (audio_stream->format == SAMPLE_32IN32) { pcm_play_ctrl.sampleSize = SAMPLE_32BIT; i2s_play_ctrl.sampleSize = SAMPLE_32BIT; } else { snd_printk("Requested format %d is not supported\n", runtime->format); return -1; } /* buffer and period sizes in frame */ pcm_play_ctrl.bufferPhyBase = audio_stream->dma_addr; pcm_play_ctrl.bufferSize = audio_stream->dma_size; pcm_play_ctrl.intByteCount = audio_stream->period_size; /* I2S playback streem stuff */ /*i2s_play_ctrl.sampleSize = pcm_play_ctrl.sampleSize;*/ i2s_play_ctrl.justification = I2S_JUSTIFIED; i2s_play_ctrl.sendLastFrame = 0; spdif_play_ctrl.nonPcm = MV_FALSE; spdif_play_ctrl.validity = chip->ch_stat_valid; if (audio_stream->stat_mem) { spdif_play_ctrl.userBitsFromMemory = MV_TRUE; spdif_play_ctrl.validityFromMemory = MV_TRUE; spdif_play_ctrl.blockStartInternally = MV_FALSE; } else { spdif_play_ctrl.userBitsFromMemory = MV_FALSE; spdif_play_ctrl.validityFromMemory = MV_FALSE; spdif_play_ctrl.blockStartInternally = MV_TRUE; } /* If this is non-PCM sound, mute I2S channel */ spin_lock_irq(&chip->reg_lock); if (!(mv88fx_snd_readl(chip, MV_AUDIO_PLAYBACK_CTRL_REG) & (APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK))) { if (MV_OK != mvAudioDCOCtrlSet(&dco_ctrl)) { snd_printk("Failed to initialize DCO clock control.\n"); return -1; } } if (audio_stream->clock_src == DCO_CLOCK) while ((mv88fx_snd_readl(chip, MV_AUDIO_SPCR_DCO_STATUS_REG) & ASDSR_DCO_LOCK_MASK) == 0); else if (audio_stream->clock_src == SPCR_CLOCK) while ((mv88fx_snd_readl(chip, MV_AUDIO_SPCR_DCO_STATUS_REG) & ASDSR_SPCR_LOCK_MASK) == 0); if (MV_OK != mvAudioPlaybackControlSet(&pcm_play_ctrl)) { snd_printk("Failed to initialize PCM playback control.\n"); return -1; } if (MV_OK != mvI2SPlaybackCtrlSet(&i2s_play_ctrl)) { snd_printk("Failed to initialize I2S playback control.\n"); return -1; } mvSPDIFPlaybackCtrlSet(&spdif_play_ctrl); spin_unlock_irq(&chip->reg_lock); #if 0 mv88fx_snd_debug("runtime->xfer_align=%d\n",(int)runtime->xfer_align); mv88fx_snd_debug("runtime->format=%d\n",runtime->format); mv88fx_snd_debug("runtime->channels=%d\n",runtime->channels); mv88fx_snd_debug("runtime->rate=%d\n",runtime->rate); mv88fx_snd_debug("runtime->dma_addr=0x%x\n",runtime->dma_addr); mv88fx_snd_debug("runtime->dma_area=0x%x\n",(unsigned int)runtime->dma_area); mv88fx_snd_debug("runtime->frame_bits=0x%x\n",runtime->frame_bits); mv88fx_snd_debug("runtime->period_size=0x%x\n", (unsigned int)runtime->period_size); mv88fx_snd_debug("runtime->buffer_size=0x%x\n", (unsigned int)runtime->buffer_size); mv88fx_snd_debug("bufferPhyBase=0x%x\n",runtime->dma_addr); mv88fx_snd_debug("bufferSize=0x%x\n",pcm_play_ctrl.bufferSize); mv88fx_snd_debug("intByteCount=0x%x.\n",pcm_play_ctrl.intByteCount); #endif return 0; }
static int mv88fx_i2s_snd_hw_playback_set(struct mv88fx_snd_chip *chip, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct mv88fx_snd_stream *audio_stream = runtime->private_data; MV_AUDIO_PLAYBACK_CTRL pcm_play_ctrl; MV_I2S_PLAYBACK_CTRL i2s_play_ctrl; MV_SPDIF_PLAYBACK_CTRL spdif_play_ctrl; MV_AUDIO_FREQ_DATA dco_ctrl; mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base); memset(&pcm_play_ctrl, 0, sizeof(pcm_play_ctrl)); memset(&dco_ctrl, 0, sizeof(dco_ctrl)); memset(&i2s_play_ctrl, 0, sizeof(i2s_play_ctrl)); memset(&spdif_play_ctrl, 0, sizeof(spdif_play_ctrl)); dco_ctrl.offset = chip->dco_ctrl_offst; mv88fx_snd_debug("rate: %u ", runtime->rate); switch (runtime->rate) { case 44100: dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH; break; case 48000: dco_ctrl.baseFreq = AUDIO_FREQ_48KH; break; case 96000: dco_ctrl.baseFreq = AUDIO_FREQ_96KH; break; default: mv88fx_snd_error("Requested rate %d is not supported", runtime->rate); return -1; } pcm_play_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST : AUDIO_32BYTE_BURST; pcm_play_ctrl.loopBack = chip->loopback; if (mv88fx_pcm_is_stereo(runtime)) { pcm_play_ctrl.monoMode = AUDIO_PLAY_MONO_OFF; } else { switch (audio_stream->mono_mode) { case MONO_LEFT: pcm_play_ctrl.monoMode = AUDIO_PLAY_LEFT_MONO; break; case MONO_RIGHT: pcm_play_ctrl.monoMode = AUDIO_PLAY_RIGHT_MONO; break; case MONO_BOTH: default: pcm_play_ctrl.monoMode = AUDIO_PLAY_BOTH_MONO; break; } } if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { pcm_play_ctrl.sampleSize = SAMPLE_16BIT; i2s_play_ctrl.sampleSize = SAMPLE_16BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) { pcm_play_ctrl.sampleSize = SAMPLE_24BIT; i2s_play_ctrl.sampleSize = SAMPLE_24BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) { pcm_play_ctrl.sampleSize = SAMPLE_32BIT; i2s_play_ctrl.sampleSize = SAMPLE_32BIT; } else { mv88fx_snd_error("Requested format %d is not supported", runtime->format); return -1; } /* buffer and period sizes in frame */ pcm_play_ctrl.bufferPhyBase = runtime->dma_addr; pcm_play_ctrl.bufferSize = frames_to_bytes(runtime, runtime->buffer_size); pcm_play_ctrl.intByteCount = frames_to_bytes(runtime, runtime->period_size); /* I2S playback streem stuff */ /*i2s_play_ctrl.sampleSize = pcm_play_ctrl.sampleSize; */ i2s_play_ctrl.justification = I2S_JUSTIFIED; i2s_play_ctrl.sendLastFrame = 0; spdif_play_ctrl.nonPcm = MV_FALSE; spdif_play_ctrl.validity = chip->ch_stat_valid; if (audio_stream->stat_mem) { spdif_play_ctrl.userBitsFromMemory = MV_TRUE; spdif_play_ctrl.validityFromMemory = MV_TRUE; spdif_play_ctrl.blockStartInternally = MV_FALSE; } else { spdif_play_ctrl.userBitsFromMemory = MV_FALSE; spdif_play_ctrl.validityFromMemory = MV_FALSE; spdif_play_ctrl.blockStartInternally = MV_TRUE; } mv88fx_snd_debug(""); /* If this is non-PCM sound, mute I2S channel */ spin_lock_irq(&chip->reg_lock); mv88fx_snd_debug("chip=%p chip->base=%p port=%d", chip, chip->base, chip->port); if (!(mv88fx_snd_readl(chip->base, MV_AUDIO_PLAYBACK_CTRL_REG(chip->port)) & (APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK))) { mv88fx_snd_debug(""); if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) { mv88fx_snd_error ("Failed to initialize DCO clock control."); return -1; mv88fx_snd_debug(""); } } mv88fx_snd_debug(""); if (audio_stream->clock_src == DCO_CLOCK) while ((mv88fx_snd_readl(chip->base, MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) & ASDSR_DCO_LOCK_MASK) == 0) ; else if (audio_stream->clock_src == SPCR_CLOCK) while ((mv88fx_snd_readl(chip->base, MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) & ASDSR_SPCR_LOCK_MASK) == 0) ; mv88fx_snd_debug(""); if (MV_OK != mvAudioPlaybackControlSet(chip->port, &pcm_play_ctrl)) { mv88fx_snd_error("Failed to initialize PCM playback control."); return -1; } mv88fx_snd_debug(""); if (MV_OK != mvI2SPlaybackCtrlSet(chip->port, &i2s_play_ctrl)) { mv88fx_snd_error("Failed to initialize I2S playback control."); return -1; } mv88fx_snd_debug(""); mvSPDIFPlaybackCtrlSet(chip->port, &spdif_play_ctrl); mv88fx_snd_debug(""); spin_unlock_irq(&chip->reg_lock); return 0; }
int mv88fx_snd_hw_capture_set(struct mv88fx_snd_chip *chip) { struct mv88fx_snd_stream *audio_stream = chip->stream[CAPTURE]; struct snd_pcm_substream *substream = audio_stream->substream; struct snd_pcm_runtime *runtime = substream->runtime; MV_AUDIO_RECORD_CTRL pcm_rec_ctrl; MV_I2S_RECORD_CTRL i2s_rec_ctrl; MV_AUDIO_FREQ_DATA dco_ctrl; dco_ctrl.offset = chip->dco_ctrl_offst; switch(audio_stream->rate) { case 44100: dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH; break; case 48000: dco_ctrl.baseFreq = AUDIO_FREQ_48KH; break; case 96000: dco_ctrl.baseFreq = AUDIO_FREQ_96KH; break; default: snd_printk("Requested rate %d is not supported\n", runtime->rate); return -1; } pcm_rec_ctrl.burst = (chip->burst == 128)?AUDIO_128BYTE_BURST: AUDIO_32BYTE_BURST; if (audio_stream->format == SAMPLE_16IN16) { pcm_rec_ctrl.sampleSize = SAMPLE_16BIT; } else if (audio_stream->format == SAMPLE_24IN32) { pcm_rec_ctrl.sampleSize = SAMPLE_24BIT; } else if (audio_stream->format == SAMPLE_32IN32) { pcm_rec_ctrl.sampleSize = SAMPLE_32BIT; } else { snd_printk("Requested format %d is not supported\n", runtime->format); return -1; } pcm_rec_ctrl.mono = (audio_stream->stereo) ? MV_FALSE : MV_TRUE; if (pcm_rec_ctrl.mono) { switch (audio_stream->mono_mode) { case MONO_LEFT: pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO; break; default: case MONO_RIGHT: pcm_rec_ctrl.monoChannel = AUDIO_REC_RIGHT_MONO; break; } } else pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO; pcm_rec_ctrl.bufferPhyBase = audio_stream->dma_addr; pcm_rec_ctrl.bufferSize = audio_stream->dma_size; pcm_rec_ctrl.intByteCount = audio_stream->period_size; /* I2S record streem stuff */ i2s_rec_ctrl.sample = pcm_rec_ctrl.sampleSize; i2s_rec_ctrl.justf = I2S_JUSTIFIED; spin_lock_irq(&chip->reg_lock); /* set clock only if record is not enabled*/ if (!(mv88fx_snd_readl(chip, MV_AUDIO_RECORD_CTRL_REG) & (ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK))) { if (MV_OK != mvAudioDCOCtrlSet(&dco_ctrl)) { snd_printk("Failed to initialize DCO clock control.\n"); return -1; } } if (MV_OK != mvAudioRecordControlSet(&pcm_rec_ctrl)) { snd_printk("Failed to initialize PCM record control.\n"); return -1; } if (MV_OK != mvI2SRecordCntrlSet(&i2s_rec_ctrl)) { snd_printk("Failed to initialize I2S record control.\n"); return -1; } spin_unlock_irq(&chip->reg_lock); #if 0 mv88fx_snd_debug("pcm_rec_ctrl.bufferSize=0x%x\n",(int)pcm_rec_ctrl.bufferSize); mv88fx_snd_debug("pcm_rec_ctrl.intByteCount=0x%x\n",(int)pcm_rec_ctrl.intByteCount); mv88fx_snd_debug("runtime->xfer_align=%d\n",(int)runtime->xfer_align); mv88fx_snd_debug("runtime->format=%d\n",runtime->format); mv88fx_snd_debug("runtime->channels=%d\n",runtime->channels); mv88fx_snd_debug("runtime->rate=%d\n",runtime->rate); mv88fx_snd_debug("runtime->dma_addr=0x%x\n",runtime->dma_addr); mv88fx_snd_debug("runtime->dma_area=0x%x\n",(unsigned int)runtime->dma_area); mv88fx_snd_debug("runtime->frame_bits=0x%x\n",runtime->frame_bits); mv88fx_snd_debug("runtime->period_size=0x%x\n", (unsigned int)runtime->period_size); mv88fx_snd_debug("runtime->buffer_size=0x%x\n", (unsigned int)runtime->buffer_size); mv88fx_snd_debug("bufferPhyBase=0x%x\n",runtime->dma_addr); #endif return 0; }
static int mv88fx_i2s_snd_hw_capture_set(struct mv88fx_snd_chip *chip, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct mv88fx_snd_stream *audio_stream = runtime->private_data; MV_AUDIO_RECORD_CTRL pcm_rec_ctrl; MV_I2S_RECORD_CTRL i2s_rec_ctrl; MV_AUDIO_FREQ_DATA dco_ctrl; //#ifdef CONFIG_MACH_DOVE_RD_AVNG // int phoneInDetected; //#endif mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base); dco_ctrl.offset = chip->dco_ctrl_offst; switch (runtime->rate) { case 44100: dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH; break; case 48000: dco_ctrl.baseFreq = AUDIO_FREQ_48KH; break; case 96000: dco_ctrl.baseFreq = AUDIO_FREQ_96KH; break; default: mv88fx_snd_debug("ERROR"); mv88fx_snd_error("Requested rate %d is not supported", runtime->rate); return -1; } pcm_rec_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST : AUDIO_32BYTE_BURST; if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { pcm_rec_ctrl.sampleSize = SAMPLE_16BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) { pcm_rec_ctrl.sampleSize = SAMPLE_24BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) { pcm_rec_ctrl.sampleSize = SAMPLE_32BIT; } else { mv88fx_snd_error("Requested format %d is not supported", runtime->format); return -1; } pcm_rec_ctrl.mono = (mv88fx_pcm_is_stereo(runtime)) ? MV_FALSE : MV_TRUE; if (pcm_rec_ctrl.mono) { switch (audio_stream->mono_mode) { case MONO_LEFT: pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO; break; default: case MONO_RIGHT: pcm_rec_ctrl.monoChannel = AUDIO_REC_RIGHT_MONO; break; } } else pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO; pcm_rec_ctrl.bufferPhyBase = runtime->dma_addr; pcm_rec_ctrl.bufferSize = frames_to_bytes(runtime, runtime->buffer_size); pcm_rec_ctrl.intByteCount = frames_to_bytes(runtime, runtime->period_size); /* I2S record streem stuff */ i2s_rec_ctrl.sample = pcm_rec_ctrl.sampleSize; i2s_rec_ctrl.justf = I2S_JUSTIFIED; spin_lock_irq(&chip->reg_lock); /* set clock only if record is not enabled */ if (!(mv88fx_snd_readl(chip->base, MV_AUDIO_RECORD_CTRL_REG(chip->port)) & (ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK))) { if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) { mv88fx_snd_debug("ERROR"); mv88fx_snd_error ("Failed to initialize DCO clock control."); return -1; } } mv88fx_snd_debug(""); if (MV_OK != mvAudioRecordControlSet(chip->port, &pcm_rec_ctrl)) { mv88fx_snd_error("Failed to initialize PCM record control."); return -1; } if (MV_OK != mvI2SRecordCntrlSet(chip->port, &i2s_rec_ctrl)) { mv88fx_snd_error("Failed to initialize I2S record control."); return -1; } mv88fx_snd_debug(""); //#ifdef CONFIG_MACH_DOVE_RD_AVNG // if (machine_is_dove_rd_avng()) { // phoneInDetected = gpio_get_value(53); // if (phoneInDetected < 0) // mv88fx_snd_error("Failed to detect phone-in."); // else { // int input_type; // mv88fx_snd_error("detect phone-in."); // if (!phoneInDetected) // input_type = 2; /* external MIC */ // else // input_type = 1; /* internal MIC */ // } // } //#endif mv88fx_snd_debug(""); spin_unlock_irq(&chip->reg_lock); mv88fx_snd_debug(""); return 0; }