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

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

parent ce216cfa
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -694,6 +694,23 @@ static int sof_ipc3_widget_kcontrol_setup(struct snd_sof_dev *sdev,
	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 = {
	.volume_put = sof_ipc3_volume_put,
	.volume_get = sof_ipc3_volume_get,
@@ -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,
	.update = sof_ipc3_control_update,
	.widget_kcontrol_setup = sof_ipc3_widget_kcontrol_setup,
	.set_up_volume_table = sof_ipc3_set_up_volume_table,
};
+6 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@
 */
#define VOLUME_FWL	16

#define SOF_TLV_ITEMS 3

struct snd_sof_widget;
struct snd_sof_route;
struct snd_sof_control;
@@ -88,6 +90,9 @@ struct sof_ipc_tplg_control_ops {
	void (*update)(struct snd_sof_dev *sdev, void *ipc_control_message);
	/* Optional callback to setup kcontrols associated with an 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
			  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,
				    struct snd_sof_pcm *spcm, int dir);
u32 vol_compute_gain(u32 value, int *tlv);
#endif
+11 −15
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@
#define VOL_HALF_DB_STEP	50

/* TLV data items */
#define TLV_ITEMS	3
#define TLV_MIN		0
#define TLV_STEP	1
#define TLV_MUTE	2
@@ -134,7 +133,7 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so
	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 */
	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)
 * Function to calculate volume gain from TLV data.
 * 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;
	u32 linear_gain;
@@ -263,20 +262,17 @@ static u32 vol_compute_gain(u32 value, int *tlv)
 * "size" specifies the number of entries in the table
 */
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;

	/* init the volume table */
	scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL);
	if (!scontrol->volume_table)
		return -ENOMEM;
	struct snd_soc_component *scomp = scontrol->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;

	/* populate the volume table */
	for (j = 0; j < size ; j++)
		scontrol->volume_table[j] = vol_compute_gain(j, tlv);
	if (tplg_ops->control->set_up_volume_table)
		return tplg_ops->control->set_up_volume_table(scontrol, tlv, size);

	return 0;
	dev_err(scomp->dev, "Mandatory op %s not set\n", __func__);
	return -EINVAL;
}

struct sof_dai_types {
@@ -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_soc_tplg_mixer_control *mc =
		container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
	int tlv[TLV_ITEMS];
	int tlv[SOF_TLV_ITEMS];
	unsigned int mask;
	int ret;