zoukankan      html  css  js  c++  java
  • alsa声卡分析alsa-utils调用过程(二)-tinymixer

    继上一篇文章:http://www.cnblogs.com/linhaostudy/p/8515277.html

    三、tinymixer调用分析:(tinymixer.log搜索节点:/dev/snd/controlCx)

    还是一样,系统调用从应用层到kernel层,都要通过VFS来到file_operations;

    我们使用tinymixer "SEC_MI2S_RX Audio Mixer MultiMedia1" 1打开通道看一下相应的流程;

    log中的open("/dev/snd_controlCx")中对应的file_operations中:

     1 /*
     2  *  INIT PART
     3  */
     4 
     5 static const struct file_operations snd_ctl_f_ops =
     6 {
     7     .owner =    THIS_MODULE,
     8     .read =        snd_ctl_read,
     9     .open =        snd_ctl_open,
    10     .release =    snd_ctl_release,
    11     .llseek =    no_llseek,
    12     .poll =        snd_ctl_poll,
    13     .unlocked_ioctl =    snd_ctl_ioctl,
    14     .compat_ioctl =    snd_ctl_ioctl_compat,
    15     .fasync =    snd_ctl_fasync,
    16 };

     tinymixer首先先调用open操作函数集;也就是snd_ctl_open打开control逻辑设备;

    我们主要分析ioctl函数,由file_operations来到snd_ctl_ioctl函数中来:

     1 static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
     2 {
     3     struct snd_ctl_file *ctl;
     4     struct snd_card *card;
     5     struct snd_kctl_ioctl *p;
     6     void __user *argp = (void __user *)arg;
     7     int __user *ip = argp;
     8     int err;
     9 
    10     ctl = file->private_data;
    11     card = ctl->card;
    12     if (snd_BUG_ON(!card))
    13         return -ENXIO;
    14     switch (cmd) {
    15     case SNDRV_CTL_IOCTL_PVERSION:
    16         return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
    17     case SNDRV_CTL_IOCTL_CARD_INFO:
    18         return snd_ctl_card_info(card, ctl, cmd, argp);
    19     case SNDRV_CTL_IOCTL_ELEM_LIST:
    20         return snd_ctl_elem_list(card, argp);
    21     case SNDRV_CTL_IOCTL_ELEM_INFO:
    22         return snd_ctl_elem_info_user(ctl, argp);
    23     case SNDRV_CTL_IOCTL_ELEM_READ:
    24         return snd_ctl_elem_read_user(card, argp);
    25     case SNDRV_CTL_IOCTL_ELEM_WRITE:
    26         return snd_ctl_elem_write_user(ctl, argp);
    27     case SNDRV_CTL_IOCTL_ELEM_LOCK:
    28         return snd_ctl_elem_lock(ctl, argp);
    29     case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
    30         return snd_ctl_elem_unlock(ctl, argp);
    31     case SNDRV_CTL_IOCTL_ELEM_ADD:
    32         return snd_ctl_elem_add_user(ctl, argp, 0);
    33     case SNDRV_CTL_IOCTL_ELEM_REPLACE:
    34         return snd_ctl_elem_add_user(ctl, argp, 1);
    35     case SNDRV_CTL_IOCTL_ELEM_REMOVE:
    36         return snd_ctl_elem_remove(ctl, argp);
    37     case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
    38         return snd_ctl_subscribe_events(ctl, ip);
    39     case SNDRV_CTL_IOCTL_TLV_READ:
    40         return snd_ctl_tlv_ioctl(ctl, argp, 0);
    41     case SNDRV_CTL_IOCTL_TLV_WRITE:
    42         return snd_ctl_tlv_ioctl(ctl, argp, 1);
    43     case SNDRV_CTL_IOCTL_TLV_COMMAND:
    44         return snd_ctl_tlv_ioctl(ctl, argp, -1);
    45     case SNDRV_CTL_IOCTL_POWER:
    46         return -ENOPROTOOPT;
    47     case SNDRV_CTL_IOCTL_POWER_STATE:
    48 #ifdef CONFIG_PM
    49         return put_user(card->power_state, ip) ? -EFAULT : 0;
    50 #else
    51         return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
    52 #endif
    53     }
    54     down_read(&snd_ioctl_rwsem);
    55     list_for_each_entry(p, &snd_control_ioctls, list) {
    56         err = p->fioctl(card, ctl, cmd, arg);
    57         if (err != -ENOIOCTLCMD) {
    58             up_read(&snd_ioctl_rwsem);
    59             return err;
    60         }
    61     }
    62     up_read(&snd_ioctl_rwsem);
    63     snd_printdd("unknown ioctl = 0x%x
    ", cmd);
    64     return -ENOTTY;
    65 }

    通过tinymixer.log搜索ioctl可以看到,进入:

    1 case SNDRV_CTL_IOCTL_ELEM_WRITE:
    2         return snd_ctl_elem_write_user(ctl, argp);

    相应流程如下:

    |->snd_ctl_ioctl  
       |->snd_ctl_elem_write_user  
         |->snd_ctl_elem_wirte  
           |->kctl->put  
              |=snd_soc_dapm_put_volsw  
                |->snd_soc_dapm_mixer_update_power//找到使用这个kcontrol的path,根据该kcontrol的值来更新path的connect状态  
                   //更新path->connect状态

    kcontrol、dapm widget、route/path创建与注册和它们之间的关系可以见:

    ALSA声卡驱动的DAPM(一)-DPAM详解

    ALSA声卡驱动的DAPM(二)-建立过程

  • 相关阅读:
    Netty学习路线总结
    Intellij IDEA 快捷键整理-鬼畜版(全键盘开发指南)
    httpClient
    [翻译]Javaslang 介绍
    Docker学习<一>--初体验Windows环境下安装
    Spring @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
    IntelliJ IDEA 2016.2激活方法
    解决mac升级后,出现的 xcrun: error: invalid active developer path, missing xcrun 错误
    Logstash 安装与配置
    【JVM学习笔记】双亲委托机制存在的意义
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/8533591.html
Copyright © 2011-2022 走看看