mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	topology: Merge lookup for data reference into tplg_copy_data()
Code refactor to reduce function calls. Now tplg_copy_data() can look up a referenced data element and merge its data. Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com> Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									bb03d929e8
								
							
						
					
					
						commit
						2481ef315f
					
				
					 4 changed files with 34 additions and 31 deletions
				
			
		| 
						 | 
					@ -140,9 +140,9 @@ static int tplg_build_mixer_control(snd_tplg_t *tplg,
 | 
				
			||||||
				 err = copy_tlv(elem, ref->elem);
 | 
									 err = copy_tlv(elem, ref->elem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else if (ref->type == SND_TPLG_TYPE_DATA) {
 | 
							} else if (ref->type == SND_TPLG_TYPE_DATA) {
 | 
				
			||||||
			ref->elem = tplg_elem_lookup(&tplg->pdata_list,
 | 
								err = tplg_copy_data(tplg, elem, ref);
 | 
				
			||||||
						ref->id, SND_TPLG_TYPE_DATA);
 | 
								if (err < 0)
 | 
				
			||||||
			 err = tplg_copy_data(elem, ref->elem);
 | 
									return err;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!ref->elem) {
 | 
							if (!ref->elem) {
 | 
				
			||||||
| 
						 | 
					@ -188,9 +188,9 @@ static int tplg_build_enum_control(snd_tplg_t *tplg,
 | 
				
			||||||
				copy_enum_texts(elem, ref->elem);
 | 
									copy_enum_texts(elem, ref->elem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else if (ref->type == SND_TPLG_TYPE_DATA) {
 | 
							} else if (ref->type == SND_TPLG_TYPE_DATA) {
 | 
				
			||||||
			ref->elem = tplg_elem_lookup(&tplg->pdata_list,
 | 
								err = tplg_copy_data(tplg, elem, ref);
 | 
				
			||||||
						ref->id, SND_TPLG_TYPE_DATA);
 | 
								if (err < 0)
 | 
				
			||||||
			err = tplg_copy_data(elem, ref->elem);
 | 
									return err;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!ref->elem) {
 | 
							if (!ref->elem) {
 | 
				
			||||||
			SNDERR("error: cannot find '%s' referenced by"
 | 
								SNDERR("error: cannot find '%s' referenced by"
 | 
				
			||||||
| 
						 | 
					@ -208,6 +208,7 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tplg_ref *ref;
 | 
						struct tplg_ref *ref;
 | 
				
			||||||
	struct list_head *base, *pos;
 | 
						struct list_head *base, *pos;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base = &elem->ref_list;
 | 
						base = &elem->ref_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,18 +218,11 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
 | 
				
			||||||
		if (ref->id == NULL || ref->elem)
 | 
							if (ref->id == NULL || ref->elem)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* bytes control only reference one private data section */
 | 
							 if (ref->type == SND_TPLG_TYPE_DATA) {
 | 
				
			||||||
		ref->elem = tplg_elem_lookup(&tplg->pdata_list,
 | 
								err = tplg_copy_data(tplg, elem, ref);
 | 
				
			||||||
			ref->id, SND_TPLG_TYPE_DATA);
 | 
								if (err < 0)
 | 
				
			||||||
		if (!ref->elem) {
 | 
									return err;
 | 
				
			||||||
			SNDERR("error: cannot find data '%s'"
 | 
					 | 
				
			||||||
				" referenced by control '%s'\n",
 | 
					 | 
				
			||||||
				ref->id, elem->id);
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* copy texts to enum elem */
 | 
					 | 
				
			||||||
		return tplg_copy_data(elem, ref->elem);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,12 +191,11 @@ static int tplg_build_widget(snd_tplg_t *tplg,
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case SND_TPLG_TYPE_DATA:
 | 
							case SND_TPLG_TYPE_DATA:
 | 
				
			||||||
			if (!ref->elem)
 | 
								err = tplg_copy_data(tplg, elem, ref);
 | 
				
			||||||
				ref->elem = tplg_elem_lookup(&tplg->pdata_list,
 | 
								if (err < 0)
 | 
				
			||||||
						ref->id, SND_TPLG_TYPE_DATA);
 | 
									return err;
 | 
				
			||||||
			if (ref->elem)
 | 
					 | 
				
			||||||
				err = tplg_copy_data(elem, ref->elem);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -889,22 +889,30 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Merge data from a referenced data element to the parent element's
 | 
					/* Find a referenced data element and copy its data to the parent
 | 
				
			||||||
 * private data buffer.
 | 
					 * element's private data buffer.
 | 
				
			||||||
 * An element can refer to multiple data sections. Data of these sections
 | 
					 * An element can refer to multiple data sections. Data of these sections
 | 
				
			||||||
 * will be merged in the their reference order.
 | 
					 * will be merged in the their reference order.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
 | 
					int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
 | 
				
			||||||
 | 
							   struct tplg_ref *ref)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct tplg_elem *ref_elem;
 | 
				
			||||||
	struct snd_soc_tplg_private *priv, *old_priv;
 | 
						struct snd_soc_tplg_private *priv, *old_priv;
 | 
				
			||||||
	int priv_data_size, old_priv_data_size;
 | 
						int priv_data_size, old_priv_data_size;
 | 
				
			||||||
	void *obj;
 | 
						void *obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ref)
 | 
						ref_elem = tplg_elem_lookup(&tplg->pdata_list,
 | 
				
			||||||
 | 
									     ref->id, SND_TPLG_TYPE_DATA);
 | 
				
			||||||
 | 
						if (!ref_elem) {
 | 
				
			||||||
 | 
							SNDERR("error: cannot find data '%s' referenced by"
 | 
				
			||||||
 | 
							" element '%s'\n", ref->id, elem->id);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tplg_dbg("Data '%s' used by '%s'\n", ref->id, elem->id);
 | 
						tplg_dbg("Data '%s' used by '%s'\n", ref->id, elem->id);
 | 
				
			||||||
	if (!ref->data || !ref->data->size) /* overlook empty private data */
 | 
						/* overlook empty private data */
 | 
				
			||||||
 | 
						if (!ref_elem->data || !ref_elem->data->size)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	old_priv = get_priv_data(elem);
 | 
						old_priv = get_priv_data(elem);
 | 
				
			||||||
| 
						 | 
					@ -912,7 +920,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	old_priv_data_size = old_priv->size;
 | 
						old_priv_data_size = old_priv->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv_data_size = ref->data->size;
 | 
						priv_data_size = ref_elem->data->size;
 | 
				
			||||||
	obj = realloc(elem->obj,
 | 
						obj = realloc(elem->obj,
 | 
				
			||||||
			elem->size + priv_data_size);
 | 
								elem->size + priv_data_size);
 | 
				
			||||||
	if (!obj)
 | 
						if (!obj)
 | 
				
			||||||
| 
						 | 
					@ -926,9 +934,9 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
 | 
				
			||||||
	/* merge the new data block */
 | 
						/* merge the new data block */
 | 
				
			||||||
	elem->size += priv_data_size;
 | 
						elem->size += priv_data_size;
 | 
				
			||||||
	priv->size = priv_data_size + old_priv_data_size;
 | 
						priv->size = priv_data_size + old_priv_data_size;
 | 
				
			||||||
	ref->compound_elem = 1;
 | 
						ref_elem->compound_elem = 1;
 | 
				
			||||||
	memcpy(priv->data + old_priv_data_size,
 | 
						memcpy(priv->data + old_priv_data_size,
 | 
				
			||||||
	       ref->data->data, priv_data_size);
 | 
						       ref_elem->data->data, priv_data_size);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -228,7 +228,9 @@ int tplg_build_widgets(snd_tplg_t *tplg);
 | 
				
			||||||
int tplg_build_routes(snd_tplg_t *tplg);
 | 
					int tplg_build_routes(snd_tplg_t *tplg);
 | 
				
			||||||
int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
 | 
					int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref);
 | 
					int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
 | 
				
			||||||
 | 
							   struct tplg_ref *ref);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
 | 
					int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
 | 
					int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue