コード例 #1
0
ファイル: aml_spdif_dai.c プロジェクト: akuster/linux-meson
void aml_spdif_play(void)
{
	_aiu_958_raw_setting_t set;
	_aiu_958_channel_status_t chstat;
	struct snd_pcm_substream substream;
	struct snd_pcm_runtime runtime;
	substream.runtime = &runtime;
	
runtime.rate = 48000;
	runtime.format = SNDRV_PCM_FORMAT_S16_LE;
	runtime.channels = 2;
	runtime.sample_bits = 16;
	memset((void *)(&set), 0, sizeof(set));
	memset((void *)(&chstat), 0, sizeof(chstat));
	set.chan_stat = &chstat;
	set.chan_stat->chstat0_l = 0x0100;
	set.chan_stat->chstat0_r = 0x0100;
	set.chan_stat->chstat1_l = 0X200;
	set.chan_stat->chstat1_r = 0X200;
	audio_hw_958_enable(0);
	if (last_iec_clock != AUDIO_CLK_FREQ_48) {
		ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n", __func__,
			   last_iec_clock, AUDIO_CLK_FREQ_48);
		
last_iec_clock = AUDIO_CLK_FREQ_48;
		audio_set_958_clk(AUDIO_CLK_FREQ_48, AUDIO_CLK_256FS);
	
}
	audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
	memset(iec958buf, 0, sizeof(iec958buf));
	audio_set_958outbuf((virt_to_phys(iec958buf) + 63) & (~63), 128, 2, 0);
	audio_set_958_mode(AIU_958_MODE_PCM16, &set);
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);	/* 512fs divide 4 == 128fs */
#else
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2);	/* 256fs divide 2 == 128fs */
#endif
	aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM, &substream);
コード例 #2
0
ファイル: aml_spdif_dai.c プロジェクト: akuster/linux-meson
1)NONE-PCM  raw output ,only available when ac3/dts audio,when raw output mode is selected by user.
2)PCM  output for  all audio, when pcm mode is selected by user .
3)PCM  output for audios except ac3/dts,when raw output mode is selected by user
*/
void aml_hw_iec958_init(struct snd_pcm_substream *substream)
{
	_aiu_958_raw_setting_t set;
	_aiu_958_channel_status_t chstat;
	unsigned i2s_mode, iec958_mode;
	unsigned start, size;
	int sample_rate;
	struct snd_dma_buffer *buf = &substream->dma_buffer;
	struct snd_pcm_runtime *runtime = substream->runtime;
	if (buf == NULL && runtime == NULL) {
		
printk("buf/0x%x runtime/0x%x\n", (unsigned)buf,
			(unsigned)runtime);
		
return;
	}

	i2s_mode = AIU_I2S_MODE_PCM16;
	sample_rate = AUDIO_CLK_FREQ_48;
	memset((void *)(&set), 0, sizeof(set));
	memset((void *)(&chstat), 0, sizeof(chstat));
	set.chan_stat = &chstat;
	printk("----aml_hw_iec958_init,runtime->rate=%d--\n", runtime->rate);
	
switch (runtime->rate) {
	case 192000:
		sample_rate = AUDIO_CLK_FREQ_192;
		break;
	case 176400:
		sample_rate = AUDIO_CLK_FREQ_1764;
		break;
	case 96000:
		sample_rate = AUDIO_CLK_FREQ_96;
		break;
	case 88200:
		sample_rate = AUDIO_CLK_FREQ_882;
		break;
	case 48000:
		sample_rate = AUDIO_CLK_FREQ_48;
		break;
	case 44100:
		sample_rate = AUDIO_CLK_FREQ_441;
		break;
	case 32000:
		sample_rate = AUDIO_CLK_FREQ_32;
		break;
	case 8000:
		sample_rate = AUDIO_CLK_FREQ_8;
		break;
	case 11025:
		sample_rate = AUDIO_CLK_FREQ_11;
		break;
	case 16000:
		sample_rate = AUDIO_CLK_FREQ_16;
		break;
	case 22050:
		sample_rate = AUDIO_CLK_FREQ_22;
		break;
	case 12000:
		sample_rate = AUDIO_CLK_FREQ_12;
		break;
	case 24000:
		sample_rate = AUDIO_CLK_FREQ_22;
		break;
	default:
		sample_rate = AUDIO_CLK_FREQ_441;
		break;
	};
	audio_hw_958_enable(0);
	if (last_iec_clock != sample_rate) {
		ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n", __func__,
			   last_iec_clock, sample_rate);
		
last_iec_clock = sample_rate;
		audio_set_958_clk(sample_rate, AUDIO_CLK_256FS);
	}
	printk("----aml_hw_iec958_init,runtime->rate=%d,sample_rate=%d--\n",
	       runtime->rate, sample_rate);
	audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
	/*clear the same source function as new raw data output */
	WRITE_MPEG_REG_BITS(AIU_I2S_MISC, 0, 3, 1);
	switch (runtime->format) {
	case SNDRV_PCM_FORMAT_S32_LE:
		i2s_mode = AIU_I2S_MODE_PCM32;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		i2s_mode = AIU_I2S_MODE_PCM24;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		i2s_mode = AIU_I2S_MODE_PCM16;
		break;
	}

	/* audio_set_i2s_mode(i2s_mode); */
	/* case 1,raw mode enabled */
	if (IEC958_mode_codec) {
		if (IEC958_mode_codec == 1) {	/* dts, use raw sync-word mode */
			iec958_mode = AIU_958_MODE_RAW;
			printk("iec958 mode RAW\n");
		} else {	/* ac3,use the same pcm mode as i2s configuration */
			iec958_mode = AIU_958_MODE_PCM_RAW;
			printk("iec958 mode %s\n",
			       (i2s_mode ==
				AIU_I2S_MODE_PCM32) ? "PCM32_RAW" : ((I2S_MODE
								      ==
								      AIU_I2S_MODE_PCM24)
								     ?
								     "PCM24_RAW"
								     :
								     "PCM16_RAW"));
		
}
	} else {
		if (i2s_mode == AIU_I2S_MODE_PCM32)
			iec958_mode = AIU_958_MODE_PCM32;
		else if (i2s_mode == AIU_I2S_MODE_PCM24)
			iec958_mode = AIU_958_MODE_PCM24;
		else
			iec958_mode = AIU_958_MODE_PCM16;
		printk("iec958 mode %s\n",
		       (i2s_mode ==
			AIU_I2S_MODE_PCM32) ? "PCM32" : ((i2s_mode ==
							  AIU_I2S_MODE_PCM24) ?
							 "PCM24" : "PCM16"));
	
}
	if (iec958_mode == AIU_958_MODE_PCM16
	    || iec958_mode == AIU_958_MODE_PCM24
	    || iec958_mode == AIU_958_MODE_PCM32) {
		set.chan_stat->chstat0_l = 0x0100;
		set.chan_stat->chstat0_r = 0x0100;
		set.chan_stat->chstat1_l = 0x200;
		set.chan_stat->chstat1_r = 0x200;
		if (sample_rate == AUDIO_CLK_FREQ_882) {
			
printk("----sample_rate==AUDIO_CLK_FREQ_882---\n");
			set.chan_stat->chstat1_l = 0x800;
			set.chan_stat->chstat1_r = 0x800;
		}

		if (sample_rate == AUDIO_CLK_FREQ_96) {
			
printk("----sample_rate==AUDIO_CLK_FREQ_96---\n");
			set.chan_stat->chstat1_l = 0xa00;
			set.chan_stat->chstat1_r = 0xa00;
		}
		start = buf->addr;
		size = snd_pcm_lib_buffer_bytes(substream);
		audio_set_958outbuf(start, size, runtime->channels, 0);
		/* audio_set_i2s_mode(AIU_I2S_MODE_PCM16); */
		/* audio_set_aiubuf(start, size); */
	} else {

		set.chan_stat->chstat0_l = 0x1902;
		set.chan_stat->chstat0_r = 0x1902;
		if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5) {	/* DD+ */
			if (runtime->rate == 32000) {
				set.chan_stat->chstat1_l = 0x300;
				set.chan_stat->chstat1_r = 0x300;
			} else if (runtime->rate == 44100) {
				set.chan_stat->chstat1_l = 0xc00;
				set.chan_stat->chstat1_r = 0xc00;
			} else {
				set.chan_stat->chstat1_l = 0Xe00;
				set.chan_stat->chstat1_r = 0Xe00;
			}
		} else {	/* DTS,DD */
			if (runtime->rate == 32000) {
				set.chan_stat->chstat1_l = 0x300;
				set.chan_stat->chstat1_r = 0x300;
			} else if (runtime->rate == 44100) {
				set.chan_stat->chstat1_l = 0;
				set.chan_stat->chstat1_r = 0;
			} else {
				set.chan_stat->chstat1_l = 0x200;
				set.chan_stat->chstat1_r = 0x200;
			}
		}
		start = buf->addr;
		size = snd_pcm_lib_buffer_bytes(substream);
		audio_set_958outbuf(start, size, runtime->channels,
				    (iec958_mode == AIU_958_MODE_RAW) ? 1 : 0);
		memset((void *)buf->area, 0, size);
	
}
	ALSA_DEBUG("aiu 958 pcm buffer size %d \n", size);
	audio_set_958_mode(iec958_mode, &set);
	if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5
	    || IEC958_mode_codec == 7 || IEC958_mode_codec == 8) {
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 4, 2);	/* 4x than i2s */
		printk("IEC958_mode_codec/%d  4x than i2s\n",
		       IEC958_mode_codec);
	} else {
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);	/* 512fs divide 4 == 128fs */
#else
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2);	/* 256fs divide 2 == 128fs */
#endif
	}
	if (IEC958_mode_codec == 2) {
		aout_notifier_call_chain(AOUT_EVENT_RAWDATA_AC_3, substream);
	
} else if (IEC958_mode_codec == 3) {
		aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DTS, substream);
	
} else if (IEC958_mode_codec == 4) {
		aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS,
コード例 #3
0
ファイル: aml_pcm.c プロジェクト: rofehr/linux-wetek
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;
}