Configurare driver I2S: Diferență între versiuni

De la YO3ITI
Sari la navigare Sari la căutare
Fără descriere a modificării
Fără descriere a modificării
Linia 41: Linia 41:


Acesta este un test
Acesta este un test
#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>
  /*
  modified for linux 4.1.5
  inspired by https://github.com/msperl/spi-config
  with thanks for https://github.com/notro/rpi-source/wiki
  as well as Florian Meier for the rpi i2s and dma drivers
  to use a differant (simple-card compatible) codec
  change the codec name string in two places and the
  codec_dai name string. (see codec's source file)
  fmt flags are set for vanilla i2s with rpi as clock slave
  N.B. playback vs capture is determined by the codec choice
    */
  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", // -> 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", // -> 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*
      },
  };
  int hello_init(void)
  {
      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;
  }
  void hello_exit(void)
  {// you'll have to sudo modprobe -r the card & codec drivers manually (first?)
      platform_device_unregister(&snd_rpi_simple_card_device);
      pr_alert("Goodbye World!\n");
  }
  module_init(hello_init);
  module_exit(hello_exit);
  MODULE_DESCRIPTION("ASoC simple-card I2S setup");
  MODULE_AUTHOR("Plugh Plover");
  MODULE_LICENSE("GPL v2");

Versiunea de la data 1 noiembrie 2022 02:03

The default ALSA sound devices supported by the Raspberry Pi 3 are PWM audio output jack and HDMI output. To run this demonstration I2S input and output needs to be enabled. The goal is to use a simple I2S interface that does not depend on a particular DAC or CODEC device that requires configuration over I2C or SPI.

To avoid recompilation of the Linux kernel a loadable kernel module is used. This enables the driver for the I2S peripheral inside the BCM2708 device to be loaded dynamically.

A full description of how to do this can be found in the link below [#]_, however a brief summary of the required steps, found to work on a clean copy of Debian Jessie shipped with ``Noobs``, is show below:

http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=91237

First, update the Raspbian Linux distribution to the latest version (version 4.4.13v7 tested). This may take a few hours::

sudo apt-get update
sudo apt-get dist-upgrade

Before proceeding with the next steps, ensure you have re-booted your Raspberry Pi so that it is running the latest version of Raspbian that you have just downloaded. This can be done using the following command::

sudo reboot

Next, we need to enable I2S in device tree. To do this, edit the file ``/boot/config.txt`` to remove the comment on line 47::

dtparam=i2s=on

The sound card driver depends on the I2S peripheral and Direct Memory Access Controller modules which need to be added to file. To do this, add the following lines to ``/etc/modules`` using your favorite text editor prefixed with ``sudo`` to ensure super user privileges::

snd_soc_bcm2708
snd_soc_bcm2708_i2s
bcm2708_dmaengine

Next, download the kernel source (this may also take a long time to download and extract). The source download script requires the installation of two helper applications that are not installed by default. The installation of these is included below::

sudo apt-get install bc
sudo apt-get install libncurses5-dev
git clone http://github.com/notro/rpi-source
cd rpi-source
python rpi-source
cd ..

Now we have the kernel source downloaded, we can modify the driver source and build the modules needed to enable I2S. We require two modules --- one called ``loader`` which instantiates the sound-card module and the other is ``asoc_simple_card`` which is the sound card driver itself.

Acesta este un test

  1. 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>
  /*
  modified for linux 4.1.5
  inspired by https://github.com/msperl/spi-config
  with thanks for https://github.com/notro/rpi-source/wiki
  as well as Florian Meier for the rpi i2s and dma drivers
  to use a differant (simple-card compatible) codec
  change the codec name string in two places and the
  codec_dai name string. (see codec's source file)
  fmt flags are set for vanilla i2s with rpi as clock slave
  N.B. playback vs capture is determined by the codec choice
   */
  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", // -> 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", // -> 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*
     },
  };
  int hello_init(void)
  {
     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;
  }
  void hello_exit(void)
  {// you'll have to sudo modprobe -r the card & codec drivers manually (first?)
     platform_device_unregister(&snd_rpi_simple_card_device);
     pr_alert("Goodbye World!\n");
  }
  module_init(hello_init);
  module_exit(hello_exit);
  MODULE_DESCRIPTION("ASoC simple-card I2S setup");
  MODULE_AUTHOR("Plugh Plover");
  MODULE_LICENSE("GPL v2");