⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 em8xxx_alsa.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 5 页
字号:
	RMuint32 audio_decoder = EMHWLIB_MODULE(AudioDecoder,audio_decoder_index);	RMuint32 AudioBtsThreshold=AUDIO_BTS_THRESHOLD;		if(!chip->STCStarted){		chip->STCStarted = TRUE;		/* To avoid the DAC to play non-valid data we start/stop the stc in the same time we do a Pause/Play on the AudioDecoder */				EM8XXXSNDGP(pE, audio_decoder, RMAudioDecoderPropertyID_State, &state, sizeof(state));		if(state!=AudioDecoder_State_Playing){			EM8XXXSNDSP(pE,audio_decoder, RMAudioDecoderPropertyID_AudioBtsThreshold, &AudioBtsThreshold,sizeof(RMuint32));			command = AudioDecoder_Command_Play;			EM8XXXSNDSP(pE, audio_decoder, RMAudioDecoderPropertyID_Command, &command, sizeof(command));						if (RMFAILED(err)){				RMDBGLOG((ENABLE, "Error while sending play command to audio decoder! \n"));			}			kc_udelay(100000);					}				// Run STC			speed.nominator = 1;		speed.denominator = 1;				EM8XXXSNDSP(pE, EMHWLIB_MODULE(STC,audio_decoder_index), RMSTCPropertyID_Speed, &speed, sizeof(speed));				if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Error while setting STC speed! \n"));			return err;		}				EM8XXXSNDSP(pE, EMHWLIB_MODULE(STC,audio_decoder_index), RMSTCPropertyID_Play,NULL,0);				if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Error while sending Play command to STC! \n"));			return err;		}				}	return RM_OK;}static int em8xxx_pcm_playback_update (em8xxx_t *chip){	snd_pcm_substream_t *substream = chip->playback_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	/* We send at each interrupt a block which size is equal to period_size.	 Thus, we have to notify the Alsa Pcm middle layer that the period is elapsed, 	and it can the update the appl-ptr. */	playback_update_position(chip);	if(chip->last_count==frames_to_bytes(runtime,runtime->period_size))		snd_pcm_period_elapsed(substream);	return 0;}static int em8xxx_pcm_capture_update (em8xxx_t *chip){	snd_pcm_substream_t *substream = chip->capture_substream;		/* We send at each interrupt a block which size is equal to period_size.	 Thus, we have to notify the Alsa Pcm middle layer that the period is elapsed, 	and it can the update the appl-ptr. */	capture_update_position(chip);	snd_pcm_period_elapsed(substream);	return 0;}static int playback_update_position (em8xxx_t *chip){	int last_ptr,size;	snd_pcm_substream_t *substream = chip->playback_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	last_ptr = chip->hw_ptr+bytes_to_frames(runtime,chip->last_count);	size = last_ptr - chip->hw_ptr;	chip->hw_ptr = last_ptr;	chip->transferred += size;	if (chip->hw_ptr >= (int)runtime->buffer_size)		chip->hw_ptr %= runtime->buffer_size;	return 0;}static int capture_update_position (em8xxx_t *chip){	int last_ptr,size;	snd_pcm_substream_t *substream = chip->capture_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	last_ptr = chip->capture_hw_ptr+runtime->period_size;	size = last_ptr - chip->capture_hw_ptr;	chip->capture_hw_ptr = last_ptr;	chip->capture_transferred += size;	if (chip->capture_hw_ptr >= (int)runtime->buffer_size)		chip->capture_hw_ptr %= runtime->buffer_size;	return 0;}static int send_data_callback(void *pE,RMuint32 bus_address){	struct em8xxxprivate * real_pE = (struct em8xxxprivate *) pE;	em8xxx_t *chip = Stable+(real_pE-Etable);	struct emhwlib_info Info;	struct emhwlib_info *pInfo = &Info;	struct em8xxx_data param;	RMuint32 Info_size;	snd_pcm_substream_t * substream = chip->playback_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	RMstatus err=RM_PENDING;	void * context;	size_t count;	RMDBGLOG((DISABLE,"Send_data_callback\n"));	if (chip->running){		if(bus_address!=0)			em8xxx_pcm_playback_update(chip);		count=frames_to_bytes(runtime,runtime->period_size);		chip->last_count=count;				pInfo = NULL;		Info_size = 0;				param.moduleId = EMHWLIB_MODULE(AudioDecoder,audio_decoder_index);		param.poolId = MAXDMAPOOL;		param.dataSize = count;				param.bus_addr = kc_virt_to_bus((unsigned long)runtime->dma_area+frames_to_bytes(runtime,chip->hw_ptr));				kc_flush_cache((void *) (kc_virt_to_phys((unsigned long)runtime->dma_area+frames_to_bytes(runtime,chip->hw_ptr))), count);		context =(void *) (((real_pE-Etable) << 16) + param.poolId + 1);			// here we are in tasklet mode, so we have to lock for SMP case 		kc_spin_lock(real_pE->lock); 		err=EMhwlibSendBuffer(real_pE->pemhwlib, param.moduleId, param.bus_addr, param.dataSize, pInfo, Info_size, context); 		kc_spin_unlock(real_pE->lock); 	}	return 0;}static RMstatus prepare_data(em8xxx_t *pS){	struct em8xxx_data param;	struct em8xxxprivate *pE = Etable + (pS-Stable);	RMuint8 *buffer=NULL;	RMuint32 timeout = 0;	RMstatus err=RM_OK;	RMuint32 audio_capture = EMHWLIB_MODULE(AudioCapture,audio_capture_index);	struct ReadBufferInfo prop;	RMuint32 nb_buf=0;	while (1) {		timeout=0;			buffer=kdmapool_getbuffer(pE->pllad,pS->capture_dmapool_id,&timeout);						if (buffer==NULL){			break;		}		nb_buf++;			param.moduleId = audio_capture;		param.poolId = pS->capture_dmapool_id;		param.bus_addr = kdmapool_get_bus_address(pE->pllad,pS->capture_dmapool_id,buffer, 0);		param.dataSize = (1<<SERIALIN_DMA_BUFFER_SIZE_LOG2);				prop.address = param.bus_addr;		prop.size = param.dataSize;		prop.context = (void *) ((pE-Etable) + param.poolId + 1);		EM8XXXSNDSP(pE, param.moduleId, RMGenericPropertyID_AddReadBuffer, &prop, sizeof(prop));				buffer=NULL;	}	printk("prepared %ld buffers \n",nb_buf);	return err;	}static RMuint32 receive_data_callback(void *pE,RMuint32 ModuleID,RMuint32 mask){	struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE;	em8xxx_t *chip = Stable + (real_pE-Etable);	RMuint32 status=0;	RMDBGLOG((DISABLE,"receive_data_callabck\n"));	if (mask & SOFT_IRQ_EVENT_XFER_RECEIVE_READY) {		tasklet_schedule(&chip->receive_data_tq);		status |= SOFT_IRQ_EVENT_XFER_RECEIVE_READY;	}	return status;}static void receive_data_interrupt(unsigned long private_data){	em8xxx_t *chip = (em8xxx_t *) private_data;	struct em8xxxprivate *pE = Etable +(chip-Stable);	RMstatus err;	RMuint32 audio_capture = EMHWLIB_MODULE(AudioCapture,audio_capture_index);	struct em8xxx_data param;	void *context;	RMuint8 info[INFO_SIZE];	RMuint32 infoSize = INFO_SIZE;	RMuint32 event_mask;	RMuint32 i,j;	snd_pcm_substream_t * substream = chip->capture_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	struct ReadBufferInfo prop;	/* Clear Event */	RMDBGLOG((ENABLE,"Receive_data_interrupt\n"));	event_mask = SOFT_IRQ_EVENT_XFER_RECEIVE_READY;		// we are in tasklet mode, we have to lock for SMP	kc_spin_lock(pE->lock);	EMhwlibSetProperty(pE->pemhwlib,audio_capture,RMGenericPropertyID_ClearEventMask,&event_mask, sizeof(event_mask));	kc_spin_unlock(pE->lock);	while(1){		if(chip->capture_pBuf==NULL){						/* Receive buffer */			param.moduleId = audio_capture;			param.poolId = chip->capture_dmapool_id;			param.infoSize = infoSize;			printk("receive buffer \n");					// we are in tasklet mode, so we have to lock for SMP			kc_spin_lock(pE->lock);			err=EMhwlibReceiveBuffer(pE->pemhwlib, param.moduleId, &(param.bus_addr), &(param.dataSize), info, &(param.infoSize), &context);			kc_spin_unlock(pE->lock);			if (RMFAILED(err)){				break;			}			chip->capture_buffer_bus_addr = param.bus_addr;			chip->capture_pBuf=kdmapool_get_virt_address(pE->pllad,chip->capture_dmapool_id,chip->capture_buffer_bus_addr, 0);			chip->capture_buffer_size = param.dataSize;			chip->capture_readable = param.dataSize;			chip->i_start=0;		}		else{			chip->i_start=chip->last_i;		}				i=chip->i_start;		j=chip->j_start;				while(j<frames_to_bytes(runtime,runtime->period_size)){			if (i>=chip->capture_buffer_size){				break;			}			switch(chip->state){			case 0:				if(chip->nb_bits_per_sample==8)					runtime->dma_area[(j+frames_to_bytes(runtime,chip->capture_hw_ptr))]=chip->capture_pBuf[i]+128;				else					runtime->dma_area[(j+1+frames_to_bytes(runtime,chip->capture_hw_ptr))]=chip->capture_pBuf[i];				j++;				break;			case 1:				if(chip->nb_bits_per_sample==16){					runtime->dma_area[(j-1+frames_to_bytes(runtime,chip->capture_hw_ptr))]=chip->capture_pBuf[i];					j++;				}				break;			default:				break;			}			i++;			chip->state++;			if(chip->channel_count==1)				chip->state %= 6;			else				chip->state %= 3;		}				chip->last_i = i;		chip->last_j = j;				if(j==frames_to_bytes(runtime,runtime->period_size)){			em8xxx_pcm_capture_update(chip);			chip->j_start=0;		}		else{			chip->j_start=chip->last_j;		}				if (i>=chip->capture_buffer_size){					prop.address = chip->capture_buffer_bus_addr;			prop.size = chip->capture_buffer_size;			prop.context = (void *) ((pE-Etable) + chip->capture_dmapool_id + 1);			printk("add read buffer \n");			//we are in tasklet mode, so we have to lock for SMP			kc_spin_lock(pE->lock);			EMhwlibSetProperty(pE->pemhwlib, param.moduleId, RMGenericPropertyID_AddReadBuffer, &prop, sizeof(prop));			kc_spin_unlock(pE->lock);			chip->capture_pBuf = NULL;		}	}	return;}static int snd_em8xxx_free_ptr(struct em8xxxprivate *pE,RMuint32 ptr){	RMuint32 dramIndex=0xffffffff;	RMstatus err;		if ((MEM_BASE_dram_controller_0<=ptr)&&(ptr<MEM_BASE_dram_controller_1)) dramIndex=0;	if ((MEM_BASE_dram_controller_1<=ptr)&&(ptr<MEM_BASE_dram_controller_1+(512*1024*1024))) dramIndex=1;	if (dramIndex<=1) {		EM8XXXSNDSP(pE,			    EMHWLIB_MODULE(MM,dramIndex),			    RMMMPropertyID_Free,			    (void *)(&ptr),sizeof(void *));		if(err!=RM_OK) 			RMDBGLOG((ENABLE,"rm_ptr_free: pointer 0x%08lx cannot be freed\n",ptr));	}	else		RMDBGLOG((ENABLE,"rm_ptr_free: pointer %p not in a dram controller\n",ptr));		return 0;}static void em8xxx_playback_stop_interrupt(unsigned long private_data){	em8xxx_t *chip = (em8xxx_t *) private_data;	struct em8xxxprivate *pE = Etable +(chip-Stable);	RMstatus err;/* 	enum AudioDecoder_Command_type command; */	RMDBGLOG((DISABLE,"em8xxx_playback_stop_interrupt\n"));	krua_unregister_sendcomplete_callback(pE);/* 	command = AudioDecoder_Command_Pause; *//* 	EM8XXXSNDSP(pE, EMHWLIB_MODULE(AudioDecoder,audio_decoder_index), RMAudioDecoderPropertyID_Command, &command, sizeof(command)); */	chip->transferred=0;	chip->STCStarted=FALSE;	EM8XXXSNDSP(pE,EMHWLIB_MODULE(STC,audio_decoder_index),RMSTCPropertyID_Stop, NULL,0);}static void em8xxx_capture_stop_interrupt(unsigned long private_data){	em8xxx_t *chip = (em8xxx_t *) private_data;	struct em8xxxprivate *pE = Etable +(chip-Stable);	enum AudioCapture_Capture_type cmd;	RMstatus err;		RMDBGLOG((DISABLE,"em8xxx_capture_stop_interrupt\n"));	krua_unregister_event_callback(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),receive_data_callback);	//  Disabling audio capture	cmd = AudioCapture_Capture_Off;	EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),RMAudioCapturePropertyID_Capture, &cmd, sizeof(cmd));}static void em8xxx_playback_setaudio_interrupt(unsigned long private_data){	em8xxx_t *chip = (em8xxx_t *) private_data;	snd_pcm_substream_t * substream = chip->playback_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	RMDBGLOG((DISABLE,"em8xxx_playback_setaudio_interrupt\n"));		if (!chip->prepared) {		chip->hw_ptr=0;		chip->appl_ptr=0;		chip->format = AudioDecoder_Codec_PCM;		chip->nb_bits_per_sample = runtime->sample_bits;		chip->MSBFirst = FALSE;		chip->sample_rate = runtime->rate;		chip->channel_count = runtime->channels;		set_audio_parameters(chip);		prepare_audio_decoder(chip);		start_stc(chip);	}	return;}static void em8xxx_capture_setaudio_interrupt(unsigned long private_data){	em8xxx_t *chip = (em8xxx_t *) private_data;	snd_pcm_substream_t * substream = chip->capture_substream;	snd_pcm_runtime_t *runtime = substream->runtime;	RMDBGLOG((DISABLE,"em8xxx_capture_setaudio_interrupt\n"));	if (!chip->prepared) {		chip->capture_hw_ptr=0;		chip->capture_appl_ptr=0;		chip->format = AudioDecoder_Codec_PCM;		chip->nb_bits_per_sample = runtime->sample_bits;		chip->MSBFirst = FALSE;		chip->sample_rate = runtime->rate;		chip->channel_count = runtime->channels;		printk("em8xxx_capture_setaudio_interrupt chip = %p \n",chip);		set_audio_parameters(chip);	}	return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -