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

📄 atlasii_dll.c

📁 Centrality Atlas II development software
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $QNXLicenseC:  * Copyright 2007,2008, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $  */#include <atlasii.h>#define	TIMEOUT_LOOPS	1000000static voidatlasii_codec_write (atlasii_t * atlasii, uint16_t reg, uint16_t val){	unsigned long timeout = 0;	ado_mutex_lock (&atlasii->hw_lock);	atlasii->ac97_ctrl->rCMD = ((val << 16) | ((reg & 0x7f) << 8));	// set CODEC_AC97_COMMAND register	atlasii->ac97_ctrl->rCTRL |= 0xe000;				   //set CODEC_AC97_CONTROL register	ado_mutex_unlock (&atlasii->hw_lock);	while (atlasii->ac97_ctrl->rCTRL & 0x4000)			   //check bit 14(tag bit of slot 1)	{		delay (1);		if (timeout++ > TIMEOUT_LOOPS)		{			ado_error ("CODEC Write failed: time out!!!!!");			break;		}	}													   //check bit 14(tag bit of slot 1)}static  uint16_tatlasii_codec_read (atlasii_t * atlasii, uint16_t reg){	uint16_t temp;	unsigned long timeout = 0;	uint32_t readValue;	uint16_t readReg = 0xffff;	ado_mutex_lock (&atlasii->hw_lock);	atlasii->ac97_ctrl->rCMD = 0x0000ffff & (((reg & 0x7f) << 8) | 0x8000);	// set CODEC_AC97_COMMAND register	do	{		atlasii->ac97_ctrl->rREG_OK = 0x01;		atlasii->ac97_ctrl->rCTRL |= 0xc000;		usleep (30);		if (atlasii->ac97_ctrl->rREG_OK & 0x1)		{			readValue = atlasii->ac97_ctrl->rSTATUS;			readReg = ((readValue & 0xffff) >> 8);		}		if (timeout++ > TIMEOUT_LOOPS)		{			ado_error ("CODEC Read failed: time out!!!!!");			break;		}	}	while (readReg != reg);	temp = (atlasii->ac97_ctrl->rSTATUS) >> 16;	ado_mutex_unlock (&atlasii->hw_lock);	return (temp);}static  int32_tatlasii_codec_init (atlasii_t * atlasii){	/* Set line out jack source to be headphone mixer */	atlasii_codec_write (atlasii, 0x16, 0x8100);	/* Set Line In as default capture source */	atlasii_codec_write (atlasii, 0x1A, (atlasii_codec_read (atlasii,				0x1A) & (0x7000)) | (4 << 8) | 4);	atlasii_codec_write (atlasii, 0x14, 0x9f1f);	return (0);}static voidatlasii_frag_dmabuf_sizer (atlasii_t * atlasii, ado_pcm_config_t * config,	ado_pcm_subchn_t * subchn){	int32_t result, frag_size;	frag_size = ado_pcm_dma_int_size (config);	result = (frag_size / 16) * 16;	if (config->trans_mode == SND_PCM_MODE_BLOCK)	{		config->mode.block.frag_size = result;		config->dmabuf.size = config->mode.block.frags_total * config->mode.block.frag_size;	}	else	{		config->mode.stream.queue_size = result;		config->dmabuf.size = config->mode.stream.queue_size;	}}int32_tatlasii_capabilities (HW_CONTEXT_T * atlasii, snd_pcm_channel_info_t * info){	int     chn_avail = 1;	if (info->channel == SND_PCM_CHANNEL_PLAYBACK && atlasii->play_strm.pcm_subchn)		chn_avail = 0;	else if (info->channel == SND_PCM_CHANNEL_CAPTURE && atlasii->cap_strm.pcm_subchn)		chn_avail = 0;	if (chn_avail == 0)	{		info->formats = 0;		info->rates = 0;		info->min_rate = 0;		info->max_rate = 0;		info->min_voices = 0;		info->max_voices = 0;		info->min_fragment_size = 0;		info->max_fragment_size = 0;	}	return (0);}int32_tatlasii_playback_aquire (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T ** pc,	ado_pcm_config_t * config, ado_pcm_subchn_t * subchn, uint32_t * why_failed){	if (atlasii->play_strm.pcm_subchn)	{		*why_failed = SND_PCM_PARAMS_NO_CHANNEL;		return (EAGAIN);	}	ado_mutex_lock (&atlasii->hw_lock);	atlasii_frag_dmabuf_sizer (atlasii, config, subchn);	if ((config->dmabuf.addr = ado_shm_alloc (config->dmabuf.size,				config->dmabuf.name, ADO_SHM_DMA_SAFE, &config->dmabuf.phys_addr)) == NULL)	{		ado_mutex_unlock (&atlasii->hw_lock);		return (errno);	}	//set xmit DMA	atlasii->common_dma->rWIDTH0 = (ado_pcm_dma_int_size (config) / 64);	atlasii->play_strm.dma->rXLEN = 0x0;	atlasii->play_strm.dma->rYLEN = 0x1f;				   //32 lines	atlasii->play_strm.dma->rCTRL = 0xC;				   //width 0, SDRAM to FIFO, BURST MODE	atlasii->common_dma->rCH_LOOP_CTRL &=		~((1 << atlasii->play_strm.dma_ch) | (1 << (atlasii->play_strm.dma_ch + 16)));	atlasii->common_dma->rCH_VALID |= (1 << atlasii->play_strm.dma_ch);	//stophe channel	atlasii->common_dma->rCH_INT = (1 << atlasii->play_strm.dma_ch);	//clear DMA status	//set ac97 controller regs	//enable ac97 DA_channel	atlasii->ac97_ctrl->rTX_FIFO_INT_EN = 0x0;			   //disable overrun underrun interrupt	atlasii->ac97_ctrl->rTX_DMA_IO_CTRL = 0;			   //DMA_FLUSH	atlasii->ac97_ctrl->rTX_FIFO_CTRL = 2;	atlasii->ac97_ctrl->rTX_FIFO_LEVEL_CHK = ((0x0c) | (0x08 << 10) | (0x04 << 20));	atlasii->ac97_ctrl->rTX_FIFO_OP = 2;				   //reset FIFO	atlasii->ac97_ctrl->rTX_FIFO_STS |= 0xC;			   //clear intr status	if (config->format.voices == 1)	{		atlasii->ac97_ctrl->rCTRL &= ~(1 << 0);			   // Disable Right channel		atlasii->ac97_ctrl->rCTRL &= ~(0x1 << 11);		   // Disable slot 4 (right channel) 	}	else	{		atlasii->ac97_ctrl->rCTRL |= (1 << 0);			   // Enable right channel		atlasii->ac97_ctrl->rCTRL |= (0x13 << 11);		   // Enable slot 3(left), 4(right), and set frame valid	}	atlasii->mixer_cb.SRC_set (atlasii->mixer_cb.mix_context, AC97_FRONT_DAC_SRC,		&config->format.rate);	atlasii->play_strm.pcm_config = config;	atlasii->play_strm.pcm_subchn = *pc = subchn;	ado_mutex_unlock (&atlasii->hw_lock);	return (EOK);}int32_tatlasii_playback_release (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc,	ado_pcm_config_t * config){	ado_mutex_lock (&atlasii->hw_lock);	atlasii->play_strm.pcm_subchn = NULL;	ado_shm_free (config->dmabuf.addr, config->dmabuf.size, config->dmabuf.name);	ado_mutex_unlock (&atlasii->hw_lock);	return (EOK);}int32_tatlasii_capture_aquire (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T ** pc,	ado_pcm_config_t * config, ado_pcm_subchn_t * subchn, uint32_t * why_failed){	if (atlasii->cap_strm.pcm_subchn)	{		*why_failed = SND_PCM_PARAMS_NO_CHANNEL;		return (EAGAIN);	}	ado_mutex_lock (&atlasii->hw_lock);	atlasii_frag_dmabuf_sizer (atlasii, config, subchn);	if ((config->dmabuf.addr = ado_shm_alloc (config->dmabuf.size,				config->dmabuf.name, ADO_SHM_DMA_SAFE, &config->dmabuf.phys_addr)) == NULL)	{		ado_mutex_unlock (&atlasii->hw_lock);		return (errno);	}	//set RCV DMA	atlasii->common_dma->rWIDTH1 = (ado_pcm_dma_int_size (config) / 64);	atlasii->cap_strm.dma->rXLEN = 0x0;	atlasii->cap_strm.dma->rYLEN = 0x1f;				   //32lines	atlasii->cap_strm.dma->rCTRL = 0x9;					   //width 1,  FIFO to SDRAM, BURST MODE	atlasii->common_dma->rCH_LOOP_CTRL &=		~((1 << atlasii->cap_strm.dma_ch) | (1 << (atlasii->cap_strm.dma_ch + 16)));	atlasii->common_dma->rCH_VALID |= (1 << atlasii->cap_strm.dma_ch);	//stophe channel	atlasii->common_dma->rCH_INT = (1 << atlasii->cap_strm.dma_ch);	//clear DMA status	//set ac97 controller regs	//enable ac97 AD_channel	atlasii->ac97_ctrl->rRX_FIFO_INT_EN = 0x0;			   //disable overrun underrun interrupt	atlasii->ac97_ctrl->rRX_DMA_IO_CTRL = 6;			   //DMA_FLUSH	atlasii->ac97_ctrl->rRX_FIFO_CTRL = 2;	atlasii->ac97_ctrl->rRX_FIFO_LEVEL_CHK = ((0x04) | (0x08 << 10) | (0x0c << 20));	atlasii->ac97_ctrl->rRX_FIFO_OP = 2;				   //reset FIFO	atlasii->ac97_ctrl->rRX_FIFO_STS |= 0xC;			   //clear intr status	if (config->format.voices == 1)		atlasii->ac97_ctrl->rCTRL &= ~(1 << 2);			   // Disable right channel	else		atlasii->ac97_ctrl->rCTRL |= (1 << 2);			   // Enable right channel	atlasii->mixer_cb.SRC_set (atlasii->mixer_cb.mix_context, AC97_LR_ADC_SRC,		&config->format.rate);	atlasii->cap_strm.pcm_config = config;	atlasii->cap_strm.pcm_subchn = *pc = subchn;	ado_mutex_unlock (&atlasii->hw_lock);	return (EOK);}int32_tatlasii_capture_release (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc,	ado_pcm_config_t * config){	ado_mutex_lock (&atlasii->hw_lock);	ado_shm_free (config->dmabuf.addr, config->dmabuf.size, config->dmabuf.name);	atlasii->cap_strm.pcm_subchn = NULL;	ado_mutex_unlock (&atlasii->hw_lock);	return (EOK);}int32_tatlasii_play_prepare (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc, ado_pcm_config_t * config){	atlasii->play_strm.pcm_cur_frag = 0;	return (EOK);}int32_tatlasii_cap_prepare (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc, ado_pcm_config_t * config){	atlasii->cap_strm.pcm_cur_frag = 0;	return (EOK);}int32_tatlasii_play_trigger (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc, uint32_t cmd){	int32_t rtn = EOK;	ado_mutex_lock (&atlasii->hw_lock);	if (cmd == ADO_PCM_TRIGGER_GO)	{		atlasii->ac97_ctrl->rTX_FIFO_INT_EN = 0xC;		   //enable overrun underrun interrupt		atlasii->play_strm.dma->rADDR = (atlasii->play_strm.pcm_config->dmabuf.phys_addr >> 2);	//start address		atlasii->common_dma->rCH_LOOP_CTRL |= (1 << atlasii->play_strm.dma_ch);		atlasii->common_dma->rCH_LOOP_CTRL |= (1 << (atlasii->play_strm.dma_ch + 16));		atlasii->ac97_ctrl->rTX_FIFO_OP = 1;			   //Start FIFO	}	else	{		atlasii->ac97_ctrl->rTX_FIFO_OP = 2;			   //Stop FIFO		atlasii->common_dma->rCH_VALID |= (1 << atlasii->play_strm.dma_ch);	//Stop DMA	}	ado_mutex_unlock (&atlasii->hw_lock);	return (rtn);}int32_tatlasii_cap_trigger (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc, uint32_t cmd){	int32_t rtn = EOK;	ado_mutex_lock (&atlasii->hw_lock);	if (cmd == ADO_PCM_TRIGGER_GO)	{		//let's go		atlasii->ac97_ctrl->rRX_FIFO_INT_EN = 0xC;		   //enable overrun underrun interrupt		atlasii->cap_strm.dma->rADDR = (atlasii->cap_strm.pcm_config->dmabuf.phys_addr >> 2);	//start address		atlasii->common_dma->rCH_LOOP_CTRL |= (1 << atlasii->cap_strm.dma_ch);		atlasii->common_dma->rCH_LOOP_CTRL |= (1 << (atlasii->cap_strm.dma_ch + 16));		atlasii->ac97_ctrl->rRX_FIFO_OP = 1;			   //Start FIFO	}	else	{		atlasii->ac97_ctrl->rRX_FIFO_OP = 2;			   //Stop FIFO		atlasii->common_dma->rCH_VALID |= (1 << atlasii->cap_strm.dma_ch);	//Stop DMA	}	ado_mutex_unlock (&atlasii->hw_lock);	return (rtn);}uint32_tatlasii_play_position (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc, ado_pcm_config_t * config){	uint32_t pos;	ado_mutex_lock (&atlasii->hw_lock);	pos =		(((atlasii->play_strm.dma->rADDR << 2) & 0x01FFFFFF) -		(config->dmabuf.phys_addr & 0x01FFFFFF) -		atlasii->play_strm.pcm_cur_frag * ado_pcm_dma_int_size (config));	if (pos < 0)		pos = 0;	ado_debug (DB_LVL_DRIVER, "play back position(): %xx %dd", pos, pos);	ado_mutex_unlock (&atlasii->hw_lock);	return (pos);}uint32_tatlasii_cap_position (HW_CONTEXT_T * atlasii, PCM_SUBCHN_CONTEXT_T * pc, ado_pcm_config_t * config){	uint32_t pos;

⌨️ 快捷键说明

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