[alsa-devel] Custom card returns "arecord: main:722: audio open error: Invalid argument"

Rob Nertney rob at rob-otics.com
Fri May 27 08:43:08 CEST 2016


I've build a card that is registered correctly as far as I can tell.

My hardware is:
static struct snd_pcm_hardware my_pcm_hw =
{
  .info = (SNDRV_PCM_INFO_MMAP |
      SNDRV_PCM_INFO_BLOCK_TRANSFER |
      SNDRV_PCM_INFO_MMAP_VALID),
  .formats          = SNDRV_PCM_FMTBIT_U8,
  .rates            = SNDRV_PCM_RATE_8000,
  .rate_min         = 8000,
  .rate_max         = 8000,
  .channels_min     = 1,
  .channels_max     = 1,
  .buffer_bytes_max = DMA_LENGTH,
  .period_bytes_min = 48,
  .period_bytes_max = 48,
  .periods_min      = 1,
  .periods_max      = 16,
};

When I run "arecord -d 2 foo.wav", I get the error message in the subject.
Printks show that I get to my_pcm_open, then immediately jump to
my_hw_free, my_pcm_close.

I'm in an FPGA embedded system. there are no other cards but mine via
arecord -L.

Here's my _init function for the module:
 struct snd_card *card;
  struct aaw_device *my_dev;
  struct snd_pcm *pcm;
  struct device *dev;
  int ret;

  printk(KERN_ERR "INIT start\n");
  snd_card_new(dev,SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, THIS_MODULE,
sizeof(struct my_device), &card);
  my_dev = card->private_data;
  my_dev->card = card;

  sprintf(card->driver, "my_driver");
  sprintf(card->shortname, "My First Audio Driver");

  snd_card_set_dev(card,dev);

  ret = snd_device_new(card, SNDRV_DEV_LOWLEVEL, my_dev, &dev_ops);
  if(ret < 0)
    printk(KERN_ERR "new device err\n");
  ret = snd_pcm_new(card, card->driver, 0, 0, 1, &pcm);
  if(ret < 0)
    printk(KERN_ERR "new pcm err\n");

  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &my_pcm_ops);

  pcm->private_data = my_dev;
  pcm->info_flags = 0;
  strcpy(pcm->name, card->shortname);

  ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
      SNDRV_DMA_TYPE_CONTINUOUS,
      snd_dma_continuous_data(GFP_KERNEL),
      DMA_LENGTH, DMA_LENGTH);
  if(ret < 0)
    printk(KERN_ERR "preallocate page err\n");

  ret = snd_card_register(card);
  if (ret < 0)
    printk(KERN_ERR "error in register snd\n");


Here's my _open function:
static int my_pcm_open(struct snd_pcm_substream *ss)
{
  struct my_device *my_dev = ss->private_data;

  printk(KERN_ERR "in pcm_open\n");
  ss->runtime->hw = my_pcm_hw;

  my_dev->substream = ss;
  ss->runtime->private_data = my_dev;
  return 0;
}

Any help would be most appreciated.

Thanks,
Rob


More information about the Alsa-devel mailing list