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

📄 vxsound.cpp

📁 devloped under vxwork, support ess sound card. driver library, include datasheet.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/****************************************************************** MODULE:		VxSound.cpp** DESCRIPTION: 	A framework for porting ALSA library sound card drivers*				to VxWorks.*				* ORIGINAL AUTHOR: 	Dan Walkes - with lots of influence from GNU ALSA*					library files and linux sound driver code.*					* UPDATED BY:		* * CREATED:		Oct, 2005* MODIFIED:		* * NOTES:**	In most cases, functions without a vx_ prefix were taken from the ALSA library*	files and modified little (if any) to work with VxWorks.  Functions starting with a*	vx_ were changed significantly to support VxWorks instead of linux.** CODE USAGE:*	See references** REVISION HISTORY AND NOTES:** Date			Update* ---------------------------------------------------------------------* Oct 1, 2005	Created.** REFERENCES:** 1) "vxWALSA Sound Driver" document included with this release.*****************************************************************/#include "vxworks.h"#include "stdlib.h"#include <stdio.h>#include <string.h>/* Vxworks -linux includes */#include "VxTypes.h"#include "VxPCI.h"#include "VxSound.h"#include "es1938.h"			  /*--------------------------------------------------------------	Global Variables----------------------------------------------------------------*/static int maximum_substreams = 4;uint32 snd_interrupt=0;snd_card_t	*psndCard;static int preallocate_dma = 1;/* variables for debugging/reference */pci_dev *pGlobPCIDev;snd_pcm_substream_t *gplayback;/* include application .h files here */#include "vx_tone_ap.h"/* a structure with sound applications.. replace with your application.	See vx_tone_ap for more information */vx_snd_application	sndAp ={	{	TONE_PLAYBACK_PRIORITY, toneApPlaybackTaskInit },	// playback params	{	0	}	// capture params};/*--------------------------------------------------------------	Function Prototypes----------------------------------------------------------------*/static int snd_pcm_free(snd_pcm_t *pcm);static int snd_pcm_lib_preallocate_pages1(snd_pcm_substream_t *substream,					  size_t size, size_t max);static int vx_snd_pcm_substream_proc_done( snd_pcm_substream_t *substream );static int vx_snd_pcm_substream_proc_init( snd_pcm_substream_t *substream );/*--------------------------------------------------------------	Function Description:		Allocates a new snd_card_t structure based on the passed parameters		This function was taken directly from the ALSA library and includes lots		of stuff specific to Linux in the  VXWORKS_UNUSED compile-switched section.		Basically all this function does now is allocate the snd_card_t structure		and initialize members.		Call snd_card_free to free this structure.		Arguments:		int idx - not used		const char *xid - not used		void *module - not used		int extra size - extra size allocated within the sound card structure		Returns:		snd_card_t * the new card or NULL if failure		---------------------------------------------------------------*/snd_card_t *snd_card_new( int idx, const char *xid, void *module, int extra_size){		snd_card_t *card;	int err;	if (extra_size < 0)		extra_size = 0;	card = (snd_card_t *) kcalloc(1, sizeof(*card) + extra_size, GFP_KERNEL);	if (card == NULL)		return NULL;	card->private_free = NULL;	return card;	/* note.. eventually may need to do some of the stuff below */		#if VXWORKS_UNUSED	if (xid) {		if (!snd_info_check_reserved_words(xid))			goto __error;		strlcpy(card->id, xid, sizeof(card->id));	}	err = 0;	write_lock(&snd_card_rwlock);	if (idx < 0) {		int idx2;		for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)			if (~snd_cards_lock & idx & 1<<idx2) {				idx = idx2;				if (idx >= snd_ecards_limit)					snd_ecards_limit = idx + 1;				break;			}	} else if (idx < snd_ecards_limit) {		if (snd_cards_lock & (1 << idx))			err = -ENODEV;	/* invalid */	} else if (idx < SNDRV_CARDS)		snd_ecards_limit = idx + 1; /* increase the limit */	else		err = -ENODEV;	if (idx < 0 || err < 0) {		write_unlock(&snd_card_rwlock);		snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1);		goto __error;	}	snd_cards_lock |= 1 << idx;		/* lock it */	write_unlock(&snd_card_rwlock);	card->number = idx;	card->module = module;	INIT_LIST_HEAD(&card->devices);	init_rwsem(&card->controls_rwsem);	rwlock_init(&card->ctl_files_rwlock);	INIT_LIST_HEAD(&card->controls);	INIT_LIST_HEAD(&card->ctl_files);	spin_lock_init(&card->files_lock);	init_waitqueue_head(&card->shutdown_sleep);	INIT_WORK(&card->free_workq, snd_card_free_thread, card);#ifdef CONFIG_PM	init_MUTEX(&card->power_lock);	init_waitqueue_head(&card->power_sleep);#endif	/* the control interface cannot be accessed from the user space until */	/* snd_cards_bitmask and snd_cards are set with snd_card_register */	if ((err = snd_ctl_create(card)) < 0) {		snd_printd("unable to register control minors\n");		goto __error;	}	if ((err = snd_info_card_create(card)) < 0) {		snd_printd("unable to create card info\n");		goto __error_ctl;	}	if (extra_size > 0)		card->private_data = (char *)card + sizeof(snd_card_t);	return card;      __error_ctl:	snd_device_free_all(card, SNDRV_DEV_CMD_PRE);      __error:	kfree(card);      	return NULL;#endif}/*--------------------------------------------------------------	Function Description:		Frees a snd_card_t structure.  This function has been modified		to call a private free function and assumes a pci structure (frees the pci 		structure as well.) 		Arguments:		snd_card_t *pcard - a pointer to the snd_card_t structure to free		Returns:---------------------------------------------------------------*/void snd_card_free( snd_card_t *pcard ){	if( pcard->pcm )	{		snd_pcm_free( pcard->pcm );	}	if( pcard->private_free )	{		( *pcard->private_free )(pcard);	}	kfree( pcard );}/*--------------------------------------------------------------	Function Description:		Frees the DMA area in the substream.. if one was allocated.		Arguments:		snd_pcm_substream_t *substream - a pointer to the substream for which to free the			DMA area		Returns:---------------------------------------------------------------*/static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream){	if (substream->dma_buffer.area == NULL)		return;#if VX_BUILD_UNUSED		/* add later.. actually do the mem free */	if (substream->dma_buf_id)		snd_dma_reserve_buf(&substream->dma_buffer, substream->dma_buf_id);	else		snd_dma_free_pages(&substream->dma_buffer);#else	free( substream->dma_buffer.area );#endif	substream->dma_buffer.area = NULL;}/** * snd_pcm_lib_preallocate_free - release the preallocated buffer of the specified substream. * @substream: the pcm substream instance * * Releases the pre-allocated buffer of the given substream. * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_lib_preallocate_free(snd_pcm_substream_t *substream){	snd_pcm_lib_preallocate_dma_free(substream);#if VX_BUILD_NO_INCLUDE	if (substream->proc_prealloc_entry) {		snd_info_unregister(substream->proc_prealloc_entry);		substream->proc_prealloc_entry = NULL;	}#endif	return 0;}/** * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm * @pcm: the pcm instance * * Releases all the pre-allocated buffers on the given pcm. * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_lib_preallocate_free_for_all(snd_pcm_t *pcm){	snd_pcm_substream_t *substream;	int stream;	for (stream = 0; stream < 2; stream++)		for (substream = pcm->streams[stream].substream; substream; substream = substream->next)			snd_pcm_lib_preallocate_free(substream);	return 0;}/** * snd_pcm_set_ops - set the PCM operators * @pcm: the pcm instance * @direction: stream direction, SNDRV_PCM_STREAM_XXX * @ops: the operator table * * Sets the given PCM operators to the pcm instance. */void snd_pcm_set_ops(snd_pcm_t *pcm, int direction, snd_pcm_ops_t *ops){	snd_pcm_str_t *stream = &pcm->streams[direction];	snd_pcm_substream_t *substream;		for (substream = stream->substream; substream != NULL; substream = substream->next)		substream->ops = ops;}/** * snd_pcm_new_stream - create a new PCM stream * @pcm: the pcm instance * @stream: the stream direction, SNDRV_PCM_STREAM_XXX * @substream_count: the number of substreams * * Creates a new stream for the pcm. * The corresponding stream on the pcm must have been empty before * calling this, i.e. zero must be given to the argument of * snd_pcm_new(). * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count){	int idx, err;	snd_pcm_str_t *pstr = &pcm->streams[stream];	snd_pcm_substream_t *substream, *prev;#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)	init_MUTEX(&pstr->oss.setup_mutex);#endif	pstr->stream = stream;	pstr->pcm = pcm;	pstr->substream_count = substream_count;#if VX_BUILD_NO_INCLUDE	if (substream_count > 0) {		err = snd_pcm_stream_proc_init(pstr);		if (err < 0)			return err;	}	pstr->reg = &snd_pcm_reg[stream];#endif	prev = NULL;	for (idx = 0, prev = NULL; idx < substream_count; idx++) {		substream = (snd_pcm_substream_t *) kcalloc(1, sizeof(*substream), GFP_KERNEL);		if (substream == NULL)			return -ENOMEM;		substream->pcm = pcm;		substream->pstr = pstr;		substream->number = idx;		substream->stream = stream;		sprintf(substream->name, "subdevice #%i", idx);		substream->buffer_bytes_max = UINT_MAX;		/* note: not sure where this is done in linux.. but it seems like it should work			to allocate here */		substream->runtime = (snd_pcm_runtime_t *)kcalloc( 1, sizeof(snd_pcm_runtime_t), 0 );		if( substream->runtime == NULL )		{			kfree( substream );			return -ENOMEM;		}		if (prev == NULL)			pstr->substream = substream;		else			prev->next = substream;		/* create an empty semaphore to show when the dma period has elapsed */		err = snd_pcm_substream_proc_init(substream);		if (err < 0) {			kfree(substream->runtime);			kfree(substream);			return err;		}#if VX_BUILD_NO_INCLUDE		substream->group = &substream->self_group;		spin_lock_init(&substream->self_group.lock);		INIT_LIST_HEAD(&substream->self_group.substreams);		list_add_tail(&substream->link_list, &substream->self_group.substreams);		spin_lock_init(&substream->timer_lock);#endif		prev = substream; 	}	return 0;}/*--------------------------------------------------------------	Function Description:		Allocates memory space of the passed size for DMA access for the		specified substream and fills in parameters in the structure with		DMA address/sizes		Arguments:		snd_pcm_substream_t *substream - a pointer to the substream for which to free the			DMA area		Returns:	 	0 on success		negative on failure---------------------------------------------------------------*/static int vx_preallocate_pcm_pages(snd_pcm_substream_t *substream,size_t size ){	struct snd_dma_buffer *dmab = &substream->dma_buffer;	int err;	snd_assert(size > 0, return -EINVAL);		dmab->bytes = size;	dmab->addr = (uint32) vx_pci_get_next_dma_mem_space_align( size ); 

⌨️ 快捷键说明

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