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

📄 em8xxx_alsa.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 5 页
字号:
static void em8xxx_playback_start_interrupt(unsigned long private_data){	em8xxx_t *chip = (em8xxx_t *) private_data;	struct em8xxxprivate *pE = Etable +(chip-Stable);	RMDBGLOG((DISABLE,"em8xxx_playback_start_interrupt\n"));		/*Even if the pcm instance is already close, there might still be interruptions.	 This avoid to enter non-valid code.*/	if(chip->pcm_open_count==0)		return;	if(pE->data_callback==NULL)		krua_register_sendcomplete_callback(pE, send_data_callback);	send_data_callback(pE,0);}static void em8xxx_capture_start_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_start_interrupt\n"));	/*Even if the pcm instance is already close, there might still be interruptions.	 This avoid to enter non-valid code.*/	if(chip->pcm_open_count==0)		return;	krua_register_event_callback(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),SOFT_IRQ_EVENT_XFER_RECEIVE_READY,receive_data_callback);	//  Enabling audio capture	cmd = AudioCapture_Capture_On;		EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),RMAudioCapturePropertyID_Capture, &cmd, sizeof(cmd));		receive_data_callback(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),SOFT_IRQ_EVENT_XFER_RECEIVE_READY);}static int snd_em8xxx_playback_open(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	RMDBGLOG((DISABLE,"em8xxx_playback_open\n"));	chip->playback_substream = substream;	runtime->hw = snd_em8xxx_playback;	chip->position = 0;	chip->transferred = 0;	chip->hw_ptr = 0;	chip->appl_ptr=0;	chip->pcm_open_count++;		open_audio_decoder(chip);	return 0;}static int snd_em8xxx_capture_open(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	RMDBGLOG((DISABLE,"em8xxx_capture_open_interrupt\n"));	chip->capture_substream = substream;	runtime->hw = snd_em8xxx_capture;	chip->capture_hw_ptr = 0;	chip->capture_appl_ptr=0;	chip->i_start=0;	chip->j_start=0;	chip->last_i=0;	chip->last_j=0;	chip->state = 0;	chip->capture_pBuf=NULL;	chip->pcm_open_count++;			open_audio_capture(chip);	return 0;}static int snd_em8xxx_playback_close(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	struct em8xxxprivate *pE = Etable + (chip-Stable);	RMuint32 profile;	RMstatus err;		printk("snd_em8xxx_playback_close \n");	chip->pcm_open_count--;	krua_unregister_sendcomplete_callback(pE);	chip->playback_substream = NULL;	chip->format = 0;	chip->sample_rate = 0;	chip->channel_count = 0;	chip->prepared = FALSE;			// close audio profile	profile=0;	EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioDecoder,audio_decoder_index), RMAudioDecoderPropertyID_Close, &profile, sizeof(profile));		// free resources	snd_em8xxx_free_ptr (pE,chip->AudioProfileCachedAddr);	snd_em8xxx_free_ptr (pE,chip->AudioProfileUncachedAddr);        	// stop stc 		chip->firstPTS = TRUE;	EM8XXXSNDSP(pE,EMHWLIB_MODULE(STC,audio_decoder_index),RMSTCPropertyID_Close, NULL,sizeof(RMuint32));	if (EMHWLIB_MODULE(AudioDecoder,audio_decoder_index) != 0) {		/* Free the audio shared memory per engine */		RMstatus err;		RMuint32 connected_task_count;		EM8XXXSNDGP(pE, EMHWLIB_MODULE(AudioEngine,audio_engine_index), RMAudioEnginePropertyID_ConnectedTaskCount, 					&connected_task_count, sizeof(connected_task_count));		if (err != RM_OK) {			RMDBGLOG((ENABLE, "Cannot get RMAudioEnginePropertyID_ConnectedTaskCount %lu\n", EMHWLIB_MODULE(AudioEngine,audio_engine_index)));			return err;                                                         		}		if (connected_task_count == 0) {			struct AudioEngine_DecoderSharedMemory_type shared;			RMuint32 address;			EM8XXXSNDGP(pE, EMHWLIB_MODULE(AudioEngine,audio_engine_index), RMAudioEnginePropertyID_DecoderSharedMemory,					     &shared, sizeof(shared));				if (err != RM_OK) {				RMDBGLOG((ENABLE, "Cannot get DecoderSharedMemory0\n"));				return err;			}			if (shared.Address) {				RMDBGLOG((ENABLE, "FREE %lx_DRAM AUDIO SHARED MEMORY addr=0x%lx size=0x%lx!\n",					  audio_decoder_index, shared.Address, shared.Size));				address = shared.Address;				shared.Address = 0;				shared.Size = 0;								EM8XXXSNDSP(pE, EMHWLIB_MODULE(AudioEngine,audio_engine_index), RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared));				snd_em8xxx_free_ptr (pE, address);			}		}		else {			RMDBGLOG((ENABLE, "CANNOT FREE AUDIO SHARED MEMORY. There are still %lx audio tasks opened. \n",				  connected_task_count));		}	}	return 0;}static int snd_em8xxx_capture_close(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	struct em8xxxprivate *pE = Etable + (chip-Stable);	RMuint32 profile;	RMstatus err;	RMDBGLOG((DISABLE,"em8xxx_capture_close\n"));	chip->pcm_open_count--;	krua_unregister_event_callback(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),receive_data_callback);	chip->playback_substream = NULL;	chip->format = 0;	chip->sample_rate = 0;	chip->channel_count = 0;	chip->prepared = FALSE;	// close audio capture profile	profile=0;	EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index), RMAudioCapturePropertyID_Close, &profile, sizeof(profile));	// close dma pool	kdmapool_close(pE->pllad,chip->capture_dmapool_id);		// free resources	snd_em8xxx_free_ptr (pE,chip->SerialinProfileCachedAddr);	snd_em8xxx_free_ptr (pE,chip->SerialinProfileUncachedAddr);	return 0;}static int snd_em8xxx_pcm_hw_params(snd_pcm_substream_t *substream,				    snd_pcm_hw_params_t * hw_params){	int err;	/* In this callback the Alsa Pcm middle layer allocate the memory for the dmapool  */	RMDBGLOG((DISABLE,"snd_em8xxx_pcm_hw_params\n"));	if ((err = snd_pcm_lib_malloc_pages(substream,32*(1024))) < 0)		return err;	return 0;}static int snd_em8xxx_pcm_hw_free(snd_pcm_substream_t *substream){		return snd_pcm_lib_free_pages(substream);}static int snd_em8xxx_playback_prepare(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	RMDBGLOG((DISABLE,"snd_em8xxx_playback_prepare\n"));	/* HACK : change stop threshold to avoid xrun*/	substream->runtime->stop_threshold *=2;	/*For backward compatibility, it is better to schedule a tasklet here, 	  because this callback might be atomic, and we can't lock. */	tasklet_hi_schedule(&chip->playback_setaudio_tq);	return 0;}static int snd_em8xxx_capture_prepare(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	RMDBGLOG((DISABLE,"snd_em8xxx_capture_prepare\n"));/* 	/\*For backward compatibility, it is better to schedule a tasklet here,  *//* 	  because this callback might be atomic, and we can't lock. *\/ */	tasklet_schedule(&chip->capture_setaudio_tq);	return 0;}static int snd_em8xxx_playback_trigger(snd_pcm_substream_t * substream,				       int cmd){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	RMDBGLOG((DISABLE,"snd_em8xxx_playback_trigger\n"));	switch (cmd) {	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:	case SNDRV_PCM_TRIGGER_START:		chip->running=TRUE;		/* We have to schedule this tasklet with the lowest priority,		   unless the em8xxx tasklet that process the 		   state change will probably not be processed */		tasklet_schedule(&chip->playback_start_tq);		break;	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:	case SNDRV_PCM_TRIGGER_STOP:		chip->running=FALSE;		tasklet_schedule(&chip->playback_stop_tq);		break;	default:		return -EINVAL;	}	return 0;}static int snd_em8xxx_capture_trigger(snd_pcm_substream_t * substream,				       int cmd){	em8xxx_t *chip = snd_pcm_substream_chip(substream);		RMDBGLOG((DISABLE,"snd_em8xxx_capture_trigger\n"));	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:		chip->running=TRUE;		/* We have to schedule this tasklet with the lowest priority,		   unless the em8xxx tasklet that process the 		   state change will probably not be processed */		tasklet_schedule(&chip->capture_start_tq);		break;	case SNDRV_PCM_TRIGGER_STOP:		chip->running=FALSE;		tasklet_hi_schedule(&chip->capture_stop_tq);		break;	default:		return -EINVAL;	}	return 0;}static snd_pcm_uframes_t snd_em8xxx_playback_pointer(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	return chip->hw_ptr;}static snd_pcm_uframes_t snd_em8xxx_capture_pointer(snd_pcm_substream_t * substream){	em8xxx_t *chip = snd_pcm_substream_chip(substream);	return chip->capture_hw_ptr;}static int snd_em8xxx_playback_ack(snd_pcm_substream_t * substream){	snd_pcm_runtime_t *runtime = substream->runtime;	em8xxx_t *chip = snd_pcm_substream_chip(substream);	/*This callback is used to track the current appl_ptr. It is called from the Alsa Pcm	 middle layer when it updates the appl_ptr after a write operation.*/	chip->appl_ptr=runtime->control->appl_ptr;	return 0;}static int snd_em8xxx_capture_ack(snd_pcm_substream_t * substream){	snd_pcm_runtime_t *runtime = substream->runtime;	em8xxx_t *chip = snd_pcm_substream_chip(substream);	/*This callback is used to track the current appl_ptr. It is called from the Alsa Pcm	 middle layer when it updates the appl_ptr after a read operation.*/	chip->capture_appl_ptr=runtime->control->appl_ptr;	return 0;}static void snd_em8xxx_free_pcm(snd_pcm_t *pcm){	em8xxx_t *chip = pcm->private_data;	struct em8xxxprivate *pE = Etable + (chip - Stable);		snd_em8xxx_free_ptr (pE,chip->AudioUCodeAddr);	snd_pcm_lib_preallocate_free_for_all(pcm);}static int __devinit snd_em8xxx_new_pcm(em8xxx_t *chip, int device, snd_pcm_t ** rpcm){	snd_pcm_t *pcm;	int err;	if (rpcm)		*rpcm = NULL;	if ((err = snd_pcm_new(chip->card, "em8xxx", device, 2, 1, &pcm)) < 0)		return err;		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_em8xxx_playback_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em8xxx_capture_ops);	pcm->private_data = chip;	pcm->private_free = snd_em8xxx_free_pcm;	pcm->info_flags = 0;	strcpy(pcm->name, "EM8xxx");	/*This fonction preallocate a big area of memory to make contiguous buffers	 in hw_params callback.*/	#if EM86XX_MODE==EM86XX_MODEID_STANDALONE	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,					      snd_dma_continuous_data(GFP_KERNEL), 32*1024, 32*1024);#else	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(chip->pci), 32*1024, 32*1024);#endif	init_audio(chip);		if (rpcm)		*rpcm = pcm;	return 0;}/************************************************************************ *********                    LOW LEVEL DRIVER                   ******** ************************************************************************/static int snd_em8xxx_free(em8xxx_t *chip){	return 0;}static int snd_em8xxx_dev_free(snd_device_t *device){	em8xxx_t *chip = (em8xxx_t *) device->device_data;	return snd_em8xxx_free(chip);}#if EM86XX_MODE==EM86XX_MODEID_STANDALONEstatic int __devinit snd_em8xxx_create(snd_card_t * card,em8xxx_t * chip)#elsestatic int __devinit snd_em8xxx_create(snd_card_t * card,struct pci_dev * pci,em8xxx_t * chip)#endif{	int err;	static snd_device_ops_t ops = {		.dev_free =	snd_em8xxx_dev_free,	};		chip->card = card;#if EM86XX_MODE==EM86XX_MODEID_WITHHOST	chip->pci = pci;#endif	 	chip->sndprivate_active = 1; 	init_waitqueue_head(&chip->sound_queue);	tasklet_init(&chip->playback_start_tq,em8xxx_playback_start_interrupt,(unsigned long) chip);	tasklet_init(&chip->playback_setaudio_tq,em8xxx_playback_setaudio_interrupt,(unsigned long) chip);	tasklet_init(&chip->playback_stop_tq,em8xxx_playback_stop_interrupt,(unsigned long) chip);	tasklet_init(&chip->capture_start_tq,em8xxx_capture_start_interrupt,(unsigned long) chip);	tasklet_init(&chip

⌨️ 快捷键说明

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