本文主要是介绍树莓派-MIC篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1 DMIC驱动
arch\arm\boot\dts\overlays\example-sound-overlay.dts
// Definitions for example audio add on soundcard
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&sound>;
__overlay__ {
compatible = "ai,example-soundcard";
i2s-controller = <&i2s>;
status = "okay";
};
};
};
linux\arch\arm\boot\dts\overlays\Makefile
dtbo-$(RPI_DT_OVERLAYS) += example-sound.dtbo
sound\soc\bcm\example-soundcard.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/platform_device.h>
#include <sound/simple_card.h>
#include <linux/delay.h>
void device_release_callback(struct device *dev) { /* do nothing */ };
static struct asoc_simple_card_info snd_rpi_simple_card_info = {
.card = "snd_rpi_simple_card", // -> snd_soc_card.name
.name = "simple-card_codec_link", // -> snd_soc_dai_link.name
.codec = "snd-soc-dummy", // "dmic-codec", // -> snd_soc_dai_link.codec_name
.platform = "3f203000.i2s",
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFM,
.cpu_dai = {
.name = "3f203000.i2s", // -> snd_soc_dai_link.cpu_dai_name
.sysclk = 0 },
.codec_dai = {
.name = "snd-soc-dummy-dai", //"dmic-codec", // -> snd_soc_dai_link.codec_dai_name
.sysclk = 0 },
};
static struct platform_device snd_rpi_simple_card_device = {
.name = "asoc-simple-card", //module alias
.id = 0,
.num_resources = 0,
.dev = { .release = &device_release_callback,
.platform_data = &snd_rpi_simple_card_info, // *HACK ALERT*
},
};
static int example_soundcard_probe(struct platform_device *pdev)
{
const char *dmaengine = "bcm2708-dmaengine"; //module name
int ret;
ret = request_module(dmaengine);
pr_alert("request module load '%s': %d\n",dmaengine, ret);
ret = platform_device_register(&snd_rpi_simple_card_device);
pr_alert("register platform device '%s': %d\n",snd_rpi_simple_card_device.name, ret);
pr_alert("Hello World :)\n");
return 0;
}
static int example_soundcard_remove(struct platform_device *pdev)
{
platform_device_unregister(&snd_rpi_simple_card_device);
return 0;
}
static const struct of_device_id example_soundcard_of_match[] = {
{ .compatible = "ai,example-soundcard", },
{},
};
MODULE_DEVICE_TABLE(of, example_soundcard_of_match);
static struct platform_driver example_soundcard_driver = {
.driver = {
.name = "example-audio",
.owner = THIS_MODULE,
.of_match_table = example_soundcard_of_match,
},
.probe = example_soundcard_probe,
.remove = example_soundcard_remove,
};
module_platform_driver(example_soundcard_driver);
MODULE_AUTHOR("Thornton");
MODULE_DESCRIPTION("example Soundcard");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:example-soundcard");
linux\sound\soc\bcm\Makefile
obj-m += snd-soc-example-soundcard.o
linux\sound\soc\bcm\bcm2835-i2s.c
@@ -456,6 +456,10 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *
ch2pos = bclk_ratio / 2 + data_delay;
switch (params_channels(params)) {
+ case 1:
+ format = BCM2835_I2S_CH1(format);
+ format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos));
+ break;
case 2:
format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format);
format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos));
@@ -494,6 +498,8 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *s
switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
/* CPU is master */
+ mode |= BCM2835_I2S_PDMN;
+ mode |= BCM2835_I2S_PDME;
break;
case SND_SOC_DAIFMT_CBM_CFS:
/*
@@ -508,6 +514,8 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *s
* CPU is bit clock master
*/
mode |= BCM2835_I2S_FSM;
+ mode |= BCM2835_I2S_PDMN;
+ mode |= BCM2835_I2S_PDME;
break;
case SND_SOC_DAIFMT_CBM_CFM:
/* CODEC is master */
@@ -736,7 +744,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = {
| SNDRV_PCM_FMTBIT_S32_LE
},
.capture = {
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE
2 KERNEL编译
export PATH=$PATH:/home/thornton/work/pi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=/home/thornton/work/pi/firmware modules_install
3 KERNEL更新
将RPI T卡插在LINUX系统下,会弹出两个盘,一个是KERENL盘和一个BOOT盘
将firmware/lib拷到KERNEL盘,其他拷到BOOT盘
4 启动驱动
修改BOOT盘里的config.txt
#dtparam=i2s=on
改为
dtparam=i2s=on
使能snd-soc-bcm2835-i2s.ko驱动
dtparam=audio=on
使能snd-bcm2835.ko
dtoverlay=example-sound
使能snd-soc-example-soundcard.ko
5测试
arecord -D hw:1,0 -r16000 -fS16_LE -twav -c2|aplay -D hw:0,0 -r16000 -fS16_LE -c1
这篇关于树莓派-MIC篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!