[alsa-devel] [RFC PATCH 3/3] ucm: Execute sequence of component devices

Liam Girdwood liam.r.girdwood at linux.intel.com
Tue Nov 15 09:49:58 CET 2016


On Tue, 2016-11-15 at 16:02 +0800, mengdong.lin at linux.intel.com wrote:
> From: Mengdong Lin <mengdong.lin at linux.intel.com>
> 
> A machine device's sequence can enable or disable a component device. So
> when executing a machine device's sequence, the enable or disable sequence
> of its component devices will also be excecuted.
> 
> Add a parameter 'cdev_in' to function execute_sequence(). This function
> is used to execute a sequence of either machine or component devices.
> Since the sequence of a component device does not define the card device,
> when executing its sequence, this parameter can pass the cdev defined by
> the sequence of its parent, the machine device. When executing sequence of
> machine devices, this parameter should be set to NULL.
> 
> Signed-off-by: Mengdong Lin <mengdong.lin at linux.intel.com>
> 
> diff --git a/src/ucm/main.c b/src/ucm/main.c
> index 8cc9208..a852cf4 100644
> --- a/src/ucm/main.c
> +++ b/src/ucm/main.c
> @@ -48,6 +48,13 @@ static int get_value3(char **value,
>  		      struct list_head *value_list2,
>  		      struct list_head *value_list3);
>  
> +static int execute_component_seq(snd_use_case_mgr_t *uc_mgr,
> +				 struct component_sequence *cmpt_seq,
> +				 struct list_head *value_list1,
> +				 struct list_head *value_list2,
> +				 struct list_head *value_list3,
> +				 char *cdev_in);
> +
>  static int check_identifier(const char *identifier, const char *prefix)
>  {
>  	int len;
> @@ -341,13 +348,22 @@ static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
>   * \brief Execute the sequence
>   * \param uc_mgr Use case manager
>   * \param seq Sequence
> + * \param cdev_in input cdev,  parenet's cdev for a component device,
> + *				or NULL for a machine device.
>   * \return zero on success, otherwise a negative error code
> + *
> + * A machine device's sequence can enable or disable a component device.
> + * But the enable/disable sequence of a component device does not define
> + * cdev, the card device. So when executing a component device's sequence,
> + * we need to pass the cdev defined by the sequence of its parent, the
> + * machine device. And for machine device, cdev should be set to NULL.
>   */
>  static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
>  			    struct list_head *seq,
>  			    struct list_head *value_list1,
>  			    struct list_head *value_list2,
> -			    struct list_head *value_list3)
> +			    struct list_head *value_list3,
> +			    char *cdev_in)

Could the current cdev be embedded in uc_mgr ? 

>  {
>  	struct list_head *pos;
>  	struct sequence_element *s;
> @@ -366,7 +382,16 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
>  		case SEQUENCE_ELEMENT_TYPE_CSET:
>  		case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE:
>  		case SEQUENCE_ELEMENT_TYPE_CSET_TLV:
> -			if (cdev == NULL) {
> +			if (cdev == NULL && cdev_in) {
> +				/* Sequence of a component device, should use
> +				 * the input cdev defined by sequence of its
> +				 * parent, the machine device.
> +				 */
> +				cdev = strdup(cdev_in);
> +				if (cdev == NULL)
> +					goto __fail_nomem;
> +
> +			} else if (cdev == NULL) {
>  				char *playback_ctl = NULL;
>  				char *capture_ctl = NULL;
>  
> @@ -405,7 +430,9 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
>  					free(capture_ctl);
>  				} else
>  					cdev = capture_ctl;
> +
>  			}
> +

Looks like this formatting change was added by mistake ?

>  			if (ctl == NULL) {
>  				err = open_ctl(uc_mgr, &ctl, cdev);
>  				if (err < 0) {
> @@ -427,6 +454,19 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
>  			if (err < 0)
>  				goto __fail;
>  			break;
> +		case SEQUENCE_ELEMENT_TYPE_CMPT_SEQ:
> +			/* Execute enable or disable sequence of a component
> +			 * device. Pass the cdev defined by the machine device.
> +			 */
> +			err = execute_component_seq(uc_mgr,
> +							&s->data.cmpt_seq,
> +							value_list1,
> +							value_list2,
> +							value_list3,
> +							cdev);
> +			if (err < 0)
> +				goto __fail;
> +			break;
>  		default:
>  			uc_error("unknown sequence command %i", s->type);
>  			break;
> @@ -442,6 +482,39 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
>  
>  }
>  
> +/* Execute enable or disable sequence of a component device.
> + *
> + * For a component device (a codec or embedded DSP), its sequence doesn't
> + * specify the sound card device 'cdev', because a component can be reused
> + * by different sound cards (machines). So when executing its sequence, a
> + * parameter 'cdev_in' is used to pass cdev defined by the sequence of its
> + * parent, the machine device.
> + */
> +static int execute_component_seq(snd_use_case_mgr_t *uc_mgr,
> +				 struct component_sequence *cmpt_seq,
> +				 struct list_head *value_list1,
> +				 struct list_head *value_list2,
> +				 struct list_head *value_list3,
> +				 char *cdev_in)
> +{
> +	struct use_case_device *device = cmpt_seq->device;
> +	struct list_head *seq;
> +	int err;
> +
> +
> +	if (cmpt_seq->enable)
> +		seq = &device->enable_list;
> +	else
> +		seq = &device->disable_list;

What happens here if there is only an enable sequence and no disable
sequence ? i.e. will seq be NULL ?

> +
> +	err = execute_sequence(uc_mgr, seq,
> +			       &device->value_list,
> +			       &uc_mgr->active_verb->value_list,
> +			       &uc_mgr->value_list,
> +			       cdev_in);
> +	return err;
> +}
> +
>  /**
>   * \brief Import master config and execute the default sequence
>   * \param uc_mgr Use case manager
> @@ -455,7 +528,7 @@ static int import_master_config(snd_use_case_mgr_t *uc_mgr)
>  	if (err < 0)
>  		return err;
>  	err = execute_sequence(uc_mgr, &uc_mgr->default_list,
> -			       &uc_mgr->value_list, NULL, NULL);
> +			       &uc_mgr->value_list, NULL, NULL, NULL);
>  	if (err < 0)
>  		uc_error("Unable to execute default sequence");
>  	return err;
> @@ -761,7 +834,7 @@ static int set_verb(snd_use_case_mgr_t *uc_mgr,
>  	err = execute_sequence(uc_mgr, seq,
>  			       &verb->value_list,
>  			       &uc_mgr->value_list,
> -			       NULL);
> +			       NULL, NULL);
>  	if (enable && err >= 0)
>  		uc_mgr->active_verb = verb;
>  	return err;
> @@ -792,7 +865,8 @@ static int set_modifier(snd_use_case_mgr_t *uc_mgr,
>  	err = execute_sequence(uc_mgr, seq,
>  			       &modifier->value_list,
>  			       &uc_mgr->active_verb->value_list,
> -			       &uc_mgr->value_list);
> +			       &uc_mgr->value_list,
> +			       NULL);
>  	if (enable && err >= 0) {
>  		list_add_tail(&modifier->active_list, &uc_mgr->active_modifiers);
>  	} else if (!enable) {
> @@ -826,7 +900,8 @@ static int set_device(snd_use_case_mgr_t *uc_mgr,
>  	err = execute_sequence(uc_mgr, seq,
>  			       &device->value_list,
>  			       &uc_mgr->active_verb->value_list,
> -			       &uc_mgr->value_list);
> +			       &uc_mgr->value_list,
> +			       NULL);
>  	if (enable && err >= 0) {
>  		list_add_tail(&device->active_list, &uc_mgr->active_devices);
>  	} else if (!enable) {
> @@ -953,7 +1028,7 @@ static int dismantle_use_case(snd_use_case_mgr_t *uc_mgr)
>  	uc_mgr->active_verb = NULL;
>  
>  	err = execute_sequence(uc_mgr, &uc_mgr->default_list,
> -			       &uc_mgr->value_list, NULL, NULL);
> +			       &uc_mgr->value_list, NULL, NULL, NULL);
>  	
>  	return err;
>  }
> @@ -969,7 +1044,7 @@ int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr)
>  
>  	pthread_mutex_lock(&uc_mgr->mutex);
>  	err = execute_sequence(uc_mgr, &uc_mgr->default_list,
> -			       &uc_mgr->value_list, NULL, NULL);
> +			       &uc_mgr->value_list, NULL, NULL, NULL);
>  	INIT_LIST_HEAD(&uc_mgr->active_modifiers);
>  	INIT_LIST_HEAD(&uc_mgr->active_devices);
>  	uc_mgr->active_verb = NULL;
> @@ -1578,6 +1653,7 @@ static int handle_transition_verb(snd_use_case_mgr_t *uc_mgr,
>                          err = execute_sequence(uc_mgr, &trans->transition_list,
>  					       &uc_mgr->active_verb->value_list,
>  					       &uc_mgr->value_list,
> +					       NULL,
>  					       NULL);
>                          if (err >= 0)
>                                  return 1;
> @@ -1689,7 +1765,8 @@ static int switch_device(snd_use_case_mgr_t *uc_mgr,
>                          err = execute_sequence(uc_mgr, &trans->transition_list,
>  					       &xold->value_list,
>  					       &uc_mgr->active_verb->value_list,
> -					       &uc_mgr->value_list);
> +					       &uc_mgr->value_list,
> +					       NULL);
>                          if (err >= 0) {
>                                  list_del(&xold->active_list);
>                                  list_add_tail(&xnew->active_list, &uc_mgr->active_devices);
> @@ -1741,7 +1818,8 @@ static int switch_modifier(snd_use_case_mgr_t *uc_mgr,
>                          err = execute_sequence(uc_mgr, &trans->transition_list,
>  					       &xold->value_list,
>  					       &uc_mgr->active_verb->value_list,
> -					       &uc_mgr->value_list);
> +					       &uc_mgr->value_list,
> +					       NULL);
>                          if (err >= 0) {
>                                  list_del(&xold->active_list);
>                                  list_add_tail(&xnew->active_list, &uc_mgr->active_modifiers);




More information about the Alsa-devel mailing list