Commit 48d2a1ce authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown

ASoC: SOF: Add a new op to set up volume table

Add a new op set_up_volume_table for control IPC ops. Define and set
the op for IPC3.
Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20220426171743.171061-2-ranjani.sridharan@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent ce216cfa
...@@ -694,6 +694,23 @@ static int sof_ipc3_widget_kcontrol_setup(struct snd_sof_dev *sdev, ...@@ -694,6 +694,23 @@ static int sof_ipc3_widget_kcontrol_setup(struct snd_sof_dev *sdev,
return 0; return 0;
} }
static int
sof_ipc3_set_up_volume_table(struct snd_sof_control *scontrol, int tlv[SOF_TLV_ITEMS], int size)
{
int i;
/* init the volume table */
scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL);
if (!scontrol->volume_table)
return -ENOMEM;
/* populate the volume table */
for (i = 0; i < size ; i++)
scontrol->volume_table[i] = vol_compute_gain(i, tlv);
return 0;
}
const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = { const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = {
.volume_put = sof_ipc3_volume_put, .volume_put = sof_ipc3_volume_put,
.volume_get = sof_ipc3_volume_get, .volume_get = sof_ipc3_volume_get,
...@@ -708,4 +725,5 @@ const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = { ...@@ -708,4 +725,5 @@ const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = {
.bytes_ext_volatile_get = sof_ipc3_bytes_ext_volatile_get, .bytes_ext_volatile_get = sof_ipc3_bytes_ext_volatile_get,
.update = sof_ipc3_control_update, .update = sof_ipc3_control_update,
.widget_kcontrol_setup = sof_ipc3_widget_kcontrol_setup, .widget_kcontrol_setup = sof_ipc3_widget_kcontrol_setup,
.set_up_volume_table = sof_ipc3_set_up_volume_table,
}; };
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
*/ */
#define VOLUME_FWL 16 #define VOLUME_FWL 16
#define SOF_TLV_ITEMS 3
struct snd_sof_widget; struct snd_sof_widget;
struct snd_sof_route; struct snd_sof_route;
struct snd_sof_control; struct snd_sof_control;
...@@ -88,6 +90,9 @@ struct sof_ipc_tplg_control_ops { ...@@ -88,6 +90,9 @@ struct sof_ipc_tplg_control_ops {
void (*update)(struct snd_sof_dev *sdev, void *ipc_control_message); void (*update)(struct snd_sof_dev *sdev, void *ipc_control_message);
/* Optional callback to setup kcontrols associated with an swidget */ /* Optional callback to setup kcontrols associated with an swidget */
int (*widget_kcontrol_setup)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget); int (*widget_kcontrol_setup)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget);
/* mandatory callback to set up volume table for volume kcontrols */
int (*set_up_volume_table)(struct snd_sof_control *scontrol, int tlv[SOF_TLV_ITEMS],
int size);
}; };
/** /**
...@@ -463,4 +468,5 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so ...@@ -463,4 +468,5 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so
size_t object_size, int token_instance_num); size_t object_size, int token_instance_num);
int sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_runtime *rtd, int sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_runtime *rtd,
struct snd_sof_pcm *spcm, int dir); struct snd_sof_pcm *spcm, int dir);
u32 vol_compute_gain(u32 value, int *tlv);
#endif #endif
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#define VOL_HALF_DB_STEP 50 #define VOL_HALF_DB_STEP 50
/* TLV data items */ /* TLV data items */
#define TLV_ITEMS 3
#define TLV_MIN 0 #define TLV_MIN 0
#define TLV_STEP 1 #define TLV_STEP 1
#define TLV_MUTE 2 #define TLV_MUTE 2
...@@ -134,7 +133,7 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so ...@@ -134,7 +133,7 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so
return 0; return 0;
} }
static inline int get_tlv_data(const int *p, int tlv[TLV_ITEMS]) static inline int get_tlv_data(const int *p, int tlv[SOF_TLV_ITEMS])
{ {
/* we only support dB scale TLV type at the moment */ /* we only support dB scale TLV type at the moment */
if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE) if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
...@@ -224,7 +223,7 @@ static u32 vol_pow32(u32 a, int exp, u32 fwl) ...@@ -224,7 +223,7 @@ static u32 vol_pow32(u32 a, int exp, u32 fwl)
* Function to calculate volume gain from TLV data. * Function to calculate volume gain from TLV data.
* This function can only handle gain steps that are multiples of 0.5 dB * This function can only handle gain steps that are multiples of 0.5 dB
*/ */
static u32 vol_compute_gain(u32 value, int *tlv) u32 vol_compute_gain(u32 value, int *tlv)
{ {
int dB_gain; int dB_gain;
u32 linear_gain; u32 linear_gain;
...@@ -263,20 +262,17 @@ static u32 vol_compute_gain(u32 value, int *tlv) ...@@ -263,20 +262,17 @@ static u32 vol_compute_gain(u32 value, int *tlv)
* "size" specifies the number of entries in the table * "size" specifies the number of entries in the table
*/ */
static int set_up_volume_table(struct snd_sof_control *scontrol, static int set_up_volume_table(struct snd_sof_control *scontrol,
int tlv[TLV_ITEMS], int size) int tlv[SOF_TLV_ITEMS], int size)
{ {
int j; struct snd_soc_component *scomp = scontrol->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
/* init the volume table */ const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL);
if (!scontrol->volume_table)
return -ENOMEM;
/* populate the volume table */ if (tplg_ops->control->set_up_volume_table)
for (j = 0; j < size ; j++) return tplg_ops->control->set_up_volume_table(scontrol, tlv, size);
scontrol->volume_table[j] = vol_compute_gain(j, tlv);
return 0; dev_err(scomp->dev, "Mandatory op %s not set\n", __func__);
return -EINVAL;
} }
struct sof_dai_types { struct sof_dai_types {
...@@ -772,7 +768,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, ...@@ -772,7 +768,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp,
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct snd_soc_tplg_mixer_control *mc = struct snd_soc_tplg_mixer_control *mc =
container_of(hdr, struct snd_soc_tplg_mixer_control, hdr); container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
int tlv[TLV_ITEMS]; int tlv[SOF_TLV_ITEMS];
unsigned int mask; unsigned int mask;
int ret; int ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment