树莓派-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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值