树莓派-MIC篇

Posted skdev

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树莓派-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篇的主要内容,如果未能解决你的问题,请参考以下文章

使用树莓派打造一个私人NAS+博客(1)——网络篇

使用树莓派打造一个私人NAS+博客(2)——硬件篇

树莓派——步进电机+驱动器 篇

树莓派 ——红外遥控篇lirc【内核4.19.x】

树莓派怎么连电脑

《树莓派开发笔记 - 第1部分 基础篇》第7章 树莓派变身路由器