Home >Database >Mysql Tutorial >谈谈alsa-lib和驱动自身对kctl.info什么时候赋值的

谈谈alsa-lib和驱动自身对kctl.info什么时候赋值的

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOriginal
2016-06-07 15:05:291426browse

谈谈 kctl.info 什么 时候 赋值 为snd_ctl_elem_user_info的 可以是alsa-lib库调用接口添加 应用层 static const snd_ctl_ops_t snd_ctl_hw_ops = { ... .element_add = snd_ctl_hw_elem_add, .element_replace = snd_ctl_hw_elem_replace, ... }; 内核层 sn

谈谈kctl.info什么时候赋值为snd_ctl_elem_user_info的

可以是alsa-lib库调用接口添加
应用层
static const snd_ctl_ops_t snd_ctl_hw_ops = {
    ...
.element_add = snd_ctl_hw_elem_add,
.element_replace = snd_ctl_hw_elem_replace,
    ...
};
内核层
snd_ctl_elem_add_user
snd_ctl_elem_add
kctl.info = snd_ctl_elem_user_info;

也可以是kernel自动添加,其中wm8991_snd_controls就是使用下面的SOC_SINGLE,SOC_SINGLE_TLV等宏定义的数组
snd_ctl_add(codec->card, snd_soc_cnew(&wm8991_snd_controls[i],codec, NULL));
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
    void *data, char *long_name);
==> snd_ctl_new1
===> kctl.info = ncontrol->info;

下面都有内置的.info方法实现
/*
 * Convenience kcontrol builders
 */
#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
    ((unsigned long)&(struct soc_mixer_control) \
    {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \
    .invert = xinvert})
#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
    ((unsigned long)&(struct soc_mixer_control) \
    {.reg = xreg, .max = xmax, .invert = xinvert})
#define SOC_SINGLE(xname, reg, shift, max, invert) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
    .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
    .put = snd_soc_put_volsw, \
    .private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
#define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
    .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
         SNDRV_CTL_ELEM_ACCESS_READWRITE,\
    .tlv.p = (tlv_array), \
    .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
    .put = snd_soc_put_volsw, \
    .private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
#define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
    .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
    .put = snd_soc_put_volsw, \
    .private_value = (unsigned long)&(struct soc_mixer_control) \
        {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
         .max = xmax, .invert = xinvert} }
#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
    .info = snd_soc_info_volsw_2r, \
    .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
    .private_value = (unsigned long)&(struct soc_mixer_control) \
        {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
        .max = xmax, .invert = xinvert} }
#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
    .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
         SNDRV_CTL_ELEM_ACCESS_READWRITE,\
    .tlv.p = (tlv_array), \
    .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
    .put = snd_soc_put_volsw, \
    .private_value = (unsigned long)&(struct soc_mixer_control) \
        {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
         .max = xmax, .invert = xinvert} }
#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
    .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
         SNDRV_CTL_ELEM_ACCESS_READWRITE,\
    .tlv.p = (tlv_array), \
    .info = snd_soc_info_volsw_2r, \
    .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
    .private_value = (unsigned long)&(struct soc_mixer_control) \
        {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
        .max = xmax, .invert = xinvert} }
#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
{    .iface  = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
    .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
          SNDRV_CTL_ELEM_ACCESS_READWRITE, \
    .tlv.p  = (tlv_array), \
    .info   = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
    .put    = snd_soc_put_volsw_s8, \
    .private_value = (unsigned long)&(struct soc_mixer_control) \
        {.reg = xreg, .min = xmin, .max = xmax} }
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
{    .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
    .max = xmax, .texts = xtexts }
#define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
    SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
{    .max = xmax, .texts = xtexts }
#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xmax, xtexts, xvalues) \
{    .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
    .mask = xmask, .max = xmax, .texts = xtexts, .values = xvalues}
#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xmax, xtexts, xvalues) \
    SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
#define SOC_ENUM(xname, xenum) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
    .info = snd_soc_info_enum_double, \
    .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
    .private_value = (unsigned long)&xenum }
#define SOC_VALUE_ENUM(xname, xenum) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
    .info = snd_soc_info_enum_double, \
    .get = snd_soc_get_value_enum_double, \
    .put = snd_soc_put_value_enum_double, \
    .private_value = (unsigned long)&xenum }
#define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
     xhandler_get, xhandler_put) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
    .info = snd_soc_info_volsw, \
    .get = xhandler_get, .put = xhandler_put, \
    .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\
     xhandler_get, xhandler_put) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
    .info = snd_soc_info_volsw, \
    .get = xhandler_get, .put = xhandler_put, \
    .private_value = (unsigned long)&(struct soc_mixer_control) \
        {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
         .max = xmax, .invert = xinvert} }
#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
     xhandler_get, xhandler_put, tlv_array) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
    .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
         SNDRV_CTL_ELEM_ACCESS_READWRITE,\
    .tlv.p = (tlv_array), \
    .info = snd_soc_info_volsw, \
    .get = xhandler_get, .put = xhandler_put, \
    .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
    .info = snd_soc_info_bool_ext, \
    .get = xhandler_get, .put = xhandler_put, \
    .private_value = xdata }
#define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
{    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
    .info = snd_soc_info_enum_ext, \
    .get = xhandler_get, .put = xhandler_put, \
    .private_value = (unsigned long)&xenum }

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:jsp登录界面+accessNext article:数据库程序员 情书