Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // This file is provided under a dual BSD/GPLv2 license.  When using or
0004 // redistributing this file, you may do so under either license.
0005 //
0006 // Copyright(c) 2018 Intel Corporation. All rights reserved.
0007 //
0008 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
0009 //
0010 
0011 /* Mixer Controls */
0012 
0013 #include <linux/pm_runtime.h>
0014 #include <linux/leds.h>
0015 #include "sof-priv.h"
0016 #include "sof-audio.h"
0017 
0018 int snd_sof_volume_get(struct snd_kcontrol *kcontrol,
0019                struct snd_ctl_elem_value *ucontrol)
0020 {
0021     struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
0022     struct snd_sof_control *scontrol = sm->dobj.private;
0023     struct snd_soc_component *scomp = scontrol->scomp;
0024     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0025     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0026 
0027     if (tplg_ops->control->volume_get)
0028         return tplg_ops->control->volume_get(scontrol, ucontrol);
0029 
0030     return 0;
0031 }
0032 
0033 int snd_sof_volume_put(struct snd_kcontrol *kcontrol,
0034                struct snd_ctl_elem_value *ucontrol)
0035 {
0036     struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
0037     struct snd_sof_control *scontrol = sm->dobj.private;
0038     struct snd_soc_component *scomp = scontrol->scomp;
0039     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0040     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0041 
0042     if (tplg_ops->control->volume_put)
0043         return tplg_ops->control->volume_put(scontrol, ucontrol);
0044 
0045     return false;
0046 }
0047 
0048 int snd_sof_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0049 {
0050     struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
0051     struct snd_sof_control *scontrol = sm->dobj.private;
0052     unsigned int channels = scontrol->num_channels;
0053     int platform_max;
0054 
0055     if (!sm->platform_max)
0056         sm->platform_max = sm->max;
0057     platform_max = sm->platform_max;
0058 
0059     if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
0060         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
0061     else
0062         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0063 
0064     uinfo->count = channels;
0065     uinfo->value.integer.min = 0;
0066     uinfo->value.integer.max = platform_max - sm->min;
0067     return 0;
0068 }
0069 
0070 int snd_sof_switch_get(struct snd_kcontrol *kcontrol,
0071                struct snd_ctl_elem_value *ucontrol)
0072 {
0073     struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
0074     struct snd_sof_control *scontrol = sm->dobj.private;
0075     struct snd_soc_component *scomp = scontrol->scomp;
0076     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0077     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0078 
0079     if (tplg_ops->control->switch_get)
0080         return tplg_ops->control->switch_get(scontrol, ucontrol);
0081 
0082     return 0;
0083 }
0084 
0085 int snd_sof_switch_put(struct snd_kcontrol *kcontrol,
0086                struct snd_ctl_elem_value *ucontrol)
0087 {
0088     struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
0089     struct snd_sof_control *scontrol = sm->dobj.private;
0090     struct snd_soc_component *scomp = scontrol->scomp;
0091     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0092     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0093 
0094     if (tplg_ops->control->switch_put)
0095         return tplg_ops->control->switch_put(scontrol, ucontrol);
0096 
0097     return false;
0098 }
0099 
0100 int snd_sof_enum_get(struct snd_kcontrol *kcontrol,
0101              struct snd_ctl_elem_value *ucontrol)
0102 {
0103     struct soc_enum *se = (struct soc_enum *)kcontrol->private_value;
0104     struct snd_sof_control *scontrol = se->dobj.private;
0105     struct snd_soc_component *scomp = scontrol->scomp;
0106     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0107     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0108 
0109     if (tplg_ops->control->enum_get)
0110         return tplg_ops->control->enum_get(scontrol, ucontrol);
0111 
0112     return 0;
0113 }
0114 
0115 int snd_sof_enum_put(struct snd_kcontrol *kcontrol,
0116              struct snd_ctl_elem_value *ucontrol)
0117 {
0118     struct soc_enum *se = (struct soc_enum *)kcontrol->private_value;
0119     struct snd_sof_control *scontrol = se->dobj.private;
0120     struct snd_soc_component *scomp = scontrol->scomp;
0121     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0122     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0123 
0124     if (tplg_ops->control->enum_put)
0125         return tplg_ops->control->enum_put(scontrol, ucontrol);
0126 
0127     return false;
0128 }
0129 
0130 int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
0131               struct snd_ctl_elem_value *ucontrol)
0132 {
0133     struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
0134     struct snd_sof_control *scontrol = be->dobj.private;
0135     struct snd_soc_component *scomp = scontrol->scomp;
0136     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0137     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0138 
0139     if (tplg_ops->control->bytes_get)
0140         return tplg_ops->control->bytes_get(scontrol, ucontrol);
0141 
0142     return 0;
0143 }
0144 
0145 int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
0146               struct snd_ctl_elem_value *ucontrol)
0147 {
0148     struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
0149     struct snd_sof_control *scontrol = be->dobj.private;
0150     struct snd_soc_component *scomp = scontrol->scomp;
0151     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0152     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0153 
0154     if (tplg_ops->control->bytes_put)
0155         return tplg_ops->control->bytes_put(scontrol, ucontrol);
0156 
0157     return 0;
0158 }
0159 
0160 int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
0161               const unsigned int __user *binary_data,
0162               unsigned int size)
0163 {
0164     struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
0165     struct snd_sof_control *scontrol = be->dobj.private;
0166     struct snd_soc_component *scomp = scontrol->scomp;
0167     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0168     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0169 
0170     /* make sure we have at least a header */
0171     if (size < sizeof(struct snd_ctl_tlv))
0172         return -EINVAL;
0173 
0174     if (tplg_ops->control->bytes_ext_put)
0175         return tplg_ops->control->bytes_ext_put(scontrol, binary_data, size);
0176 
0177     return 0;
0178 }
0179 
0180 int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data,
0181                    unsigned int size)
0182 {
0183     struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
0184     struct snd_sof_control *scontrol = be->dobj.private;
0185     struct snd_soc_component *scomp = scontrol->scomp;
0186     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0187     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0188     int ret, err;
0189 
0190     ret = pm_runtime_resume_and_get(scomp->dev);
0191     if (ret < 0 && ret != -EACCES) {
0192         dev_err_ratelimited(scomp->dev, "%s: failed to resume %d\n", __func__, ret);
0193         return ret;
0194     }
0195 
0196     if (tplg_ops->control->bytes_ext_volatile_get)
0197         ret = tplg_ops->control->bytes_ext_volatile_get(scontrol, binary_data, size);
0198 
0199     pm_runtime_mark_last_busy(scomp->dev);
0200     err = pm_runtime_put_autosuspend(scomp->dev);
0201     if (err < 0)
0202         dev_err_ratelimited(scomp->dev, "%s: failed to idle %d\n", __func__, err);
0203 
0204     return ret;
0205 }
0206 
0207 int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
0208               unsigned int __user *binary_data,
0209               unsigned int size)
0210 {
0211     struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
0212     struct snd_sof_control *scontrol = be->dobj.private;
0213     struct snd_soc_component *scomp = scontrol->scomp;
0214     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0215     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0216 
0217     if (tplg_ops->control->bytes_ext_get)
0218         return tplg_ops->control->bytes_ext_get(scontrol, binary_data, size);
0219 
0220     return 0;
0221 }