调试WM9714音频通道切换
来源:互联网 发布:shopnc源码下载2017 编辑:程序博客网 时间:2024/05/19 02:44
WM9714的耳机跟喇叭通道切换由寄存器软件控制,跟之前电视里面插入耳机让功放直接拉低关掉外音的方式有点差别。通过设置WM9714的0X1C寄存器的值来切换,其中设置耳机时为0X00A0,设置喇叭时为0X1200。
电路中有外部上拉固定EINT11为高电平,通过插入耳机将这个外中断EINT11拉低来触发中断,再进行WM9714的寄存器控制。首先在WM9713.C中wm9713_soc_probe()中,添加初始化通道设置和注册中断。
#define HdPhone_EintPin IRQ_EINT(11)
#define HdPhone_GpioPin S3C64XX_GPN(11)
#define OUTPUT_VALUE_HP (0x00a0)
#define OUTPUT_VALUE_SPK (0x1200)
static int wm9713_soc_probe(struct platform_device *pdev)
{
......
s3c_gpio_cfgpin(HdPhone_GpioPin, S3C_GPIO_SFN(2)); //配置GPIO11为外中断
s3c_gpio_setpull(HdPhone_GpioPin, S3C_GPIO_PULL_NONE); //不上拉也不下拉,硬件默认拉高
set_irq_type(HdPhone_EintPin, IRQ_TYPE_EDGE_BOTH); //插入跟拔出耳机都会触发中断
if(readl(S3C64XX_GPNDAT)&(1<<11)) //如果上电默认是喇叭,设置通道;否则设置耳机
{
ac97_write(codec, AC97_REC_GAIN, OUTPUT_VALUE_SPK);
}
else
{
ac97_write(codec, AC97_REC_GAIN, OUTPUT_VALUE_HP);
}
ret = request_irq(HdPhone_EintPin, s3c6400_9713HdSp_irq, //给EINT11注册中断和中断处理函数,参数包括中断方式,
IRQF_DISABLED, "HdphonSpeak", NULL); //中断名
if(ret<0) //如果注册不成功,执行GOTO
{
printk(KERN_ERR "request_irq(s3c6400_9713HdSp_irq) failed !!!/n");
goto irq_err;
}
.........
irq_err:
free_irq(HdPhone_EintPin,NULL); //释放中断
.........
}
中断handler如下:
static irqreturn_t s3c6400_9713HdSp_irq(int irq, void *dev_id)
{
struct snd_soc_codec *codec = wm9713_dai->codec; //获取系统的codec
writel(readl(S3C64XX_EINT0MASK)|(1<<11),S3C64XX_EINT0MASK); //disable EINT0 Interrupt before deal it
writel(1<<11,S3C64XX_EINT0PEND); //disable Interrupt
if(readl(S3C64XX_GPNDAT)&(1<<11)) //如果是喇叭,否则是耳机
{
ac97_write(codec, AC97_REC_GAIN, OUTPUT_VALUE_SPK);
}
else
{
ac97_write(codec, AC97_REC_GAIN, OUTPUT_VALUE_HP);
}
writel(readl(S3C64XX_EINT0MASK)&(~(1<<11)),S3C64XX_EINT0MASK); //Enable Interrupt after deal it
return IRQ_HANDLED;
}
以上即OK,在实际中还发现一个问题,插拔耳机切通道一直正常,但是第一次开机和仅仅用喇叭播放时喇叭不出声,也就是说一直需要耳机触发后喇叭跟耳机才会出声?通过测试波形,发现有耳机输入波形跟切换正常;但是功放输入会没有波形,估计还是切换通道的问题,查找后原因在于播放声音时,Entered s3c6400_ac97_hifi_prepare()中,判断SNDRV_PCM_STREAM_PLAYBACK会将0X1C寄存器写成0XAA,把喇叭所需的0X1200覆盖,屏蔽这句即可。可通过在s3c6400_ac97_trigger()中,设置打印语句:
for (temp =0x00;temp<=0x7e;temp+=0x02)
s3c6400_ac97_read(0,temp);
将CMD=1开始播放音频时9714的寄存器值全部读出,作出判断依据。
==================WIN CE的做法===============================================
初始化执行中:
Irq = IRQ_EINT11; //中断GPIO
DWORD m_dwSysintrHPSense = NULL; //耳机切换标志
HANDLE m_hHPSenseInterrupt = NULL; //耳机切换中断句柄
HANDLE m_hHPSenseInterruptThread; //耳机切换中断线程句柄
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(DWORD), &m_dwSysintrHPSense, sizeof(DWORD), NULL)) //GPIO作中断控制注册
{
WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : HP sense IOCTL_HAL_REQUEST_SYSINTR Failed/n/r")));
m_dwSysintrHPSense = SYSINTR_UNDEFINED;
return FALSE;
}
m_hHPSenseInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL); //初始化中断句柄
if (m_hHPSenseInterrupt == NULL)
{
WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : HP sense CreateEvent() Failed /n/r")));
return(FALSE);
}
if (!InterruptInitialize(m_dwSysintrHPSense, m_hHPSenseInterrupt, NULL, 0)) //绑定中断句柄和标志
{
WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : HP sense InterruptInitialize() Failed /n/r")));
return FALSE;
}
m_hHPSenseInterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0,
(LPTHREAD_START_ROUTINE)CallInterruptThreadHPSense, this, 0, NULL); //创建中断线程
if (m_hHPSenseInterruptThread == NULL) //如果没有创建成功线程,返回。
{
WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : HP sense CreateThread() Failed /n/r")));
return FALSE;
}
void CallInterruptThreadHPSense(HardwareContext *pHWContext)
{
pHWContext->InterruptThreadHPSense(); //通过硬件上下文调用中断处理函数
}
中断处理函数:
void HardwareContext::InterruptThreadHPSense()
{
......
if(!(g_pGPIOReg->GPNDAT & (1<<11))) //如果插入耳机
{
WriteCodecRegister(WM9713_OUTPUT_MUX, OUTPUT_VALUE_HP);
RETAILMSG(AC97_HP_DEBUG,(_T("[WAV:] HeadPhone OUTPUT/n/r")));
}
while(TRUE)
{
WaitForSingleObject(m_hHPSenseInterrupt, INFINITE); //线程等待中断发生
g_pGPIOReg->EINT0MASK |= (0x1<<11); // Mask EINT9, Clear Interrupt Pending
g_pGPIOReg->EINT0PEND = (0x1<<11); // Clear pending EINT9
if(g_pGPIOReg->GPNDAT & (1<<11))
{
WriteCodecRegister(WM9713_OUTPUT_MUX, OUTPUT_VALUE_SPK);
RETAILMSG(AC97_HP_DEBUG,(_T("[WAV:] SPEAK OUTPUT/n/r")));
}
else
{
WriteCodecRegister(WM9713_OUTPUT_MUX, OUTPUT_VALUE_HP);
RETAILMSG(AC97_HP_DEBUG,(_T("[WAV:] HeadPhone OUTPUT/n/r")));
}
InterruptDone(m_dwSysintrHPSense);
g_pGPIOReg->EINT0MASK &= ~(0x1<<11); // Unmask EINT9, Enable Interrupt
}
......
}
- 调试WM9714音频通道切换
- 调试WM9714音频通道切换
- 调试WM9714音频通道切换
- Audio音频输出通道切换
- android+WM9714(AC97)调试
- Android+WM9714调试
- android+WM9714(AC97)调试
- android+WM9714(AC97)调试
- android+WM9714(AC97)调试
- 【Android】Audio音频输出通道切换
- 【Android】Audio音频输出通道切换
- FS_S5PC100平台上WM9714 ALSA音频移植
- FS_S5PC100平台上WM9714 ALSA音频移植
- Android底层开发之耳机插拔与音频通道切换实例
- Android底层开发之耳机插拔与音频通道切换实例
- Android底层开发之耳机插拔与音频通道切换实例
- freeRdp ---- 音频输出通道扩展
- android声音通道的切换
- ruby-语法
- 《唐骏日记》
- Python中RE模块的应用
- Class org.jnp.server.NamingServer does not implement the requested interface org.jnp.interfaces.Naming
- 明日又天涯——蝶舞萧霞
- 调试WM9714音频通道切换
- 点击按钮,生成表单
- JAVA实现验证码
- Cookie应用完全解析(一):asp.net中Cookie技术
- c
- js 简单时间显示
- 关于Jboss GateIn
- S3c610 Codec移植的工作经验总结
- 内存对齐和char d[0], char *d