Android音频驱动-ASOC之Sound Card创建

xiaoxiao2021-02-28  163

static const struct file_operations snd_fops = { .owner = THIS_MODULE, .open = snd_open, .llseek = noop_llseek, }; static int __init alsa_sound_init(void) { snd_major = major; snd_ecards_limit = cards_limit; if (register_chrdev(major, "alsa", &snd_fops)) {//注册声卡主设备,设置声卡的回调函数 pr_err("ALSA core: unable to register native major device number %d\n", major); return -EIO; } if (snd_info_init() < 0) { unregister_chrdev(major, "alsa"); return -ENOMEM; } snd_info_minor_register(); return 0; } int __init snd_info_init(void) { struct proc_dir_entry *p; p = proc_mkdir("asound", NULL);//创建asound根目录 if (p == NULL) return -ENOMEM; snd_proc_root = p; #ifdef CONFIG_SND_OSSEMUL { struct snd_info_entry *entry; if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_oss_root = entry; } #endif #if IS_ENABLED(CONFIG_SND_SEQUENCER) { struct snd_info_entry *entry; if ((entry = snd_info_create_module_entry(THIS_MODULE, "seq", NULL)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_seq_root = entry; } #endif snd_info_version_init(); snd_minor_info_init(); snd_minor_info_oss_init(); snd_card_info_init(); return 0; } static int __init snd_info_version_init(void) { struct snd_info_entry *entry; entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); if (entry == NULL) return -ENOMEM; entry->c.text.read = snd_info_version_read;//读取prc/asound/version显示的信息 if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_info_version_entry = entry; return 0; } static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { snd_iprintf(buffer, "Advanced Linux Sound Architecture Driver Version k%s.\n", init_utsname()->release); } int __init snd_minor_info_init(void) { struct snd_info_entry *entry; entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); if (entry) { entry->c.text.read = snd_minor_info_read;//读取prc/asound/devices显示的信息 if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } snd_minor_info_entry = entry; return 0; } static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { int minor; struct snd_minor *mptr; mutex_lock(&sound_mutex); for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { if (!(mptr = snd_minors[minor])) continue; if (mptr->card >= 0) { if (mptr->device >= 0) snd_iprintf(buffer, "%3i: [%2i-%2i]: %s\n", minor, mptr->card, mptr->device, snd_device_type_name(mptr->type)); else snd_iprintf(buffer, "%3i: [%2i] : %s\n", minor, mptr->card, snd_device_type_name(mptr->type)); } else snd_iprintf(buffer, "%3i: : %s\n", minor, snd_device_type_name(mptr->type)); } mutex_unlock(&sound_mutex); } int __init snd_card_info_init(void) { struct snd_info_entry *entry; entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); if (! entry) return -ENOMEM; entry->c.text.read = snd_card_info_read;//读取prc/asound/cards显示的信息 if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } snd_card_info_entry = entry; return 0; } static void snd_card_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { int idx, count; struct snd_card *card; for (idx = count = 0; idx < SNDRV_CARDS; idx++) { mutex_lock(&snd_card_mutex); if ((card = snd_cards[idx]) != NULL) { count++; snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", idx, card->id, card->driver, card->shortname); snd_iprintf(buffer, " %s\n", card->longname); } mutex_unlock(&snd_card_mutex); } if (!count) snd_iprintf(buffer, "--- no soundcards ---\n"); } int snd_info_minor_register(void) { struct snd_info_entry *entry; memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { entry->c.text.read = snd_sndstat_proc_read;//读取prc/asound/sndstat显示的信息 if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } snd_sndstat_proc_entry = entry; return 0; } static void snd_sndstat_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA emulation code)\n"); snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n", init_utsname()->sysname, init_utsname()->nodename, init_utsname()->release, init_utsname()->version, init_utsname()->machine); snd_iprintf(buffer, "Config options: 0\n"); snd_iprintf(buffer, "\nInstalled drivers: \n"); snd_iprintf(buffer, "Type 10: ALSA emulation\n"); snd_iprintf(buffer, "\nCard config: \n"); snd_card_info_read_oss(buffer); snd_sndstat_show_strings(buffer, "Audio devices", SNDRV_OSS_INFO_DEV_AUDIO); snd_sndstat_show_strings(buffer, "Synth devices", SNDRV_OSS_INFO_DEV_SYNTH); snd_sndstat_show_strings(buffer, "Midi devices", SNDRV_OSS_INFO_DEV_MIDI); snd_sndstat_show_strings(buffer, "Timers", SNDRV_OSS_INFO_DEV_TIMERS); snd_sndstat_show_strings(buffer, "Mixers", SNDRV_OSS_INFO_DEV_MIXERS); } //创建proc/asound/目录下的文件 int snd_info_register(struct snd_info_entry * entry) { struct proc_dir_entry *root, *p = NULL; //root是当前文件的父目录,snd_proc_root等于asound root = entry->parent == NULL ? snd_proc_root : entry->parent->p; if (S_ISDIR(entry->mode)) { p = proc_mkdir_mode(entry->name, entry->mode, root); } else { p = proc_create_data(entry->name, entry->mode, root, &snd_info_entry_operations, entry); proc_set_size(p, entry->size); } entry->p = p; if (entry->parent) list_add_tail(&entry->list, &entry->parent->children); return 0; }

Anroid N:/ # cd proc/asound/ card0/ cards devices hwdep mtsndcard/ oss/ pcm seq/ timers version

转载请注明原文地址: https://www.6miu.com/read-47751.html

最新回复(0)