Jump to content

    

ASoC ALSA

Не обнаружил достойной документации по данной подсистеме.

Исходники рыть ... как то не айс.

Кто может порекомендовать что нибудь дельное из книг/достойной документации?

В идеале, как вообще цеплять i2c + i2s на dai + snd_card

Вообще идеально - работающий max98089 :-)

 

Распишу поподробнее...

В BSP прописал интерфейс i2c, адрес 0х10, max98088

Скомпилил ядро c all asoc codecs.

В результате наблюдаю в /proc/asound/codecs max98088

Так как система андроид, то в /sys/kernel/debug/asoc/codecs есть max98088.1-10

Теперь вот траблы прицеплением сего к DAI и SND_CARD.

Готовые исходники для другой EV_BOARD создали в debug/asoc мифическую поддиректорию с непонятным соержимым... ахочется получить soundcard, которая как бы там прописана.

 

 

Share this post


Link to post
Share on other sites

Вообщем имеем begleboneblack + max98089 EVKIT

Висит кодек на i2c-1

Пишем драйвер для ALSA:

#include <linux/clk.h>
  #include <linux/platform_device.h>
  #include <linux/module.h>
  #include <sound/core.h>
  #include <sound/pcm.h>
  #include <sound/soc.h>
  
  #include <asm/mach-types.h>
  #include <mach/hardware.h>
  #include <mach/gpio.h>
  #include <plat/mcbsp.h>
  #include <mach/board-am335xevm.h>
  //#include "omap-mcbsp.h"
  //#include "omap-pcm.h"
  #include "davinci-pcm.h"
  #include "davinci-i2s.h"
  #include "davinci-mcasp.h"
  
  
  #include "../codecs/max98088.h"
  
  #define CODEC_CLOCK     12000000
  
  static int am335x_evm_hw_params(struct snd_pcm_substream *substream,
      struct snd_pcm_hw_params *params)
  {
      struct snd_soc_pcm_runtime *rtd = substream->private_data;
      struct snd_soc_dai *codec_dai = rtd->codec_dai;
      struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
      int ret;
      unsigned sysclk = 12000000;
  
      /* ASP1 on DM355 EVM is clocked by an external oscillator */
      if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
          machine_is_davinci_dm365_evm())
          sysclk = 27000000;
  
      /* ASP0 in DM6446 EVM is clocked by U55, as configured by
       * board-dm644x-evm.c using GPIOs from U18.  There are six
       * options; here we "know" we use a 48 KHz sample rate.
       */
      else if (machine_is_davinci_evm())
          sysclk = 12288000;
  
      else if (machine_is_davinci_da830_evm() ||
                  machine_is_davinci_da850_evm())
          sysclk = 24576000;
      /* On AM335X, CODEC gets MCLK from external Xtal (12MHz). */
      else if (machine_is_am335xevm())
  #ifdef CONFIG_MACH_AM335XEVM
          if (am335x_evm_get_id() == EVM_SK)
              sysclk = 24000000;
          else
  #endif
              sysclk = 12000000;
  
      else
          return -EINVAL;
      pr_info("MAX98088 EVM snd_soc_dai_set_sysclk\n");
      ret = snd_soc_dai_set_sysclk(codec_dai, 0,
              CODEC_CLOCK, SND_SOC_CLOCK_IN);
      if (ret < 0) {
          printk(KERN_ERR "MAX98089 can't set codec system clock\n");
          return ret;
      }
  
      ret = snd_soc_dai_set_sysclk(cpu_dai, sysclk, 0,
                  SND_SOC_CLOCK_IN);
      if (ret < 0) {
          printk(KERN_ERR "MAX98089 can't set CPU system clock sysclk\n");
          return ret;
      }
  
      snd_soc_dai_set_sysclk(cpu_dai, sysclk, 0,
                  SND_SOC_CLOCK_IN);
      if (ret < 0) {
          printk(KERN_ERR "MAX98089  can't set CPU system clock sysclk (2)\n");
          return ret;
      }
  
      return 0;
  }
  
  static struct snd_soc_ops am335x_evm_ops = {
      .hw_params = am335x_evm_hw_params,
  };
  
  /* am335x_evm machine dapm widgets */
  static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
      SND_SOC_DAPM_HP("Line Out", NULL),
      SND_SOC_DAPM_LINE("Line In", NULL),
      SND_SOC_DAPM_MIC("Mic In", NULL),
  };
  
  static const struct snd_soc_dapm_route audio_map[] = {
      /* Line Out connected to LLOUT, RLOUT */
      {"Line Out", NULL, "LOUT"},
      {"Line Out", NULL, "ROUT"},
  
      {"LLINEIN", NULL, "Line In"},
      {"RLINEIN", NULL, "Line In"},
  
      {"MICIN", NULL, "Mic In"},
  };
  
  /* Digital audio interface glue - connects codec <--> CPU */
  static struct snd_soc_dai_link am335x_evm_dai = {
      .name = "max98088",
      .stream_name = "AIC23",
      .cpu_dai_name ="davinci-mcasp.1",
      .codec_dai_name = "max98088-hifi",
      .platform_name = "davinci-pcm-audio",
      .codec_name = "max98088.1-0010",
      .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
             SND_SOC_DAIFMT_CBM_CFM,
  //    .init = &am335x_evm_soc_init,
      .ops = &am335x_evm_ops,
  };
  
  /* Audio machine driver */
  static struct snd_soc_card snd_soc_am335x_evm = {
      .name = "max98088pd",
      .dai_link = &am335x_evm_dai,
      .num_links = 1,
  
      .dapm_widgets = max98088_dapm_widgets,
      .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
      .dapm_routes = audio_map,
      .num_dapm_routes = ARRAY_SIZE(audio_map),
  };
  
  static struct platform_device *am335x_evm_snd_device;
  
  static int __init am335x_evm_soc_init(void)
  {
      int ret;
  
  //    if (!machine_is_omapam335x_evm())
  //        return -ENODEV;
      pr_info("MAX98088 EVM SoC init\n");
  
      am335x_evm_snd_device = platform_device_alloc("soc-audio", -1);
      if (!am335x_evm_snd_device) {
          printk(KERN_ERR "MAX98088 Platform device allocation failed\n");
          return -ENOMEM;
      }
      pr_info("MAX98088 EVM platform_set_drvdata ... \n");
      platform_set_drvdata(am335x_evm_snd_device, &snd_soc_am335x_evm);
      pr_info("MAX98088 EVM platform_set_drvdata OK! \n");
      ret = platform_device_add(am335x_evm_snd_device);
      if (ret)
          goto err1;
  
      return 0;
  
  err1:
      printk(KERN_ERR "Unable to add MAX98088 platform device\n");
      platform_device_put(am335x_evm_snd_device);
  
      return ret;
  }
  
  static void __exit am335x_evm_soc_exit(void)
  {
      platform_device_unregister(am335x_evm_snd_device);
  }
  
  module_init(am335x_evm_soc_init);
  module_exit(am335x_evm_soc_exit);
  
  MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
  MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM");
  MODULE_LICENSE("GPL v2");

 

На выходе имеем следующую фигню:

по dmesg

 

<7>[ 2.452697] i2c-core: driver [cs4271] registered

<7>[ 2.452880] i2c-core: driver [da7210-codec] registered

<7>[ 2.453063] max98088 1-0010: probe

<7>[ 2.453063] max98088 1-0010: codec register 1-0010

<7>[ 2.453125] max98088 1-0010: dai register 1-0010 #2

<7>[ 2.453125] Registered DAI 'HiFi'

<7>[ 2.453125] Registered DAI 'Aux'

<7>[ 2.453155] Registered codec 'max98088.1-0010'

<7>[ 2.453186] i2c-core: driver [max98088] registered

 

и далее

 

 

<6>[ 2.458251] MAX98088 EVM SoC init

<6>[ 2.461791] MAX98088 EVM platform_set_drvdata ...

<6>[ 2.466796] MAX98088 EVM platform_set_drvdata OK!

<7>[ 2.472076] soc-audio soc-audio: binding max98088 at idx 0

<7>[ 2.472106] soc-audio soc-audio: CPU DAI davinci-mcasp.1 not registered

<7>[ 2.472106] soc-audio soc-audio: CODEC DAI max98088-hifi not registered

<7>[ 2.472137] soc-audio soc-audio: Registered card 'max98088pd'

<6>[ 2.472167] ALSA device list:

<6>[ 2.475250] No soundcards found.

 

No soundcards found.

 

 

Хотя бы подскажите, куда копать..

Еще не пойму одной вещи - у меня вроде .ops не вызываются, и кодек не пишет отладочных собщений,

хотя #define DEBUG в нем поставил, уровень отладки kprint 7, и есть еще живительное CFLAGS_max98088.o = -DDEBUG в Makefile. После всего этого отладочных сообщений нету..

 

P.S.: Скрыть под спойлер код не удалось. Что то не работает на форуме, сори.

Share this post


Link to post
Share on other sites

Дело оказалось в snd_soc_dai_link am335x_evm_dai

 

 static struct snd_soc_dai_link am335x_evm_dai = {
     .name = "max98088",
      .stream_name = "HiFi",
      .cpu_dai_name ="davinci-mcasp.1",
      .codec_dai_name = "max98088.1-10",
      .platform_name = "davinci-pcm-audio",
      .codec_name = "max98088.1-0010",
      .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
             SND_SOC_DAIFMT_CBM_CFM,
      .ops = &am335x_evm_ops,
  };

Ключевыми является .stream_name и .codec_dai_name.

Теперь осталось понять, в каком месте разработчики борды напутали, и какой из трех i2c в ядре выведен на пины отмеченные как i2c-1 :)

Share this post


Link to post
Share on other sites

Сам себе задал вопрос, сам и ответил.

На beagleboneblack Android SDK 4.2.2 имеет следующие соответствия по i2c: В ядре i2c0, на борде i2c-1, i2c1 -> i2c-2 , i2c2-> i2c-3. При этом инициализация i2c-1 -> i2c2 изначально в ядре не прописана, если ваше устройство "висит" на этой шине - ее придется прописать.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this