zoukankan      html  css  js  c++  java
  • alsa driver--card

    https://www.kernel.org/doc/html/v4.11/sound/kernel-api/writing-an-alsa-driver.html

    1.创建声卡

    snd_card是对声卡硬件抽象出来的结构体,几乎所有与声音相关的逻辑设备都是在snd_card的管理之下,声卡驱动的第一个动作通常就是创建一个snd_card结构体。

    我们可以通过调用snd_card_new来创建一个snd_card结构体。

    struct snd_card *card;
    int err;
    err = snd_card_new(&pci->dev, index, id, module, extra_size, &card);

    /**
    * snd_card_new - create and initialize a soundcard structure
    * @parent: the parent device object
    * @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
    * @xid: card identification (ASCII string)
    * @module: top level module for locking
    * @extra_size: allocate this extra size after the main soundcard structure
    * @card_ret: the pointer to store the created card instance
    */
    int snd_card_new(struct device *parent, int idx, const char *xid, struct module *module, int extra_size, struct snd_card **card_ret)

    这里extra_size是为card->private_data分配的内存大小。通常private_data保存chip-specifc data.

    2.创建声卡的芯片专用数据

     chip-specific data包含I/O port address, its resource pointer, or the irq number等信息。

    有两种方法可以来分配chip specific data.

    1).通过snd_card_new实现:

    struct mychip {
              struct snd_card *card;
              ....
      };
    err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                         sizeof(struct mychip), &card);
    struct mychip *chip = card->private_data;
    chip->card = card;

    在snd_card_new中分配chip。并将chip和card关联起来。card结构中的private_data就是chip,chip中又包含card。

    2).通过snd_device_new来将chip作为一个低阶device注册到card上。

    在snd_device_new中指定extra_size为0.

      struct snd_card *card;
      struct mychip *chip;
      err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                         0, &card);
      .....
      chip = kzalloc(sizeof(*chip), GFP_KERNEL);
      chip->card = card;
    static struct snd_device_ops ops = {
              .dev_free =        snd_mychip_dev_free,
      };
      ....
      snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);   
      static int snd_mychip_dev_free(struct snd_device *device)
      {
              return snd_mychip_free(device->device_data);
      }

    /**
    * snd_device_new - create an ALSA device component
    * @card: the card instance
    * @type: the device type, SNDRV_DEV_XXX
    * @device_data: the data pointer of this device
    * @ops: the operator table
    */
    int snd_device_new(struct snd_card *card, enum snd_device_type type,
    void *device_data, struct snd_device_ops *ops)

     snd_device_new不为芯片专用数据device_data分配空间,因此在调用之前,必须为芯片专用分配空间,在ops的dev_free中定义析构函数对芯片专用数据进行析构。dev_free会在调用snd_card_free时自动调用。对于用户自定义的 device, type可以使用SNDRV_DEV_LOWLEVEL。

    snd_mychip_dev_free() 是用来free前面kzmalloc的空间。

     3.设置声卡驱动名字和声卡名字。

    strcpy(card->driver, "My Chip");
    strcpy(card->shortname, "My Own Chip 123");
    sprintf(card->longname, "%s at 0x%lx irq %i",
              card->shortname, chip->ioport, chip->irq);
     4.创建声卡功能部件,如PCM,mixer, MIDI
    .每一种部件的创建最终会调用snd_device_new()来生成一个snd_device实例,并把该实例链接到snd_card的devices链表中。

    通常,alsa-driver的已经提供了一些常用的部件的创建函数,而不必直接调用snd_device_new(),比如: snd_pcm_new()

    5.注册声卡

    err = snd_card_register(card);
      if (err < 0) {
              snd_card_free(card);
              return err;
      }

     具体声卡创建的例子可参考sound/sparc/amd9730.c   

     



  • 相关阅读:
    超市帐单系统
    JavaOOP
    拦截器的工作原理是什么?
    struts2
    500错误
    idea添加struts框架后报错
    2019春第九周作业
    2019春第八周作业
    2019春第七周作业
    2019春第六周作业
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6198770.html
Copyright © 2011-2022 走看看