加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

ALSA在Linux3.1上的一些完善

发布时间:2021-12-17 19:31:25 所属栏目:PHP教程 来源:互联网
导读:Android迈进了4.0,相应的Linux内核也进入了3.x时代。之后的一个工作估计要将2.6.32的驱动移植到3.x上面来。因此趁现在有空,看看alsa在这方面有什么改动。 总的来说,架构大的改动是不大可能的。codec中几个关键结构体没有大的变化,如snd_soc_dai_ops、snd

Android迈进了4.0,相应的Linux内核也进入了3.x时代。之后的一个工作估计要将2.6.32的驱动移植到3.x上面来。因此趁现在有空,看看alsa在这方面有什么改动。
 
总的来说,架构大的改动是不大可能的。codec中几个关键结构体没有大的变化,如snd_soc_dai_ops、snd_soc_dai_driver(相当于2.6.32中的snd_soc_dai),倒是以前的snd_soc_codec_device重定义为snd_soc_codec_driver,这个算是最明显的。
 
 
 
注册用结构体-snd_soc_codec_driver
 
 
2.6.32:
 
[cpp]
/* codec device */  
struct snd_soc_codec_device {  
    int (*probe)(struct platform_device *pdev);  
    int (*remove)(struct platform_device *pdev);  
    int (*suspend)(struct platform_device *pdev, pm_message_t state);  
    int (*resume)(struct platform_device *pdev);  
};  
3.1.1:
[cpp]
/* codec driver */  
struct snd_soc_codec_driver {  
  
    /* driver ops */  
    int (*probe)(struct snd_soc_codec *);  
    int (*remove)(struct snd_soc_codec *);  
    int (*suspend)(struct snd_soc_codec *,  
            pm_message_t state);  
    int (*resume)(struct snd_soc_codec *);  
  
    /* Default control and setup, added after probe() is run */  
    const struct snd_kcontrol_new *controls;  
    int num_controls;  
    const struct snd_soc_dapm_widget *dapm_widgets;  
    int num_dapm_widgets;  
    const struct snd_soc_dapm_route *dapm_routes;  
    int num_dapm_routes;  
  
    /* codec wide operations */  
    int (*set_sysclk)(struct snd_soc_codec *codec,  
              int clk_id, unsigned int freq, int dir);  
    int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,  
        unsigned int freq_in, unsigned int freq_out);  
  
    /* codec IO */  
    unsigned int (*read)(struct snd_soc_codec *, unsigned int);  
    int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);  
    int (*display_register)(struct snd_soc_codec *, char *,  
                size_t, unsigned int);  
    int (*volatile_register)(struct snd_soc_codec *, unsigned int);  
    int (*readable_register)(struct snd_soc_codec *, unsigned int);  
    int (*writable_register)(struct snd_soc_codec *, unsigned int);  
    short reg_cache_size;  
    short reg_cache_step;  
    short reg_word_size;  
    const void *reg_cache_default;  
    short reg_access_size;  
    const struct snd_soc_reg_access *reg_access_default;  
    enum snd_soc_compress_type compress_type;  
  
    /* codec bias level */  
    int (*set_bias_level)(struct snd_soc_codec *,  
                  enum snd_soc_bias_level level);  
  
    void (*seq_notifier)(struct snd_soc_dapm_context *,  
                 enum snd_soc_dapm_type, int);  
  
    /* probe ordering - for components with runtime dependencies */  
    int probe_order;  
    int remove_order;  
};  
位于snd_soc_codec_driver中的一些codec IO成员函数和set_bias_level回调函数原来都放在另外一个结构体snd_soc_codec中,现在放置在这里了,这是根据源码结构调整的结果。事实真正需要设置的成员也不是很多,如下:
 
[cpp]
static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {  
    .probe =    wm9713_soc_probe,  
    .remove =   wm9713_soc_remove,  
    .suspend =  wm9713_soc_suspend,  
    .resume =   wm9713_soc_resume,  
    .read = ac97_read,  
    .write = ac97_write,  
    .set_bias_level = wm9713_set_bias_level,  
    .reg_cache_size = ARRAY_SIZE(wm9713_reg),  
    .reg_word_size = sizeof(u16),  
    .reg_cache_step = 2,  
    .reg_cache_default = wm9713_reg,  
    .dapm_widgets = wm9713_dapm_widgets,  
    .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),  
    .dapm_routes = wm9713_audio_map,  
    .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),  
};  
probe、remove、suspend、resume相信不用累述了,volatile_register函数判断指定的寄存器是否volatile,reg_cache_size一般为寄存器数目,reg_word_size为寄存器的字长,reg_cache_default为寄存器默认值配置表。
 
而dapm_widgets、dapm_routes就比较“犀利”了。之前的dapm widgets和routes分别通过函数snd_soc_dapm_new_controls和snd_soc_dapm_add_routes来注册的(当然现在还保留这些接口),现在则可以填入到这个结构体,在soc-core里注册,省了不少功夫:
 
[cpp]
static int soc_probe_codec(struct snd_soc_card *card,  
               struct snd_soc_codec *codec)  
{  
    //...   
  
    if (driver->dapm_widgets)  
        snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,  
                      driver->num_dapm_widgets);  
  
    //...   
  
    if (driver->controls)  
        snd_soc_add_controls(codec, driver->controls,  
                     driver->num_controls);  
    if (driver->dapm_routes)  
        snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,  
                    driver->num_dapm_routes);  
    //...   
}  
 
 
同时可看到dirver ops的函数参数有所不同了,以前是struct platform_device *pdev,现在改为struct snd_soc_codec *codec,这个与codec的注册函数snd_soc_register_codec和设备的drvdata有关,之后会逐一分析。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读