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
Note that the directory ``linux`` will appended with a long hash. Please use this directory in the above copy command.
E.g. ``/linux-e88b69aa792dbe2b289ff528c0d07303068aa0aa/``.
The file needs a small modification to work around a bug (uninitialized BCLK ratio, causing the default of 100 bit clocks per I2S frame rather than the required 64 bit). To make this correction, at the end of function ``asoc_simple_card_dai_init`` around line number 213, add the following  source lines::
  ret = snd_soc_dai_set_bclk_ratio(cpu, 64);
  pr_alert("BCLK ratio set to 64!\n");
Use this makefile to build the module.
i.e. copy the contents into ``Makefile``. Note that the last line must be indented using a tab character rather than using spaces to avoid a build error::


<syntaxhighlight lang="C">
<syntaxhighlight lang="C">

Versiunea de la data 1 noiembrie 2022 02:04

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

Note that the directory ``linux`` will appended with a long hash. Please use this directory in the above copy command. E.g. ``/linux-e88b69aa792dbe2b289ff528c0d07303068aa0aa/``.

The file needs a small modification to work around a bug (uninitialized BCLK ratio, causing the default of 100 bit clocks per I2S frame rather than the required 64 bit). To make this correction, at the end of function ``asoc_simple_card_dai_init`` around line number 213, add the following source lines::

  ret = snd_soc_dai_set_bclk_ratio(cpu, 64);
  pr_alert("BCLK ratio set to 64!\n");

Use this makefile to build the module. i.e. copy the contents into ``Makefile``. Note that the last line must be indented using a tab character rather than using spaces to avoid a build error::

#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");