新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux ALSA聲卡驅動之二:聲卡的創建

        Linux ALSA聲卡驅動之二:聲卡的創建

        作者: 時間:2016-12-07 來源:網絡 收藏

          1. struct snd_card

        本文引用地址:http://www.104case.com/article/201612/341246.htm

          1.1. snd_card是什么

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

          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 聲卡的私有數據,可以在創建聲卡時通過參數指定數據的大小

          2. 聲卡的建立流程

          2.1.1. 第一步,創建snd_card的一個實例

          struct snd_card *card;

          int err;

          ....

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

          index 一個整數值,該聲卡的編號

          id 字符串,聲卡的標識符

          第四個參數 該參數決定在創建snd_card實例時,需要同時額外分配的私有數據的大小,該數據的指針最終會賦值給snd_card的private_data數據成員

          card 返回所創建的snd_card實例的指針

          2.1.2. 第二步,創建聲卡的芯片專用數據

          聲卡的專用數據主要用于存放該聲卡的一些資源信息,例如中斷資源、io資源、dma資源等。可以有兩種創建方法:

          通過上一步中snd_card_create()中的第四個參數,讓snd_card_create自己創建

          // struct mychip 用于保存專用數據

          err = snd_card_create(index, id, THIS_MODULE,

          sizeof(struct mychip), &card);

          // 從private_data中取出

          struct mychip *chip = card->private_data;

          自己創建:

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

          // 專用數據記錄snd_card實例

          chip->card = card;

          .....

          然后,把芯片的專有數據注冊為聲卡的一個低階設備:

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

          注冊為低階設備主要是為了當聲卡被注銷時,芯片專用數據所占用的內存可以被自動地釋放。

          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字段保存著芯片的ID字符串,user空間的alsa-lib會使用到該字符串,所以必須要保證該ID的唯一性。shortname字段更多地用于打印信息,longname字段則會出現在/proc/asound/cards中。


        上一頁 1 2 下一頁

        關鍵詞: Linux ALSA

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 大兴区| 霞浦县| 抚顺市| 九江市| 科尔| 博罗县| 车致| 新巴尔虎左旗| 罗定市| 且末县| 绩溪县| 浠水县| 宁南县| 志丹县| 新宾| 潼关县| 靖边县| 遵义县| 延安市| 永仁县| 乐业县| 东辽县| 西城区| 垫江县| 遂昌县| 邯郸市| 墨脱县| 建德市| 体育| 利辛县| 大英县| 嘉峪关市| 栖霞市| 宜君县| 翁牛特旗| 太湖县| 博爱县| 潮安县| 永仁县| 富顺县| 改则县|