cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

control.c (7539B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2//
      3// This file is provided under a dual BSD/GPLv2 license.  When using or
      4// redistributing this file, you may do so under either license.
      5//
      6// Copyright(c) 2018 Intel Corporation. All rights reserved.
      7//
      8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
      9//
     10
     11/* Mixer Controls */
     12
     13#include <linux/pm_runtime.h>
     14#include <linux/leds.h>
     15#include "sof-priv.h"
     16#include "sof-audio.h"
     17
     18int snd_sof_volume_get(struct snd_kcontrol *kcontrol,
     19		       struct snd_ctl_elem_value *ucontrol)
     20{
     21	struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
     22	struct snd_sof_control *scontrol = sm->dobj.private;
     23	struct snd_soc_component *scomp = scontrol->scomp;
     24	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
     25	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
     26
     27	if (tplg_ops->control->volume_get)
     28		return tplg_ops->control->volume_get(scontrol, ucontrol);
     29
     30	return 0;
     31}
     32
     33int snd_sof_volume_put(struct snd_kcontrol *kcontrol,
     34		       struct snd_ctl_elem_value *ucontrol)
     35{
     36	struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
     37	struct snd_sof_control *scontrol = sm->dobj.private;
     38	struct snd_soc_component *scomp = scontrol->scomp;
     39	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
     40	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
     41
     42	if (tplg_ops->control->volume_put)
     43		return tplg_ops->control->volume_put(scontrol, ucontrol);
     44
     45	return false;
     46}
     47
     48int snd_sof_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
     49{
     50	struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
     51	struct snd_sof_control *scontrol = sm->dobj.private;
     52	unsigned int channels = scontrol->num_channels;
     53	int platform_max;
     54
     55	if (!sm->platform_max)
     56		sm->platform_max = sm->max;
     57	platform_max = sm->platform_max;
     58
     59	if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
     60		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
     61	else
     62		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
     63
     64	uinfo->count = channels;
     65	uinfo->value.integer.min = 0;
     66	uinfo->value.integer.max = platform_max - sm->min;
     67	return 0;
     68}
     69
     70int snd_sof_switch_get(struct snd_kcontrol *kcontrol,
     71		       struct snd_ctl_elem_value *ucontrol)
     72{
     73	struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
     74	struct snd_sof_control *scontrol = sm->dobj.private;
     75	struct snd_soc_component *scomp = scontrol->scomp;
     76	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
     77	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
     78
     79	if (tplg_ops->control->switch_get)
     80		return tplg_ops->control->switch_get(scontrol, ucontrol);
     81
     82	return 0;
     83}
     84
     85int snd_sof_switch_put(struct snd_kcontrol *kcontrol,
     86		       struct snd_ctl_elem_value *ucontrol)
     87{
     88	struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value;
     89	struct snd_sof_control *scontrol = sm->dobj.private;
     90	struct snd_soc_component *scomp = scontrol->scomp;
     91	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
     92	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
     93
     94	if (tplg_ops->control->switch_put)
     95		return tplg_ops->control->switch_put(scontrol, ucontrol);
     96
     97	return false;
     98}
     99
    100int snd_sof_enum_get(struct snd_kcontrol *kcontrol,
    101		     struct snd_ctl_elem_value *ucontrol)
    102{
    103	struct soc_enum *se = (struct soc_enum *)kcontrol->private_value;
    104	struct snd_sof_control *scontrol = se->dobj.private;
    105	struct snd_soc_component *scomp = scontrol->scomp;
    106	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    107	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    108
    109	if (tplg_ops->control->enum_get)
    110		return tplg_ops->control->enum_get(scontrol, ucontrol);
    111
    112	return 0;
    113}
    114
    115int snd_sof_enum_put(struct snd_kcontrol *kcontrol,
    116		     struct snd_ctl_elem_value *ucontrol)
    117{
    118	struct soc_enum *se = (struct soc_enum *)kcontrol->private_value;
    119	struct snd_sof_control *scontrol = se->dobj.private;
    120	struct snd_soc_component *scomp = scontrol->scomp;
    121	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    122	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    123
    124	if (tplg_ops->control->enum_put)
    125		return tplg_ops->control->enum_put(scontrol, ucontrol);
    126
    127	return false;
    128}
    129
    130int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
    131		      struct snd_ctl_elem_value *ucontrol)
    132{
    133	struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
    134	struct snd_sof_control *scontrol = be->dobj.private;
    135	struct snd_soc_component *scomp = scontrol->scomp;
    136	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    137	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    138
    139	if (tplg_ops->control->bytes_get)
    140		return tplg_ops->control->bytes_get(scontrol, ucontrol);
    141
    142	return 0;
    143}
    144
    145int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
    146		      struct snd_ctl_elem_value *ucontrol)
    147{
    148	struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
    149	struct snd_sof_control *scontrol = be->dobj.private;
    150	struct snd_soc_component *scomp = scontrol->scomp;
    151	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    152	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    153
    154	if (tplg_ops->control->bytes_put)
    155		return tplg_ops->control->bytes_put(scontrol, ucontrol);
    156
    157	return 0;
    158}
    159
    160int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
    161			  const unsigned int __user *binary_data,
    162			  unsigned int size)
    163{
    164	struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
    165	struct snd_sof_control *scontrol = be->dobj.private;
    166	struct snd_soc_component *scomp = scontrol->scomp;
    167	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    168	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    169
    170	/* make sure we have at least a header */
    171	if (size < sizeof(struct snd_ctl_tlv))
    172		return -EINVAL;
    173
    174	if (tplg_ops->control->bytes_ext_put)
    175		return tplg_ops->control->bytes_ext_put(scontrol, binary_data, size);
    176
    177	return 0;
    178}
    179
    180int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data,
    181				   unsigned int size)
    182{
    183	struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
    184	struct snd_sof_control *scontrol = be->dobj.private;
    185	struct snd_soc_component *scomp = scontrol->scomp;
    186	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    187	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    188	int ret, err;
    189
    190	ret = pm_runtime_resume_and_get(scomp->dev);
    191	if (ret < 0 && ret != -EACCES) {
    192		dev_err_ratelimited(scomp->dev, "%s: failed to resume %d\n", __func__, ret);
    193		return ret;
    194	}
    195
    196	if (tplg_ops->control->bytes_ext_volatile_get)
    197		ret = tplg_ops->control->bytes_ext_volatile_get(scontrol, binary_data, size);
    198
    199	pm_runtime_mark_last_busy(scomp->dev);
    200	err = pm_runtime_put_autosuspend(scomp->dev);
    201	if (err < 0)
    202		dev_err_ratelimited(scomp->dev, "%s: failed to idle %d\n", __func__, err);
    203
    204	return ret;
    205}
    206
    207int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
    208			  unsigned int __user *binary_data,
    209			  unsigned int size)
    210{
    211	struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
    212	struct snd_sof_control *scontrol = be->dobj.private;
    213	struct snd_soc_component *scomp = scontrol->scomp;
    214	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
    215	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
    216
    217	if (tplg_ops->control->bytes_ext_get)
    218		return tplg_ops->control->bytes_ext_get(scontrol, binary_data, size);
    219
    220	return 0;
    221}