forked from mirrors/linux
		
	ASoC: Drop soc-topology ABI v4 support
Merge series from Cezary Rojewski <cezary.rojewski@intel.com>: This patchset impacts UAPI. The only known users of the soc-topology ABI v4 are Chromebook configurations. Starting from kernel v5.4, all of them are making use of soc-topology ABI v5. The patchset first removes obsolete code from the Intel's skylake-driver - the driver of choice for the mentioned Chromebooks - and then proceeds with removal of relevant soc-topology.c and uapi bits. Cezary Rojewski (4): ASoC: Intel: Skylake: Remove soc-topology ABI v4 support ASoC: topology: Remove ABI v4 support ASoC: topology: Cleanup after ABI v4 support removal ASoC: topology: Remove obsolete ABI v4 structs include/uapi/sound/asoc.h | 56 ------ include/uapi/sound/skl-tplg-interface.h | 74 -------- sound/soc/intel/skylake/skl-topology.c | 169 ----------------- sound/soc/soc-topology.c | 241 ++---------------------- 4 files changed, 18 insertions(+), 522 deletions(-) -- 2.25.1
This commit is contained in:
		
						commit
						fe4a074542
					
				
					 4 changed files with 18 additions and 522 deletions
				
			
		| 
						 | 
				
			
			@ -576,60 +576,4 @@ struct snd_soc_tplg_dai {
 | 
			
		|||
	struct snd_soc_tplg_private priv;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Old version of ABI structs, supported for backward compatibility.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Manifest v4 */
 | 
			
		||||
struct snd_soc_tplg_manifest_v4 {
 | 
			
		||||
	__le32 size;		/* in bytes of this structure */
 | 
			
		||||
	__le32 control_elems;	/* number of control elements */
 | 
			
		||||
	__le32 widget_elems;	/* number of widget elements */
 | 
			
		||||
	__le32 graph_elems;	/* number of graph elements */
 | 
			
		||||
	__le32 pcm_elems;	/* number of PCM elements */
 | 
			
		||||
	__le32 dai_link_elems;	/* number of DAI link elements */
 | 
			
		||||
	struct snd_soc_tplg_private priv;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
/* Stream Capabilities v4 */
 | 
			
		||||
struct snd_soc_tplg_stream_caps_v4 {
 | 
			
		||||
	__le32 size;		/* in bytes of this structure */
 | 
			
		||||
	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
			
		||||
	__le64 formats;	/* supported formats SNDRV_PCM_FMTBIT_* */
 | 
			
		||||
	__le32 rates;		/* supported rates SNDRV_PCM_RATE_* */
 | 
			
		||||
	__le32 rate_min;	/* min rate */
 | 
			
		||||
	__le32 rate_max;	/* max rate */
 | 
			
		||||
	__le32 channels_min;	/* min channels */
 | 
			
		||||
	__le32 channels_max;	/* max channels */
 | 
			
		||||
	__le32 periods_min;	/* min number of periods */
 | 
			
		||||
	__le32 periods_max;	/* max number of periods */
 | 
			
		||||
	__le32 period_size_min;	/* min period size bytes */
 | 
			
		||||
	__le32 period_size_max;	/* max period size bytes */
 | 
			
		||||
	__le32 buffer_size_min;	/* min buffer size bytes */
 | 
			
		||||
	__le32 buffer_size_max;	/* max buffer size bytes */
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
/* PCM v4 */
 | 
			
		||||
struct snd_soc_tplg_pcm_v4 {
 | 
			
		||||
	__le32 size;		/* in bytes of this structure */
 | 
			
		||||
	char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
			
		||||
	char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
			
		||||
	__le32 pcm_id;		/* unique ID - used to match with DAI link */
 | 
			
		||||
	__le32 dai_id;		/* unique ID - used to match */
 | 
			
		||||
	__le32 playback;	/* supports playback mode */
 | 
			
		||||
	__le32 capture;		/* supports capture mode */
 | 
			
		||||
	__le32 compress;	/* 1 = compressed; 0 = PCM */
 | 
			
		||||
	struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
 | 
			
		||||
	__le32 num_streams;	/* number of streams */
 | 
			
		||||
	struct snd_soc_tplg_stream_caps_v4 caps[2]; /* playback and capture for DAI */
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
/* Physical link config v4 */
 | 
			
		||||
struct snd_soc_tplg_link_config_v4 {
 | 
			
		||||
	__le32 size;            /* in bytes of this structure */
 | 
			
		||||
	__le32 id;              /* unique ID - used to match */
 | 
			
		||||
	struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
 | 
			
		||||
	__le32 num_streams;     /* number of streams */
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,78 +165,4 @@ enum skl_tuple_type {
 | 
			
		|||
	SKL_TYPE_DATA
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* v4 configuration data */
 | 
			
		||||
 | 
			
		||||
struct skl_dfw_v4_module_pin {
 | 
			
		||||
	__u16 module_id;
 | 
			
		||||
	__u16 instance_id;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
struct skl_dfw_v4_module_fmt {
 | 
			
		||||
	__u32 channels;
 | 
			
		||||
	__u32 freq;
 | 
			
		||||
	__u32 bit_depth;
 | 
			
		||||
	__u32 valid_bit_depth;
 | 
			
		||||
	__u32 ch_cfg;
 | 
			
		||||
	__u32 interleaving_style;
 | 
			
		||||
	__u32 sample_type;
 | 
			
		||||
	__u32 ch_map;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
struct skl_dfw_v4_module_caps {
 | 
			
		||||
	__u32 set_params:2;
 | 
			
		||||
	__u32 rsvd:30;
 | 
			
		||||
	__u32 param_id;
 | 
			
		||||
	__u32 caps_size;
 | 
			
		||||
	__u32 caps[HDA_SST_CFG_MAX];
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
struct skl_dfw_v4_pipe {
 | 
			
		||||
	__u8 pipe_id;
 | 
			
		||||
	__u8 pipe_priority;
 | 
			
		||||
	__u16 conn_type:4;
 | 
			
		||||
	__u16 rsvd:4;
 | 
			
		||||
	__u16 memory_pages:8;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
struct skl_dfw_v4_module {
 | 
			
		||||
	char uuid[SKL_UUID_STR_SZ];
 | 
			
		||||
 | 
			
		||||
	__u16 module_id;
 | 
			
		||||
	__u16 instance_id;
 | 
			
		||||
	__u32 max_mcps;
 | 
			
		||||
	__u32 mem_pages;
 | 
			
		||||
	__u32 obs;
 | 
			
		||||
	__u32 ibs;
 | 
			
		||||
	__u32 vbus_id;
 | 
			
		||||
 | 
			
		||||
	__u32 max_in_queue:8;
 | 
			
		||||
	__u32 max_out_queue:8;
 | 
			
		||||
	__u32 time_slot:8;
 | 
			
		||||
	__u32 core_id:4;
 | 
			
		||||
	__u32 rsvd1:4;
 | 
			
		||||
 | 
			
		||||
	__u32 module_type:8;
 | 
			
		||||
	__u32 conn_type:4;
 | 
			
		||||
	__u32 dev_type:4;
 | 
			
		||||
	__u32 hw_conn_type:4;
 | 
			
		||||
	__u32 rsvd2:12;
 | 
			
		||||
 | 
			
		||||
	__u32 params_fixup:8;
 | 
			
		||||
	__u32 converter:8;
 | 
			
		||||
	__u32 input_pin_type:1;
 | 
			
		||||
	__u32 output_pin_type:1;
 | 
			
		||||
	__u32 is_dynamic_in_pin:1;
 | 
			
		||||
	__u32 is_dynamic_out_pin:1;
 | 
			
		||||
	__u32 is_loadable:1;
 | 
			
		||||
	__u32 rsvd3:11;
 | 
			
		||||
 | 
			
		||||
	struct skl_dfw_v4_pipe pipe;
 | 
			
		||||
	struct skl_dfw_v4_module_fmt in_fmt[MAX_IN_QUEUE];
 | 
			
		||||
	struct skl_dfw_v4_module_fmt out_fmt[MAX_OUT_QUEUE];
 | 
			
		||||
	struct skl_dfw_v4_module_pin in_pin[MAX_IN_QUEUE];
 | 
			
		||||
	struct skl_dfw_v4_module_pin out_pin[MAX_OUT_QUEUE];
 | 
			
		||||
	struct skl_dfw_v4_module_caps caps;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2682,168 +2682,6 @@ static int skl_tplg_get_desc_blocks(struct device *dev,
 | 
			
		|||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Functions to parse private data from configuration file format v4 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Add pipeline from topology binary into driver pipeline list
 | 
			
		||||
 *
 | 
			
		||||
 * If already added we return that instance
 | 
			
		||||
 * Otherwise we create a new instance and add into driver list
 | 
			
		||||
 */
 | 
			
		||||
static int skl_tplg_add_pipe_v4(struct device *dev,
 | 
			
		||||
			struct skl_module_cfg *mconfig, struct skl_dev *skl,
 | 
			
		||||
			struct skl_dfw_v4_pipe *dfw_pipe)
 | 
			
		||||
{
 | 
			
		||||
	struct skl_pipeline *ppl;
 | 
			
		||||
	struct skl_pipe *pipe;
 | 
			
		||||
	struct skl_pipe_params *params;
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(ppl, &skl->ppl_list, node) {
 | 
			
		||||
		if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) {
 | 
			
		||||
			mconfig->pipe = ppl->pipe;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
 | 
			
		||||
	if (!ppl)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
 | 
			
		||||
	if (!pipe)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
 | 
			
		||||
	if (!params)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	pipe->ppl_id = dfw_pipe->pipe_id;
 | 
			
		||||
	pipe->memory_pages = dfw_pipe->memory_pages;
 | 
			
		||||
	pipe->pipe_priority = dfw_pipe->pipe_priority;
 | 
			
		||||
	pipe->conn_type = dfw_pipe->conn_type;
 | 
			
		||||
	pipe->state = SKL_PIPE_INVALID;
 | 
			
		||||
	pipe->p_params = params;
 | 
			
		||||
	INIT_LIST_HEAD(&pipe->w_list);
 | 
			
		||||
 | 
			
		||||
	ppl->pipe = pipe;
 | 
			
		||||
	list_add(&ppl->node, &skl->ppl_list);
 | 
			
		||||
 | 
			
		||||
	mconfig->pipe = pipe;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void skl_fill_module_pin_info_v4(struct skl_dfw_v4_module_pin *dfw_pin,
 | 
			
		||||
					struct skl_module_pin *m_pin,
 | 
			
		||||
					bool is_dynamic, int max_pin)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < max_pin; i++) {
 | 
			
		||||
		m_pin[i].id.module_id = dfw_pin[i].module_id;
 | 
			
		||||
		m_pin[i].id.instance_id = dfw_pin[i].instance_id;
 | 
			
		||||
		m_pin[i].in_use = false;
 | 
			
		||||
		m_pin[i].is_dynamic = is_dynamic;
 | 
			
		||||
		m_pin[i].pin_state = SKL_PIN_UNBIND;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt,
 | 
			
		||||
				 struct skl_dfw_v4_module_fmt *src_fmt,
 | 
			
		||||
				 int pins)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < pins; i++) {
 | 
			
		||||
		dst_fmt[i].fmt.channels  = src_fmt[i].channels;
 | 
			
		||||
		dst_fmt[i].fmt.s_freq = src_fmt[i].freq;
 | 
			
		||||
		dst_fmt[i].fmt.bit_depth = src_fmt[i].bit_depth;
 | 
			
		||||
		dst_fmt[i].fmt.valid_bit_depth = src_fmt[i].valid_bit_depth;
 | 
			
		||||
		dst_fmt[i].fmt.ch_cfg = src_fmt[i].ch_cfg;
 | 
			
		||||
		dst_fmt[i].fmt.ch_map = src_fmt[i].ch_map;
 | 
			
		||||
		dst_fmt[i].fmt.interleaving_style =
 | 
			
		||||
						src_fmt[i].interleaving_style;
 | 
			
		||||
		dst_fmt[i].fmt.sample_type = src_fmt[i].sample_type;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
 | 
			
		||||
				    struct skl_dev *skl, struct device *dev,
 | 
			
		||||
				    struct skl_module_cfg *mconfig)
 | 
			
		||||
{
 | 
			
		||||
	struct skl_dfw_v4_module *dfw =
 | 
			
		||||
				(struct skl_dfw_v4_module *)tplg_w->priv.data;
 | 
			
		||||
	int ret;
 | 
			
		||||
	int idx = mconfig->fmt_cfg_idx;
 | 
			
		||||
 | 
			
		||||
	dev_dbg(dev, "Parsing Skylake v4 widget topology data\n");
 | 
			
		||||
 | 
			
		||||
	ret = guid_parse(dfw->uuid, (guid_t *)mconfig->guid);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
	mconfig->id.module_id = -1;
 | 
			
		||||
	mconfig->id.instance_id = dfw->instance_id;
 | 
			
		||||
	mconfig->module->resources[0].cpc = dfw->max_mcps / 1000;
 | 
			
		||||
	mconfig->module->resources[0].ibs = dfw->ibs;
 | 
			
		||||
	mconfig->module->resources[0].obs = dfw->obs;
 | 
			
		||||
	mconfig->core_id = dfw->core_id;
 | 
			
		||||
	mconfig->module->max_input_pins = dfw->max_in_queue;
 | 
			
		||||
	mconfig->module->max_output_pins = dfw->max_out_queue;
 | 
			
		||||
	mconfig->module->loadable = dfw->is_loadable;
 | 
			
		||||
	skl_tplg_fill_fmt_v4(mconfig->module->formats[0].inputs, dfw->in_fmt,
 | 
			
		||||
			     MAX_IN_QUEUE);
 | 
			
		||||
	skl_tplg_fill_fmt_v4(mconfig->module->formats[0].outputs, dfw->out_fmt,
 | 
			
		||||
			     MAX_OUT_QUEUE);
 | 
			
		||||
 | 
			
		||||
	mconfig->params_fixup = dfw->params_fixup;
 | 
			
		||||
	mconfig->converter = dfw->converter;
 | 
			
		||||
	mconfig->m_type = dfw->module_type;
 | 
			
		||||
	mconfig->vbus_id = dfw->vbus_id;
 | 
			
		||||
	mconfig->module->resources[0].is_pages = dfw->mem_pages;
 | 
			
		||||
 | 
			
		||||
	ret = skl_tplg_add_pipe_v4(dev, mconfig, skl, &dfw->pipe);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	mconfig->dev_type = dfw->dev_type;
 | 
			
		||||
	mconfig->hw_conn_type = dfw->hw_conn_type;
 | 
			
		||||
	mconfig->time_slot = dfw->time_slot;
 | 
			
		||||
	mconfig->formats_config[idx].caps_size = dfw->caps.caps_size;
 | 
			
		||||
 | 
			
		||||
	mconfig->m_in_pin = devm_kcalloc(dev,
 | 
			
		||||
				MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin),
 | 
			
		||||
				GFP_KERNEL);
 | 
			
		||||
	if (!mconfig->m_in_pin)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	mconfig->m_out_pin = devm_kcalloc(dev,
 | 
			
		||||
				MAX_OUT_QUEUE, sizeof(*mconfig->m_out_pin),
 | 
			
		||||
				GFP_KERNEL);
 | 
			
		||||
	if (!mconfig->m_out_pin)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	skl_fill_module_pin_info_v4(dfw->in_pin, mconfig->m_in_pin,
 | 
			
		||||
				    dfw->is_dynamic_in_pin,
 | 
			
		||||
				    mconfig->module->max_input_pins);
 | 
			
		||||
	skl_fill_module_pin_info_v4(dfw->out_pin, mconfig->m_out_pin,
 | 
			
		||||
				    dfw->is_dynamic_out_pin,
 | 
			
		||||
				    mconfig->module->max_output_pins);
 | 
			
		||||
 | 
			
		||||
	if (mconfig->formats_config[idx].caps_size) {
 | 
			
		||||
		mconfig->formats_config[idx].set_params = dfw->caps.set_params;
 | 
			
		||||
		mconfig->formats_config[idx].param_id = dfw->caps.param_id;
 | 
			
		||||
		mconfig->formats_config[idx].caps =
 | 
			
		||||
		devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
 | 
			
		||||
			     GFP_KERNEL);
 | 
			
		||||
		if (!mconfig->formats_config[idx].caps)
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
		memcpy(mconfig->formats_config[idx].caps, dfw->caps.caps,
 | 
			
		||||
		       dfw->caps.caps_size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int skl_tplg_get_caps_data(struct device *dev, char *data,
 | 
			
		||||
				  struct skl_module_cfg *mconfig)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -2877,13 +2715,6 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
 | 
			
		|||
	char *data;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * v4 configuration files have a valid UUID at the start of
 | 
			
		||||
	 * the widget's private data.
 | 
			
		||||
	 */
 | 
			
		||||
	if (uuid_is_valid((char *)tplg_w->priv.data))
 | 
			
		||||
		return skl_tplg_get_pvt_data_v4(tplg_w, skl, dev, mconfig);
 | 
			
		||||
 | 
			
		||||
	/* Read the NUM_DATA_BLOCKS descriptor */
 | 
			
		||||
	array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
 | 
			
		||||
	ret = skl_tplg_get_desc_blocks(dev, array);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1768,83 +1768,13 @@ static int soc_tplg_pcm_create(struct soc_tplg *tplg,
 | 
			
		|||
	return  soc_tplg_fe_link_create(tplg, pcm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* copy stream caps from the old version 4 of source */
 | 
			
		||||
static void stream_caps_new_ver(struct snd_soc_tplg_stream_caps *dest,
 | 
			
		||||
				struct snd_soc_tplg_stream_caps_v4 *src)
 | 
			
		||||
{
 | 
			
		||||
	dest->size = cpu_to_le32(sizeof(*dest));
 | 
			
		||||
	memcpy(dest->name, src->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
 | 
			
		||||
	dest->formats = src->formats;
 | 
			
		||||
	dest->rates = src->rates;
 | 
			
		||||
	dest->rate_min = src->rate_min;
 | 
			
		||||
	dest->rate_max = src->rate_max;
 | 
			
		||||
	dest->channels_min = src->channels_min;
 | 
			
		||||
	dest->channels_max = src->channels_max;
 | 
			
		||||
	dest->periods_min = src->periods_min;
 | 
			
		||||
	dest->periods_max = src->periods_max;
 | 
			
		||||
	dest->period_size_min = src->period_size_min;
 | 
			
		||||
	dest->period_size_max = src->period_size_max;
 | 
			
		||||
	dest->buffer_size_min = src->buffer_size_min;
 | 
			
		||||
	dest->buffer_size_max = src->buffer_size_max;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pcm_new_ver - Create the new version of PCM from the old version.
 | 
			
		||||
 * @tplg: topology context
 | 
			
		||||
 * @src: older version of pcm as a source
 | 
			
		||||
 * @pcm: latest version of pcm created from the source
 | 
			
		||||
 *
 | 
			
		||||
 * Support from version 4. User should free the returned pcm manually.
 | 
			
		||||
 */
 | 
			
		||||
static int pcm_new_ver(struct soc_tplg *tplg,
 | 
			
		||||
		       struct snd_soc_tplg_pcm *src,
 | 
			
		||||
		       struct snd_soc_tplg_pcm **pcm)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_tplg_pcm *dest;
 | 
			
		||||
	struct snd_soc_tplg_pcm_v4 *src_v4;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	*pcm = NULL;
 | 
			
		||||
 | 
			
		||||
	if (le32_to_cpu(src->size) != sizeof(*src_v4)) {
 | 
			
		||||
		dev_err(tplg->dev, "ASoC: invalid PCM size\n");
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev_warn(tplg->dev, "ASoC: old version of PCM\n");
 | 
			
		||||
	src_v4 = (struct snd_soc_tplg_pcm_v4 *)src;
 | 
			
		||||
	dest = kzalloc(sizeof(*dest), GFP_KERNEL);
 | 
			
		||||
	if (!dest)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	dest->size = cpu_to_le32(sizeof(*dest)); /* size of latest abi version */
 | 
			
		||||
	memcpy(dest->pcm_name, src_v4->pcm_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
 | 
			
		||||
	memcpy(dest->dai_name, src_v4->dai_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
 | 
			
		||||
	dest->pcm_id = src_v4->pcm_id;
 | 
			
		||||
	dest->dai_id = src_v4->dai_id;
 | 
			
		||||
	dest->playback = src_v4->playback;
 | 
			
		||||
	dest->capture = src_v4->capture;
 | 
			
		||||
	dest->compress = src_v4->compress;
 | 
			
		||||
	dest->num_streams = src_v4->num_streams;
 | 
			
		||||
	for (i = 0; i < le32_to_cpu(dest->num_streams); i++)
 | 
			
		||||
		memcpy(&dest->stream[i], &src_v4->stream[i],
 | 
			
		||||
		       sizeof(struct snd_soc_tplg_stream));
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 2; i++)
 | 
			
		||||
		stream_caps_new_ver(&dest->caps[i], &src_v4->caps[i]);
 | 
			
		||||
 | 
			
		||||
	*pcm = dest;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
 | 
			
		||||
	struct snd_soc_tplg_hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_tplg_pcm *pcm, *_pcm;
 | 
			
		||||
	struct snd_soc_tplg_pcm *pcm;
 | 
			
		||||
	int count;
 | 
			
		||||
	int size;
 | 
			
		||||
	int i;
 | 
			
		||||
	bool abi_match;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	count = le32_to_cpu(hdr->count);
 | 
			
		||||
| 
						 | 
				
			
			@ -1852,8 +1782,7 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
 | 
			
		|||
	/* check the element size and count */
 | 
			
		||||
	pcm = (struct snd_soc_tplg_pcm *)tplg->pos;
 | 
			
		||||
	size = le32_to_cpu(pcm->size);
 | 
			
		||||
	if (size > sizeof(struct snd_soc_tplg_pcm)
 | 
			
		||||
		|| size < sizeof(struct snd_soc_tplg_pcm_v4)) {
 | 
			
		||||
	if (size > sizeof(struct snd_soc_tplg_pcm)) {
 | 
			
		||||
		dev_err(tplg->dev, "ASoC: invalid size %d for PCM elems\n",
 | 
			
		||||
			size);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1872,31 +1801,18 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
 | 
			
		|||
		/* check ABI version by size, create a new version of pcm
 | 
			
		||||
		 * if abi not match.
 | 
			
		||||
		 */
 | 
			
		||||
		if (size == sizeof(*pcm)) {
 | 
			
		||||
			abi_match = true;
 | 
			
		||||
			_pcm = pcm;
 | 
			
		||||
		} else {
 | 
			
		||||
			abi_match = false;
 | 
			
		||||
			ret = pcm_new_ver(tplg, pcm, &_pcm);
 | 
			
		||||
			if (ret < 0)
 | 
			
		||||
				return ret;
 | 
			
		||||
		}
 | 
			
		||||
		if (size != sizeof(*pcm))
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
 | 
			
		||||
		/* create the FE DAIs and DAI links */
 | 
			
		||||
		ret = soc_tplg_pcm_create(tplg, _pcm);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			if (!abi_match)
 | 
			
		||||
				kfree(_pcm);
 | 
			
		||||
		ret = soc_tplg_pcm_create(tplg, pcm);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* offset by version-specific struct size and
 | 
			
		||||
		 * real priv data size
 | 
			
		||||
		 */
 | 
			
		||||
		tplg->pos += size + le32_to_cpu(_pcm->priv.size);
 | 
			
		||||
 | 
			
		||||
		if (!abi_match)
 | 
			
		||||
			kfree(_pcm); /* free the duplicated one */
 | 
			
		||||
		tplg->pos += size + le32_to_cpu(pcm->priv.size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count);
 | 
			
		||||
| 
						 | 
				
			
			@ -1972,49 +1888,6 @@ static void set_link_hw_format(struct snd_soc_dai_link *link,
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * link_new_ver - Create a new physical link config from the old
 | 
			
		||||
 * version of source.
 | 
			
		||||
 * @tplg: topology context
 | 
			
		||||
 * @src: old version of phyical link config as a source
 | 
			
		||||
 * @link: latest version of physical link config created from the source
 | 
			
		||||
 *
 | 
			
		||||
 * Support from version 4. User need free the returned link config manually.
 | 
			
		||||
 */
 | 
			
		||||
static int link_new_ver(struct soc_tplg *tplg,
 | 
			
		||||
			struct snd_soc_tplg_link_config *src,
 | 
			
		||||
			struct snd_soc_tplg_link_config **link)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_tplg_link_config *dest;
 | 
			
		||||
	struct snd_soc_tplg_link_config_v4 *src_v4;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	*link = NULL;
 | 
			
		||||
 | 
			
		||||
	if (le32_to_cpu(src->size) !=
 | 
			
		||||
	    sizeof(struct snd_soc_tplg_link_config_v4)) {
 | 
			
		||||
		dev_err(tplg->dev, "ASoC: invalid physical link config size\n");
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev_warn(tplg->dev, "ASoC: old version of physical link config\n");
 | 
			
		||||
 | 
			
		||||
	src_v4 = (struct snd_soc_tplg_link_config_v4 *)src;
 | 
			
		||||
	dest = kzalloc(sizeof(*dest), GFP_KERNEL);
 | 
			
		||||
	if (!dest)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	dest->size = cpu_to_le32(sizeof(*dest));
 | 
			
		||||
	dest->id = src_v4->id;
 | 
			
		||||
	dest->num_streams = src_v4->num_streams;
 | 
			
		||||
	for (i = 0; i < le32_to_cpu(dest->num_streams); i++)
 | 
			
		||||
		memcpy(&dest->stream[i], &src_v4->stream[i],
 | 
			
		||||
		       sizeof(struct snd_soc_tplg_stream));
 | 
			
		||||
 | 
			
		||||
	*link = dest;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * snd_soc_find_dai_link - Find a DAI link
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -2120,19 +1993,17 @@ static int soc_tplg_link_config(struct soc_tplg *tplg,
 | 
			
		|||
static int soc_tplg_link_elems_load(struct soc_tplg *tplg,
 | 
			
		||||
	struct snd_soc_tplg_hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_tplg_link_config *link, *_link;
 | 
			
		||||
	struct snd_soc_tplg_link_config *link;
 | 
			
		||||
	int count;
 | 
			
		||||
	int size;
 | 
			
		||||
	int i, ret;
 | 
			
		||||
	bool abi_match;
 | 
			
		||||
 | 
			
		||||
	count = le32_to_cpu(hdr->count);
 | 
			
		||||
 | 
			
		||||
	/* check the element size and count */
 | 
			
		||||
	link = (struct snd_soc_tplg_link_config *)tplg->pos;
 | 
			
		||||
	size = le32_to_cpu(link->size);
 | 
			
		||||
	if (size > sizeof(struct snd_soc_tplg_link_config)
 | 
			
		||||
		|| size < sizeof(struct snd_soc_tplg_link_config_v4)) {
 | 
			
		||||
	if (size > sizeof(struct snd_soc_tplg_link_config)) {
 | 
			
		||||
		dev_err(tplg->dev, "ASoC: invalid size %d for physical link elems\n",
 | 
			
		||||
			size);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2147,30 +2018,17 @@ static int soc_tplg_link_elems_load(struct soc_tplg *tplg,
 | 
			
		|||
	for (i = 0; i < count; i++) {
 | 
			
		||||
		link = (struct snd_soc_tplg_link_config *)tplg->pos;
 | 
			
		||||
		size = le32_to_cpu(link->size);
 | 
			
		||||
		if (size == sizeof(*link)) {
 | 
			
		||||
			abi_match = true;
 | 
			
		||||
			_link = link;
 | 
			
		||||
		} else {
 | 
			
		||||
			abi_match = false;
 | 
			
		||||
			ret = link_new_ver(tplg, link, &_link);
 | 
			
		||||
			if (ret < 0)
 | 
			
		||||
				return ret;
 | 
			
		||||
		}
 | 
			
		||||
		if (size != sizeof(*link))
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
 | 
			
		||||
		ret = soc_tplg_link_config(tplg, _link);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			if (!abi_match)
 | 
			
		||||
				kfree(_link);
 | 
			
		||||
		ret = soc_tplg_link_config(tplg, link);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* offset by version-specific struct size and
 | 
			
		||||
		 * real priv data size
 | 
			
		||||
		 */
 | 
			
		||||
		tplg->pos += size + le32_to_cpu(_link->priv.size);
 | 
			
		||||
 | 
			
		||||
		if (!abi_match)
 | 
			
		||||
			kfree(_link); /* free the duplicated one */
 | 
			
		||||
		tplg->pos += size + le32_to_cpu(link->priv.size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -2280,84 +2138,21 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * manifest_new_ver - Create a new version of manifest from the old version
 | 
			
		||||
 * of source.
 | 
			
		||||
 * @tplg: topology context
 | 
			
		||||
 * @src: old version of manifest as a source
 | 
			
		||||
 * @manifest: latest version of manifest created from the source
 | 
			
		||||
 *
 | 
			
		||||
 * Support from version 4. Users need free the returned manifest manually.
 | 
			
		||||
 */
 | 
			
		||||
static int manifest_new_ver(struct soc_tplg *tplg,
 | 
			
		||||
			    struct snd_soc_tplg_manifest *src,
 | 
			
		||||
			    struct snd_soc_tplg_manifest **manifest)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_tplg_manifest *dest;
 | 
			
		||||
	struct snd_soc_tplg_manifest_v4 *src_v4;
 | 
			
		||||
	int size;
 | 
			
		||||
 | 
			
		||||
	*manifest = NULL;
 | 
			
		||||
 | 
			
		||||
	size = le32_to_cpu(src->size);
 | 
			
		||||
	if (size != sizeof(*src_v4)) {
 | 
			
		||||
		dev_warn(tplg->dev, "ASoC: invalid manifest size %d\n",
 | 
			
		||||
			 size);
 | 
			
		||||
		if (size)
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		src->size = cpu_to_le32(sizeof(*src_v4));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev_warn(tplg->dev, "ASoC: old version of manifest\n");
 | 
			
		||||
 | 
			
		||||
	src_v4 = (struct snd_soc_tplg_manifest_v4 *)src;
 | 
			
		||||
	dest = kzalloc(sizeof(*dest) + le32_to_cpu(src_v4->priv.size),
 | 
			
		||||
		       GFP_KERNEL);
 | 
			
		||||
	if (!dest)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	dest->size = cpu_to_le32(sizeof(*dest)); /* size of latest abi version */
 | 
			
		||||
	dest->control_elems = src_v4->control_elems;
 | 
			
		||||
	dest->widget_elems = src_v4->widget_elems;
 | 
			
		||||
	dest->graph_elems = src_v4->graph_elems;
 | 
			
		||||
	dest->pcm_elems = src_v4->pcm_elems;
 | 
			
		||||
	dest->dai_link_elems = src_v4->dai_link_elems;
 | 
			
		||||
	dest->priv.size = src_v4->priv.size;
 | 
			
		||||
	if (dest->priv.size)
 | 
			
		||||
		memcpy(dest->priv.data, src_v4->priv.data,
 | 
			
		||||
		       le32_to_cpu(src_v4->priv.size));
 | 
			
		||||
 | 
			
		||||
	*manifest = dest;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int soc_tplg_manifest_load(struct soc_tplg *tplg,
 | 
			
		||||
				  struct snd_soc_tplg_hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_tplg_manifest *manifest, *_manifest;
 | 
			
		||||
	bool abi_match;
 | 
			
		||||
	struct snd_soc_tplg_manifest *manifest;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	manifest = (struct snd_soc_tplg_manifest *)tplg->pos;
 | 
			
		||||
 | 
			
		||||
	/* check ABI version by size, create a new manifest if abi not match */
 | 
			
		||||
	if (le32_to_cpu(manifest->size) == sizeof(*manifest)) {
 | 
			
		||||
		abi_match = true;
 | 
			
		||||
		_manifest = manifest;
 | 
			
		||||
	} else {
 | 
			
		||||
		abi_match = false;
 | 
			
		||||
 | 
			
		||||
		ret = manifest_new_ver(tplg, manifest, &_manifest);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
	}
 | 
			
		||||
	if (le32_to_cpu(manifest->size) != sizeof(*manifest))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	/* pass control to component driver for optional further init */
 | 
			
		||||
	if (tplg->ops && tplg->ops->manifest)
 | 
			
		||||
		ret = tplg->ops->manifest(tplg->comp, tplg->index, _manifest);
 | 
			
		||||
 | 
			
		||||
	if (!abi_match)	/* free the duplicated one */
 | 
			
		||||
		kfree(_manifest);
 | 
			
		||||
		ret = tplg->ops->manifest(tplg->comp, tplg->index, manifest);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue