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; }
void aml_m1_reset(struct snd_soc_codec* codec, bool first_time) { unsigned long data32; if(first_time){ /* initialize clock for audiodac */ audio_set_clk(AUDIO_CLK_FREQ_48,0); /* power up pll */ WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) & ~(1 << 15)); /* enable audiodac clock */ WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 1, 23, 1); msleep(100); data32 = 0; data32 |= 0 << 15; // [15] audac_soft_reset_n data32 |= 0 << 14; // [14] audac_reset_ctrl: 0=use audac_reset_n pulse from reset module; 1=use audac_soft_reset_n. data32 |= 0 << 9; // [9] delay_rd_en data32 |= 0 << 8; // [8] audac_reg_clk_inv data32 |= 0 << 1; // [7:1] audac_i2caddr data32 |= 0 << 0; // [0] audac_intfsel: 0=use host bus; 1=use I2C. WRITE_MPEG_REG(AIU_AUDAC_CTRL0, data32); // Enable APB3 fail on error data32 = 0; data32 |= 1 << 15; // [15] err_en data32 |= 255 << 0; // [11:0] max_err WRITE_MPEG_REG(AIU_AUDAC_CTRL1, data32); snd_soc_write(codec, ADAC_RESET, (0<<1)); snd_soc_write(codec, ADAC_RESET, (0<<1)); snd_soc_write(codec, ADAC_RESET, (0<<1)); snd_soc_write(codec, ADAC_RESET, (0<<1)); snd_soc_write(codec, ADAC_RESET, (0<<1)); msleep(100); snd_soc_write(codec,ADAC_CLOCK, 0); snd_soc_write(codec,ADAC_I2S_CONFIG_REG1, 6); snd_soc_write(codec, ADAC_I2S_CONFIG_REG2, 1|(1<<3)); // I2S, split snd_soc_write(codec, ADAC_POWER_CTRL_REG1, 0xc3); snd_soc_write(codec, ADAC_POWER_CTRL_REG2, 0); snd_soc_write(codec, ADAC_MUTE_CTRL_REG1,0); snd_soc_write(codec,ADAC_DAC_ADC_MIXER, 0); snd_soc_write(codec,ADAC_PLAYBACK_VOL_CTRL_LSB, 0x54); snd_soc_write(codec,ADAC_PLAYBACK_VOL_CTRL_MSB, 0x54); snd_soc_write(codec,ADAC_STEREO_HS_VOL_CTRL_LSB, 0x28); snd_soc_write(codec,ADAC_STEREO_HS_VOL_CTRL_MSB, 0x28); latch(codec); snd_soc_write(codec, ADAC_POWER_CTRL_REG2, (0<<7)); latch(codec); snd_soc_write(codec, ADAC_POWER_CTRL_REG2, (1<<7)); latch(codec); }else{ latch(codec); snd_soc_write(codec, ADAC_POWER_CTRL_REG2, (0<<7)); latch(codec); snd_soc_write(codec, ADAC_POWER_CTRL_REG2, (1<<7)); latch(codec); } snd_soc_write(codec, ADAC_RESET, (0<<1)); latch(codec); snd_soc_write(codec, ADAC_RESET, (1<<1)); latch(codec); msleep(100); }
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; }