static void aml_dai_spdif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = substream->runtime; /* struct snd_dma_buffer *buf = &substream->dma_buffer; */ ALSA_TRACE(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { memset((void *)runtime->dma_area, 0, snd_pcm_lib_buffer_bytes(substream)); if (IEC958_mode_codec == 6) { printk ("[%s %d]8chPCM output:disable aml_spdif_play()\n", __func__, __LINE__); } else { aml_spdif_play(); } /* audio_spdifout_pg_enable(0); */ } } static int aml_dai_spdif_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {
void aml_alsa_hw_reprepare(void) { /* diable 958 module before call initiation */ audio_hw_958_enable(0); aml_hw_iec958_init(); }
WRITE_MPEG_REG(AIU_958_CHSTAT_R0, 0x1902); WRITE_MPEG_REG(AIU_958_CHSTAT_R1, 0x900); aout_notifier_call_chain(AOUT_EVENT_RAWDATA_MAT_MLP, substream); } else { aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM, substream); } ALSA_PRINT("spdif dma %x,phy addr %x\n", (unsigned)runtime->dma_area, (unsigned)runtime->dma_addr); }
static int aml_i2s_copy_playback(struct snd_pcm_runtime *runtime, int channel, snd_pcm_uframes_t pos, void __user *buf, snd_pcm_uframes_t count, struct snd_pcm_substream *substream) { int res = 0; int n; int i = 0, j = 0; int align = runtime->channels * 32 / runtime->byte_align; char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, pos); struct aml_runtime_data *prtd = runtime->private_data; struct snd_dma_buffer *buffer = &substream->dma_buffer; struct aml_audio_buffer *tmp_buf = buffer->private_data; void *ubuf = tmp_buf->buffer_start; audio_stream_t *s = &prtd->s; int force_reinit_958 = 0; force_reinit_958 = (IEC958_mode_codec == 0 && (READ_MPEG_REG(AIU_MEM_IEC958_START_PTR) != READ_MPEG_REG(AIU_MEM_I2S_START_PTR))); if (s && s->device_type == AML_AUDIO_I2SOUT && (trigger_underrun) && kernel_android_50 == 1) { printk("i2s out trigger underrun force_reinit_958/%d trigger_underrun/%d IEC958_mode_codec/%d IEC958_START_PTR/0x%x I2S_START_PTR/0x%x\n", force_reinit_958, trigger_underrun, IEC958_mode_codec, READ_MPEG_REG(AIU_MEM_IEC958_START_PTR), READ_MPEG_REG(AIU_MEM_I2S_START_PTR)); //trigger_underrun = 0; return -EFAULT; } if (s && s->device_type == AML_AUDIO_I2SOUT && force_reinit_958 && kernel_android_50 == 1) { printk("i2s out trigger underrun force_reinit_958/%d", force_reinit_958); audio_hw_958_enable(0); aml_hw_iec958_init(substream); audio_hw_958_enable(1); } if (s->device_type == AML_AUDIO_I2SOUT) { aml_i2s_alsa_write_addr = frames_to_bytes(runtime, pos); } n = frames_to_bytes(runtime, count); if (aml_i2s_playback_enable == 0 && s->device_type == AML_AUDIO_I2SOUT) { return res; } res = copy_from_user(ubuf, buf, n); if (res) { return -EFAULT; } if (access_ok(VERIFY_READ, buf, frames_to_bytes(runtime, count))) { if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { int16_t * tfrom, *to, *left, *right; tfrom = (int16_t*)ubuf; to = (int16_t*)hwbuf; left = to; right = to + 16; if (pos % align) { printk("audio data unligned: pos=%d, n=%d, align=%d\n", (int)pos, n, align); } if (set_android_gain_enable == 0) { for (j = 0; j < n; j += 64) { for (i = 0; i < 16; i++) { *left++ = (*tfrom++) ; *right++ = (*tfrom++); } left += 16; right += 16; } } else { for (j = 0; j < n; j += 64) { for (i = 0; i < 16; i++) { *left++ = (int16_t)(((*tfrom++) * android_left_gain) >> 8); *right++ = (int16_t)(((*tfrom++) * android_right_gain) >> 8); } left += 16; right += 16; } } } else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE && I2S_MODE == AIU_I2S_MODE_PCM24) {
static int aml_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct aml_runtime_data *prtd = runtime->private_data; audio_stream_t *s = &prtd->s; int iec958 = 0; if(prtd == 0) return 0; switch(runtime->rate){ case 192000: s->sample_rate = AUDIO_CLK_FREQ_192; break; case 176400: s->sample_rate = AUDIO_CLK_FREQ_1764; break; case 96000: s->sample_rate = AUDIO_CLK_FREQ_96; break; case 88200: s->sample_rate = AUDIO_CLK_FREQ_882; break; case 48000: s->sample_rate = AUDIO_CLK_FREQ_48; iec958 = 2; break; case 44100: s->sample_rate = AUDIO_CLK_FREQ_441; iec958 = 0; break; case 32000: s->sample_rate = AUDIO_CLK_FREQ_32; iec958 = 3; break; case 8000: s->sample_rate = AUDIO_CLK_FREQ_8; break; case 11025: s->sample_rate = AUDIO_CLK_FREQ_11; break; case 16000: s->sample_rate = AUDIO_CLK_FREQ_16; break; case 22050: s->sample_rate = AUDIO_CLK_FREQ_22; break; case 12000: s->sample_rate = AUDIO_CLK_FREQ_12; break; case 24000: s->sample_rate = AUDIO_CLK_FREQ_22; break; default: s->sample_rate = AUDIO_CLK_FREQ_441; break; }; // iec958 and i2s clock are separated since M8 #if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8 audio_set_clk(s->sample_rate, AUDIO_CLK_256FS); audio_util_set_dac_format(AUDIO_ALGOUT_DAC_FORMAT_DSP); #else audio_set_i2s_clk(s->sample_rate, AUDIO_CLK_256FS); audio_set_958_clk(s->sample_rate, AUDIO_CLK_256FS); audio_util_set_dac_i2s_format(AUDIO_ALGOUT_DAC_FORMAT_DSP); audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP); #endif if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ trigger_underun = 0; aml_hw_i2s_init(runtime); aml_hw_iec958_init(substream); } else{ //printk("aml_pcm_prepare SNDRV_PCM_STREAM_CAPTURE: dma_addr=%x, dma_bytes=%x\n", runtime->dma_addr, runtime->dma_bytes); audio_in_i2s_set_buf(runtime->dma_addr, runtime->dma_bytes*2,audioin_mode); memset((void*)runtime->dma_area,0,runtime->dma_bytes*2); { int * ppp = (int*)(runtime->dma_area+runtime->dma_bytes*2-8); ppp[0] = 0x78787878; ppp[1] = 0x78787878; } } if( IEC958_MODE == AIU_958_MODE_PCM_RAW){ if(IEC958_mode_codec == 4 ){ // need Over clock for dd+ WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 4, 2); // 4x than i2s audio_notify_hdmi_info(AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS, substream); }else if(IEC958_mode_codec == 3 ||IEC958_mode_codec == 1 ){ // no-over clock for dts pcm mode audio_notify_hdmi_info(AOUT_EVENT_RAWDATA_DTS, substream); } else //dd audio_notify_hdmi_info(AOUT_EVENT_RAWDATA_AC_3, substream); }else if(IEC958_mode_codec == 1){ audio_notify_hdmi_info(AOUT_EVENT_RAWDATA_DTS, substream); }else{ audio_notify_hdmi_info(AOUT_EVENT_IEC_60958_PCM, substream); } #if 0 printk("Audio Parameters:\n"); printk("\tsample rate: %d\n", runtime->rate); printk("\tchannel: %d\n", runtime->channels); printk("\tsample bits: %d\n", runtime->sample_bits); printk("\tformat: %s\n", snd_pcm_format_name(runtime->format)); printk("\tperiod size: %ld\n", runtime->period_size); printk("\tperiods: %d\n", runtime->periods); printk("\tiec958 mode: %d, raw=%d, codec=%d\n", IEC958_MODE, IEC958_mode_raw, IEC958_mode_codec); #endif return 0; }
extern void aml_hw_iec958_init(struct snd_pcm_substream *substream); static int aml_dai_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = substream->runtime; struct aml_runtime_data *prtd = runtime->private_data; struct aml_i2s *i2s = snd_soc_dai_get_drvdata(dai); int audio_clk_config = AUDIO_CLK_FREQ_48; audio_stream_t *s = &prtd->s; ALSA_TRACE(); switch (runtime->rate) { case 192000: audio_clk_config = AUDIO_CLK_FREQ_192; break; case 176400: audio_clk_config = AUDIO_CLK_FREQ_1764; break; case 96000: audio_clk_config = AUDIO_CLK_FREQ_96; break; case 88200: audio_clk_config = AUDIO_CLK_FREQ_882; break; case 48000: audio_clk_config = AUDIO_CLK_FREQ_48; break; case 44100: audio_clk_config = AUDIO_CLK_FREQ_441; break; case 32000: audio_clk_config = AUDIO_CLK_FREQ_32; break; case 8000: audio_clk_config = AUDIO_CLK_FREQ_8; break; case 11025: audio_clk_config = AUDIO_CLK_FREQ_11; break; case 16000: audio_clk_config = AUDIO_CLK_FREQ_16; break; case 22050: audio_clk_config = AUDIO_CLK_FREQ_22; break; case 12000: audio_clk_config = AUDIO_CLK_FREQ_12; break; case 24000: audio_clk_config = AUDIO_CLK_FREQ_22; break; default: audio_clk_config = AUDIO_CLK_FREQ_441; break; }; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) audio_out_i2s_enable(0); if (i2s->old_samplerate != runtime->rate) { ALSA_PRINT("enterd %s,old_samplerate:%d,sample_rate=%d\n", __func__, i2s->old_samplerate, runtime->rate); i2s->old_samplerate = runtime->rate; audio_set_i2s_clk(audio_clk_config, AUDIO_CLK_256FS, i2s->mpll); } audio_util_set_dac_i2s_format(AUDIO_ALGOUT_DAC_FORMAT_DSP); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { s->i2s_mode = dai_info[dai->id].i2s_mode; audio_in_i2s_set_buf(runtime->dma_addr, runtime->dma_bytes * 2, 0, i2s_pos_sync); memset((void *)runtime->dma_area, 0, runtime->dma_bytes * 2); { int *ppp = (int *)(runtime->dma_area + runtime->dma_bytes * 2 - 8); ppp[0] = 0x78787878; ppp[1] = 0x78787878; } s->device_type = AML_AUDIO_I2SIN; } else { s->device_type = AML_AUDIO_I2SOUT; aml_hw_i2s_init(runtime); /* i2s/958 share the same audio hw buffer when PCM mode */ if (IEC958_mode_codec == 0) { aml_hw_iec958_init(substream); /* use the hw same sync for i2s/958 */ WRITE_MPEG_REG_BITS(AIU_I2S_MISC, 1, 3, 1); } else WRITE_MPEG_REG_BITS(AIU_I2S_MISC, 0, 3, 1); } if (runtime->channels == 8) {
static int aml_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct aml_runtime_data *prtd = runtime->private_data; audio_stream_t *s = &prtd->s; int iec958 = 0; if(prtd == 0) return 0; switch(runtime->rate){ case 192000: s->sample_rate = AUDIO_CLK_FREQ_192; break; case 176400: s->sample_rate = AUDIO_CLK_FREQ_1764; break; case 96000: s->sample_rate = AUDIO_CLK_FREQ_96; break; case 88200: s->sample_rate = AUDIO_CLK_FREQ_882; break; case 48000: s->sample_rate = AUDIO_CLK_FREQ_48; iec958 = 2; break; case 44100: s->sample_rate = AUDIO_CLK_FREQ_441; iec958 = 0; break; case 32000: s->sample_rate = AUDIO_CLK_FREQ_32; iec958 = 3; break; case 8000: s->sample_rate = AUDIO_CLK_FREQ_8; break; case 11025: s->sample_rate = AUDIO_CLK_FREQ_11; break; case 16000: s->sample_rate = AUDIO_CLK_FREQ_16; break; case 22050: s->sample_rate = AUDIO_CLK_FREQ_22; break; case 12000: s->sample_rate = AUDIO_CLK_FREQ_12; break; case 24000: s->sample_rate = AUDIO_CLK_FREQ_22; break; default: s->sample_rate = AUDIO_CLK_FREQ_441; break; }; audio_set_clk(s->sample_rate, AUDIO_CLK_256FS); audio_util_set_dac_format(AUDIO_ALGOUT_DAC_FORMAT_DSP); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ aml_hw_i2s_init(runtime); aml_hw_iec958_init(); } else{ //printk("aml_pcm_prepare SNDRV_PCM_STREAM_CAPTURE: dma_addr=%x, dma_bytes=%x\n", runtime->dma_addr, runtime->dma_bytes); audio_in_i2s_set_buf(runtime->dma_addr, runtime->dma_bytes*2); memset((void*)runtime->dma_area,0,runtime->dma_bytes*2); { int * ppp = (int*)(runtime->dma_area+runtime->dma_bytes*2-8); ppp[0] = 0x78787878; ppp[1] = 0x78787878; } } aout_notifier_call_chain(AOUT_EVENT_PREPARE, substream); if( IEC958_MODE == AIU_958_MODE_PCM_RAW) aout_notifier_call_chain(AOUT_EVENT_RAWDATA_AC_3, substream); if( IEC958_MODE == AIU_958_MODE_RAW) aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DTS, substream); #if 0 printk("Audio Parameters:\n"); printk("\tsample rate: %d\n", runtime->rate); printk("\tchannel: %d\n", runtime->channels); printk("\tsample bits: %d\n", runtime->sample_bits); printk("\tformat: %s\n", snd_pcm_format_name(runtime->format)); printk("\tperiod size: %ld\n", runtime->period_size); printk("\tperiods: %d\n", runtime->periods); printk("\tiec958 mode: %d, raw=%d, codec=%d\n", IEC958_MODE, IEC958_mode_raw, IEC958_mode_codec); #endif return 0; }