音频驱动
这里smart210_wm8960.c放在drivers/sound/soc/下并修改Makefile和Kconfig
Makefile
# S3c24XX Platform Support
# S3C24XX Machine Support
snd-soc-bells-objs := bells.o
snd-soc-smart210-wm8960-objs := smart210_wm8960.o
obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
obj-$(CONFIG_SND_SOC_SMART210_WM8960) += snd-soc-smart210-wm8960.o
Kconfig
config SND_SOC_SAMSUNG
tristate "ASoC support for Samsung"
depends on PLAT_SAMSUNG
select S3C64XX_DMA if ARCH_S3C64XX
select S3C2410_DMA if ARCH_S3C24XX
help
Say Y or M if you want to add support for codecs attached to
the Samsung SoCs' Audio interfaces. You will also need to
select the audio interfaces to support below.
config SND_S3C24XX_I2S
tristate
select S3C2410_DMA
config SND_S3C_I2SV2_SOC
tristate
config SND_S3C2412_SOC_I2S
tristate
select SND_S3C_I2SV2_SOC
select S3C2410_DMA
config SND_SAMSUNG_PCM
tristate
config SND_SAMSUNG_AC97
tristate
select SND_SOC_AC97_BUS
config SND_SAMSUNG_SPDIF
tristate
select SND_SOC_SPDIF
config SND_SAMSUNG_I2S
tristate
config SND_SOC_SAMSUNG_SMDK_WM8994
tristate "SoC I2S Audio support for WM8994 on SMDK"
depends on SND_SOC_SAMSUNG
depends on I2C=y && GENERIC_HARDIRQS
select MFD_WM8994
select SND_SOC_WM8994
select SND_SAMSUNG_I2S
help
Say Y if you want to add support for SoC audio on the SMDKs.
config SND_SOC_SMART210_WM8960
tristate "SoC I2S Audio support for WM8960 on smart210"
depends on SND_SOC_SAMSUNG
select SND_SOC_WM8960
select SND_SAMSUNG_I2S
help
Say Y if you want to add support for SoC audio on the smart210.
smart210_wm8960.c
/*
* linux-3.10.79
* arm-linux-gcc-4.5.1
*
* @ audio platform driver
*/
#include <linux/module.h>
#include <linux/init.h> /* module_init, ... */
#include <linux/kernel.h> /* everything */
#include <linux/cdev.h> /* cdev_init, ... */
#include <linux/fs.h> /* file_operations, */
#include <linux/device.h> /* class_create,... */
#include <linux/platform_device.h>
#include <linux/slab.h> /* kmalloc, ... */
#include <asm/io.h> /* ioremap,... */
#include <sound/soc.h>
static int smart210_audio_hw_params(struct snd_pcm_substream * substream,
struct snd_pcm_hw_params *params)
{
return 0;
}
const struct snd_soc_ops smart210_audio_ops =
{
.hw_params = smart210_audio_hw_params,
};
static const struct snd_soc_dapm_widget smart210_dapm_capture_widgets[] = {
SND_SOC_DAPM_MIC( "Mic Jack", NULL ),
SND_SOC_DAPM_LINE( "Line Input 3 (FM)",NULL ),
};
static const struct snd_soc_dapm_widget smart210_dapm_playback_widgets[] = {
SND_SOC_DAPM_HP( "Headphone Jack", NULL ),
SND_SOC_DAPM_SPK( "Speaker_L", NULL ),
SND_SOC_DAPM_SPK( "Speaker_R", NULL ),
};
static const struct snd_soc_dapm_route smart210_audio_map[] = {
{ "Headphone Jack", NULL, "HP_L" },
{ "Headphone Jack", NULL, "HP_R" },
{ "Speaker_L", NULL, "SPK_LP" },
{ "Speaker_L", NULL, "SPK_LN" },
{ "Speaker_R", NULL, "SPK_RP" },
{ "Speaker_R", NULL, "SPK_RN" },
{ "LINPUT1", NULL, "MICB" },
{ "MICB", NULL, "Mic Jack" },
};
static int smart210_audio_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
pr_info("%s called .\n", __func__);
snd_soc_dapm_nc_pin(dapm, "RINPUT1");
snd_soc_dapm_nc_pin(dapm, "LINPUT2");
snd_soc_dapm_nc_pin(dapm, "RINPUT2");
snd_soc_dapm_nc_pin(dapm, "OUT3");
snd_soc_dapm_new_controls( dapm, smart210_dapm_capture_widgets, ARRAY_SIZE( smart210_dapm_capture_widgets ) );
snd_soc_dapm_new_controls( dapm, smart210_dapm_playback_widgets, ARRAY_SIZE( smart210_dapm_playback_widgets ) );
snd_soc_dapm_add_routes( dapm, smart210_audio_map, ARRAY_SIZE( smart210_audio_map ) );
snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
snd_soc_dapm_enable_pin(dapm, "Mic Jack");
snd_soc_dapm_enable_pin(dapm, "Speaker_L");
snd_soc_dapm_enable_pin(dapm, "Speaker_R");
snd_soc_dapm_disable_pin(dapm, "Line Input 3 (FM)");
snd_soc_dapm_sync( dapm );
return 0;
}
static struct snd_soc_dai_link smart210_dai = {
.name = "smart210 audio",
.stream_name = "wm8960 HiFi",
.codec_name = "wm8960.0-001a",
.platform_name = "samsung-i2s.0",
.cpu_dai_name = "samsung-i2s.0",
.codec_dai_name = "wm8960-hifi",
.init = smart210_audio_init,
.ops = &smart210_audio_ops,
};
static struct snd_soc_card smart210_soc_card = {
.name = "smart210_audio",
.dai_link = &smart210_dai,
.num_links = 1,
};
static struct platform_device *smart210_audio_device;
static int smart210_wm8960_init(void)
{
int ret = 0;
pr_info("%s called .\n", __func__);
smart210_audio_device = platform_device_alloc("soc-audio", -1);
if(!smart210_audio_device){
return -ENOMEM;
}
platform_set_drvdata(smart210_audio_device, &smart210_soc_card);
ret = platform_device_add(smart210_audio_device);
if(ret){
platform_device_put(smart210_audio_device);
}
return 0;
}
static void smart210_wm8960_exit(void)
{
pr_info("%s called .\n", __func__);
platform_device_unregister(smart210_audio_device);
}
module_init(smart210_wm8960_init);
module_exit(smart210_wm8960_exit);
MODULE_LICENSE("GPL");
最终启动日志有:
log:
[ 1.536469] wm8960_i2c_probe called.
[ 1.543415] smart210_wm8960_init called .
[ 1.543850] soc-audio soc-audio: ASoC: machine smart210_audio should use snd_soc_register_card()
[ 1.543968] soc-audio soc-audio: ASoC: binding smart210 audio at idx 0
[ 1.544045] soc-audio soc-audio: register codec: wm8960.0-001a <-> current codec : wm8960.0-001a
[ 1.549795] soc-audio soc-audio: register codec: snd-soc-dummy <-> current codec : wm8960.0-001a
[ 1.558344] soc-audio soc-audio: registered platform: samsung-idma <-> current platform : samsung-i2s.0
[ 1.567605] soc-audio soc-audio: registered platform: samsung-i2s.0 <-> current platform : samsung-i2s.0
[ 1.577109] soc-audio soc-audio: registered platform: samsung-i2s-sec <-> current platform : samsung-i2s.0
[ 1.586844] soc-audio soc-audio: registered platform: snd-soc-dummy <-> current platform : samsung-i2s.0
[ 1.596424] wm8960 0-001a: No platform data supplied
[ 1.709963] smart210_audio_init called .
[ 1.710763] soc-audio soc-audio: wm8960-hifi <-> samsung-i2s.0 mapping ok
mapping ok ,表示能正常识别声卡。后面的测试有空再补上。