mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-10-29 05:40:23 -04:00 
			
		
		
		
	Merge branch 'alsa-ucm-disable-devices-on-suspend' into 'master'
alsa-ucm: Disable UCM devices when suspending See merge request pulseaudio/pulseaudio!772
This commit is contained in:
		
						commit
						3678231a44
					
				
					 4 changed files with 120 additions and 0 deletions
				
			
		|  | @ -195,6 +195,7 @@ enum { | |||
| 
 | ||||
| static void userdata_free(struct userdata *u); | ||||
| static int unsuspend(struct userdata *u, bool recovering); | ||||
| static void sync_mixer(struct userdata *u, pa_device_port *port); | ||||
| 
 | ||||
| /* FIXME: Is there a better way to do this than device names? */ | ||||
| static bool is_iec958(struct userdata *u) { | ||||
|  | @ -1087,6 +1088,12 @@ static void suspend(struct userdata *u) { | |||
|     pa_sink_set_max_rewind_within_thread(u->sink, 0); | ||||
|     pa_sink_set_max_request_within_thread(u->sink, 0); | ||||
| 
 | ||||
|     /* Disabling the UCM devices may save some power. */ | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(u->sink->active_port); | ||||
|         pa_alsa_ucm_port_device_disable(data); | ||||
|     } | ||||
| 
 | ||||
|     pa_log_info("Device suspended..."); | ||||
| } | ||||
| 
 | ||||
|  | @ -1202,6 +1209,13 @@ static int unsuspend(struct userdata *u, bool recovering) { | |||
| 
 | ||||
|     pa_log_info("Trying resume..."); | ||||
| 
 | ||||
|     /* We disable all UCM devices when suspending, so let's enable them again. */ | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(u->sink->active_port); | ||||
|         pa_alsa_ucm_port_device_enable(data); | ||||
|         sync_mixer(u, u->sink->active_port); | ||||
|     } | ||||
| 
 | ||||
|     if ((is_iec958(u) || is_hdmi(u)) && pa_sink_is_passthrough(u->sink)) { | ||||
|         /* Need to open device in NONAUDIO mode */ | ||||
|         int len = strlen(u->device_name) + 8; | ||||
|  | @ -1508,6 +1522,12 @@ static void sink_get_volume_cb(pa_sink *s) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     if (pa_alsa_path_get_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r) < 0) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -1538,6 +1558,12 @@ static void sink_set_volume_cb(pa_sink *s) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     /* Shift up by the base volume */ | ||||
|     pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume); | ||||
| 
 | ||||
|  | @ -1601,6 +1627,12 @@ static void sink_write_volume_cb(pa_sink *s) { | |||
|     pa_assert(u->mixer_handle); | ||||
|     pa_assert(s->flags & PA_SINK_DEFERRED_VOLUME); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     /* Shift up by the base volume */ | ||||
|     pa_sw_cvolume_divide_scalar(&hw_vol, &hw_vol, s->base_volume); | ||||
| 
 | ||||
|  | @ -1639,6 +1671,14 @@ static int sink_get_mute_cb(pa_sink *s, bool *mute) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) { | ||||
|             *mute = s->muted; | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (pa_alsa_path_get_mute(u->mixer_path, u->mixer_handle, mute) < 0) | ||||
|         return -1; | ||||
| 
 | ||||
|  | @ -1652,6 +1692,12 @@ static void sink_set_mute_cb(pa_sink *s) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     pa_alsa_path_set_mute(u->mixer_path, u->mixer_handle, s->muted); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -176,6 +176,7 @@ enum { | |||
| 
 | ||||
| static void userdata_free(struct userdata *u); | ||||
| static int unsuspend(struct userdata *u, bool recovering); | ||||
| static void sync_mixer(struct userdata *u, pa_device_port *port); | ||||
| 
 | ||||
| static pa_hook_result_t reserve_cb(pa_reserve_wrapper *r, void *forced, struct userdata *u) { | ||||
|     pa_assert(r); | ||||
|  | @ -995,6 +996,12 @@ static void suspend(struct userdata *u) { | |||
|     /* Close PCM device */ | ||||
|     close_pcm(u); | ||||
| 
 | ||||
|     /* Disabling the UCM devices may save some power. */ | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(u->source->active_port); | ||||
|         pa_alsa_ucm_port_device_disable(data); | ||||
|     } | ||||
| 
 | ||||
|     pa_log_info("Device suspended..."); | ||||
| } | ||||
| 
 | ||||
|  | @ -1085,6 +1092,13 @@ static int unsuspend(struct userdata *u, bool recovering) { | |||
| 
 | ||||
|     pa_log_info("Trying resume..."); | ||||
| 
 | ||||
|     /* We disable all UCM devices when suspending, so let's enable them again. */ | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(u->source->active_port); | ||||
|         pa_alsa_ucm_port_device_enable(data); | ||||
|         sync_mixer(u, u->source->active_port); | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|      * On some machines, during the system suspend and resume, the thread_func could receive | ||||
|      * POLLERR events before the dev nodes in /dev/snd/ are accessible, and thread_func calls | ||||
|  | @ -1382,6 +1396,12 @@ static void source_get_volume_cb(pa_source *s) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     if (pa_alsa_path_get_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r) < 0) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -1412,6 +1432,12 @@ static void source_set_volume_cb(pa_source *s) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     /* Shift up by the base volume */ | ||||
|     pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume); | ||||
| 
 | ||||
|  | @ -1475,6 +1501,12 @@ static void source_write_volume_cb(pa_source *s) { | |||
|     pa_assert(u->mixer_handle); | ||||
|     pa_assert(s->flags & PA_SOURCE_DEFERRED_VOLUME); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     /* Shift up by the base volume */ | ||||
|     pa_sw_cvolume_divide_scalar(&hw_vol, &hw_vol, s->base_volume); | ||||
| 
 | ||||
|  | @ -1513,6 +1545,14 @@ static int source_get_mute_cb(pa_source *s, bool *mute) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) { | ||||
|             *mute = s->muted; | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (pa_alsa_path_get_mute(u->mixer_path, u->mixer_handle, mute) < 0) | ||||
|         return -1; | ||||
| 
 | ||||
|  | @ -1526,6 +1566,12 @@ static void source_set_mute_cb(pa_source *s) { | |||
|     pa_assert(u->mixer_path); | ||||
|     pa_assert(u->mixer_handle); | ||||
| 
 | ||||
|     if (u->ucm_context) { | ||||
|         pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(s->active_port); | ||||
|         if (pa_alsa_ucm_port_device_status(data) <= 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     pa_alsa_path_set_mute(u->mixer_path, u->mixer_handle, s->muted); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2535,6 +2535,18 @@ static void ucm_port_data_free(pa_device_port *port) { | |||
|     pa_xfree(ucm_port->eld_mixer_device_name); | ||||
| } | ||||
| 
 | ||||
| int pa_alsa_ucm_port_device_enable(pa_alsa_ucm_port_data *data) { | ||||
|     return ucm_device_enable(data->ucm, data->device); | ||||
| } | ||||
| 
 | ||||
| int pa_alsa_ucm_port_device_disable(pa_alsa_ucm_port_data *data) { | ||||
|     return ucm_device_disable(data->ucm, data->device); | ||||
| } | ||||
| 
 | ||||
| long pa_alsa_ucm_port_device_status(pa_alsa_ucm_port_data *data) { | ||||
|     return ucm_device_status(data->ucm, data->device); | ||||
| } | ||||
| 
 | ||||
| #else /* HAVE_ALSA_UCM */ | ||||
| 
 | ||||
| /* Dummy functions for systems without UCM support */ | ||||
|  | @ -2591,4 +2603,16 @@ void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, p | |||
| void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir) { | ||||
| } | ||||
| 
 | ||||
| int pa_alsa_ucm_port_device_enable(pa_alsa_ucm_port_data *data) { | ||||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| int pa_alsa_ucm_port_device_disable(pa_alsa_ucm_port_data *data) { | ||||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| long pa_alsa_ucm_port_device_status(pa_alsa_ucm_port_data *data) { | ||||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -286,6 +286,10 @@ struct pa_alsa_ucm_port_data { | |||
|     int eld_device; /* PCM device number */ | ||||
| }; | ||||
| 
 | ||||
| int pa_alsa_ucm_port_device_enable(pa_alsa_ucm_port_data *data); | ||||
| int pa_alsa_ucm_port_device_disable(pa_alsa_ucm_port_data *data); | ||||
| long pa_alsa_ucm_port_device_status(pa_alsa_ucm_port_data *data); | ||||
| 
 | ||||
| struct pa_alsa_ucm_volume { | ||||
|     char *mixer_elem;	/* mixer element identifier */ | ||||
|     char *master_elem;	/* master mixer element identifier */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alper Nebi Yasak
						Alper Nebi Yasak