2.6.33的内核,在内核自带的s3c2443-ac97.c上移植的s3c6410-ac97.c,把开发板的smdk6400_wm9713.c配置搬过来的。
改动不大,遇到的主要几个问题是:
1、开始的时候"AC97 Playback" preallocate_dma_buffer成功,"AC97 Capture"的失败。后来发现是FB用的DMA太多了, s3c_fb_pd_win 的 max_bpp我们使用的16bits,但我们设成32bits,FB申请DMA的时候是按max_bpp申请的。改完max_bpp就OK了。
2、warm reset函数里面最后把AC97给关了,就没打开,cold reset的最后就打开了。但wm9713初始化的时候是先cold reset,再warm reset。我就把cold reset的最后一点搬上来了,代码如下。
static void s3c6410_ac97_warm_reset(struct snd_ac97 *ac97)
{
u32 ac_glbctrl;
ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET;
writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
msleep(1);
ac_glbctrl = 0;
writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
msleep(1);
/************** wy! add *****************/
ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
msleep(1);
ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
msleep(1);
ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA |
S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA;
writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
/************** wy! add *****************/
}
3、开始的时候没有声音,后来参考开发板的代码。发现开发板的代码里面的 snd_soc_dai_ops多了个.prepare的初始化。没看过AC97,感觉是在调音量。
static struct snd_soc_dai_ops s3c6410_ac97_dai_ops = {
.hw_params = s3c6410_ac97_hw_params,
.trigger = s3c6410_ac97_trigger,
.prepare = s3c6410_ac97_hifi_prepare, //wy ! add from kfb
};
static int s3c6410_ac97_hifi_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
/*
* To support full duplex
* Tested by cat /dev/dsp > /dev/dsp
*/
s3c6410_ac97_write(0,0x26,0x0);
s3c6410_ac97_write(0, 0x0c, 0x0808);
s3c6410_ac97_write(0,0x3c, 0xf803);
s3c6410_ac97_write(0,0x3e,0xb990);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
//s3c6400_ac97_write(0,0x02, 0x8080); //modify by kfb
s3c6410_ac97_write(0,0x02, 0x0404);
s3c6410_ac97_write(0, 0x04, 0x0606);
//s3c6400_ac97_write(0,0x1c, 0x00aa); //modify by kfb
s3c6410_ac97_write(0,0x1c, 0x12aa);
}
else
{
s3c6410_ac97_write(0, 0x12, 0x0f0f);
#ifdef CONFIG_SOUND_WM9713_INPUT_STREAM_MIC
s3c6410_ac97_write(0,0x5c,0x2);
s3c6410_ac97_write(0,0x10,0x68);
s3c6410_ac97_write(0,0x14,0xfe00);
#else /* Input Stream is LINE-IN */
s3c6410_ac97_write(0, 0x14, 0xd612);
#endif
}
return 0;
}
4、smdk6400_wm9713.c的初始化和 smdk2443_wm9710.c的初始化不一样,最后在开发板的基础上做了一点改动。代码如下:
/*
* smdk6400_wm9713.c -- SoC audio for smdk6400
*
* Copyright (C) 2007, Ryu Euiyoul
*
* Copyright 2007 Wolfson Microelectronics PLC.
* Author: Graeme Gregory
* graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Revision history
* 8th Mar 2007 Initial version.
* 20th Sep 2007 Apply at smdk6400
*
*/
#include
#include
//#include
#include
#include
#include
#include
#include "../codecs/wm9713.h"
#include "s3c-pcm.h"
#include "s3c-dma.h"
#include "s3c24xx-ac97.h"
static struct snd_soc_card s3c6410;
static struct snd_soc_dai_link s3c6410_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 HiFi",
.cpu_dai = &s3c6410_ac97_dai[0],
.codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
},
};
static struct snd_soc_card s3c6410 = {
.name = "S3C6410",
.dai_link = s3c6410_dai,
.num_links = ARRAY_SIZE(s3c6410_dai),
.platform = &s3c24xx_soc_platform, //wy ! add from smdk6400_snd_ac97_devdata
};
static struct snd_soc_device s3c6410_snd_ac97_devdata = {
//.machine = &s3c6410, //wy ! modify
.card = &s3c6410, //wy ! add
//.platform = &s3c24xx_soc_platform,
.codec_dev = &soc_codec_dev_wm9713,
};
static struct platform_device *s3c6410_snd_ac97_device;
static int __init s3c6410_init(void)
{
int ret;
s3c6410_snd_ac97_device = platform_device_alloc("soc-audio", -1);
if (!s3c6410_snd_ac97_device)
return -ENOMEM;
platform_set_drvdata(s3c6410_snd_ac97_device,
&s3c6410_snd_ac97_devdata);
s3c6410_snd_ac97_devdata.dev = &s3c6410_snd_ac97_device->dev;
ret = platform_device_add(s3c6410_snd_ac97_device);
if (ret)
platform_device_put(s3c6410_snd_ac97_device);
return ret;
}
static void __exit s3c6410_exit(void)
{
platform_device_unregister(s3c6410_snd_ac97_device);
}
module_init(s3c6410_init);
module_exit(s3c6410_exit);
/* Module information */
MODULE_AUTHOR("Samsung: Ryu");
MODULE_DESCRIPTION("ALSA SoC WM9713 S3C6410");
MODULE_LICENSE("GPL");
PS:s3c6410-ac97.c的MIC的部分我没用,全注释了,具体就不知道能不能用了。capture我也没试过是否正常。我们只用播放声音。
阅读(7992) | 评论(2) | 转发(0) |