<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Linux ALSA聲卡驅動(dòng)之二:聲卡的創(chuàng )建

Linux ALSA聲卡驅動(dòng)之二:聲卡的創(chuàng )建

作者: 時(shí)間:2016-12-07 來(lái)源:網(wǎng)絡(luò ) 收藏

  1. struct snd_card

本文引用地址:http://dyxdggzs.com/article/201612/341246.htm

  1.1. snd_card是什么

  snd_card可以說(shuō)是整個(gè)音頻驅動(dòng)最頂層的一個(gè)結構,整個(gè)聲卡的軟件邏輯結構開(kāi)始于該結構,幾乎所有與聲音相關(guān)的邏輯設備都是在snd_card的管理之下,聲卡驅動(dòng)的第一個(gè)動(dòng)作通常就是創(chuàng )建一個(gè)snd_card結構體。正因為如此,本節中,我們也從 struct cnd_card開(kāi)始吧。

  1.2. snd_card的定義

  snd_card的定義位于改頭文件中:include/sound/core.h

  /* main structure for soundcard */

  struct snd_card {

  int number; /* number of soundcard (index to

  snd_cards) */

  char id[16]; /* id string of this card */

  char driver[16]; /* driver name */

  char shortname[32]; /* short name of this soundcard */

  char longname[80]; /* name of this soundcard */

  char mixername[80]; /* mixer name */

  char components[128]; /* card components delimited with

  space */

  struct module *module; /* top-level module */

  void *private_data; /* private data for soundcard */

  void (*private_free) (struct snd_card *card); /* callback for freeing of

  private data */

  struct list_head devices; /* devices */

  unsigned int last_numid; /* last used numeric ID */

  struct rw_semaphore controls_rwsem; /* controls list lock */

  rwlock_t ctl_files_rwlock; /* ctl_files list lock */

  int controls_count; /* count of all controls */

  int user_ctl_count; /* count of all user controls */

  struct list_head controls; /* all controls for this card */

  struct list_head ctl_files; /* active control files */

  struct snd_info_entry *proc_root; /* root for soundcard specific files */

  struct snd_info_entry *proc_id; /* the card id */

  struct proc_dir_entry *proc_root_link; /* number link to real id */

  struct list_head files_list; /* all files associated to this card */

  struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown

  state */

  spinlock_t files_lock; /* lock the files for this card */

  int shutdown; /* this card is going down */

  int free_on_last_close; /* free in context of file_release */

  wait_queue_head_t shutdown_sleep;

  struct device *dev; /* device assigned to this card */

  #ifndef CONFIG_SYSFS_DEPRECATED

  struct device *card_dev; /* cardX object for sysfs */

  #endif

  #ifdef CONFIG_PM

  unsigned int power_state; /* power state */

  struct mutex power_lock; /* power lock */

  wait_queue_head_t power_sleep;

  #endif

  #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)

  struct snd_mixer_oss *mixer_oss;

  int mixer_oss_change_count;

  #endif

  };

  struct list_head devices 記錄該聲卡下所有邏輯設備的鏈表

  struct list_head controls 記錄該聲卡下所有的控制單元的鏈表

  void *private_data 聲卡的私有數據,可以在創(chuàng )建聲卡時(shí)通過(guò)參數指定數據的大小

  2. 聲卡的建立流程

  2.1.1. 第一步,創(chuàng )建snd_card的一個(gè)實(shí)例

  struct snd_card *card;

  int err;

  ....

  err = snd_card_create(index, id, THIS_MODULE, 0, &card);

  index 一個(gè)整數值,該聲卡的編號

  id 字符串,聲卡的標識符

  第四個(gè)參數 該參數決定在創(chuàng )建snd_card實(shí)例時(shí),需要同時(shí)額外分配的私有數據的大小,該數據的指針最終會(huì )賦值給snd_card的private_data數據成員

  card 返回所創(chuàng )建的snd_card實(shí)例的指針

  2.1.2. 第二步,創(chuàng )建聲卡的芯片專(zhuān)用數據

  聲卡的專(zhuān)用數據主要用于存放該聲卡的一些資源信息,例如中斷資源、io資源、dma資源等??梢杂袃煞N創(chuàng )建方法:

  通過(guò)上一步中snd_card_create()中的第四個(gè)參數,讓snd_card_create自己創(chuàng )建

  // struct mychip 用于保存專(zhuān)用數據

  err = snd_card_create(index, id, THIS_MODULE,

  sizeof(struct mychip), &card);

  // 從private_data中取出

  struct mychip *chip = card->private_data;

  自己創(chuàng )建:

  struct mychip {

  struct snd_card *card;

  ....

  };

  struct snd_card *card;

  struct mychip *chip;

  chip = kzalloc(sizeof(*chip), GFP_KERNEL);

  ......

  err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);

  // 專(zhuān)用數據記錄snd_card實(shí)例

  chip->card = card;

  .....

  然后,把芯片的專(zhuān)有數據注冊為聲卡的一個(gè)低階設備:

  static int snd_mychip_dev_free(struct snd_device *device)

  {

  return snd_mychip_free(device->device_data);

  }

  static struct snd_device_ops ops = {

  .dev_free = snd_mychip_dev_free,

  };

  ....

  snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);

  注冊為低階設備主要是為了當聲卡被注銷(xiāo)時(shí),芯片專(zhuān)用數據所占用的內存可以被自動(dòng)地釋放。

  2.1.3. 第三步,設置Driver的ID和名字

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

  snd_card的driver字段保存著(zhù)芯片的ID字符串,user空間的alsa-lib會(huì )使用到該字符串,所以必須要保證該ID的唯一性。shortname字段更多地用于打印信息,longname字段則會(huì )出現在/proc/asound/cards中。


上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: Linux ALSA

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>