mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
card: Add messages to enable/disable jack detection
With this patch, messages can be sent to the cards to enable/disable jack detection for the whole card or single ports, manually set a port state and to retrieve the current state of jack detection and port availability.
This commit is contained in:
parent
58521c05e8
commit
f178a5b12e
7 changed files with 95 additions and 21 deletions
|
@ -47,3 +47,28 @@ Object path: /card/<card_name>
|
||||||
Message: get-profile-sticky
|
Message: get-profile-sticky
|
||||||
Parameters: None
|
Parameters: None
|
||||||
Return value: JSON "true" or "false"
|
Return value: JSON "true" or "false"
|
||||||
|
|
||||||
|
Object path: /cards/<card_name>
|
||||||
|
Message: set-jack-detection
|
||||||
|
Parameters: {"port_name|all":true|false}
|
||||||
|
Return value: None
|
||||||
|
|
||||||
|
Object path: /cards/<card_name>
|
||||||
|
Message: get-jack-detection
|
||||||
|
Parameters: "port_name|all"
|
||||||
|
Return value: {"port_name":true|false}
|
||||||
|
If "all" is specified, the returned object looks different:
|
||||||
|
{"Card name":"card_name", "Detection states":{"port_name":true|false, ...}}
|
||||||
|
|
||||||
|
Object path: /cards/<card_name>
|
||||||
|
Message: set-port-state
|
||||||
|
Parameters: {"port_name|all":0|1|2}
|
||||||
|
Return value: None
|
||||||
|
0=unknown, 1=no, 2=yes
|
||||||
|
|
||||||
|
Object path: /cards/<card_name>
|
||||||
|
Message: get-port-state
|
||||||
|
Parameters: "port_name|all"
|
||||||
|
Return value: {"port_name":0|1|2}
|
||||||
|
If "all" is specified, the returned object looks different:
|
||||||
|
{"Card name":"card_name", "Port states":{"port_name":0|1|2, ...}}
|
||||||
|
|
|
@ -2480,7 +2480,7 @@ static void device_set_available(pa_alsa_ucm_device *device, pa_available_t avai
|
||||||
device->available = available;
|
device->available = available;
|
||||||
|
|
||||||
PA_DYNARRAY_FOREACH(port, device->ucm_ports, idx)
|
PA_DYNARRAY_FOREACH(port, device->ucm_ports, idx)
|
||||||
pa_device_port_set_available(port->core_port, port->device->available);
|
pa_device_port_set_available(port->core_port, port->device->available, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) {
|
void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) {
|
||||||
|
@ -2519,7 +2519,7 @@ static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *
|
||||||
port->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
|
port->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
|
||||||
(pa_free_cb_t) pa_alsa_path_free);
|
(pa_free_cb_t) pa_alsa_path_free);
|
||||||
|
|
||||||
pa_device_port_set_available(port->core_port, port->device->available);
|
pa_device_port_set_available(port->core_port, port->device->available, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ucm_port_data_free(pa_device_port *port) {
|
static void ucm_port_data_free(pa_device_port *port) {
|
||||||
|
|
|
@ -435,10 +435,10 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
|
||||||
|
|
||||||
for (tp = tports; tp->port; tp++)
|
for (tp = tports; tp->port; tp++)
|
||||||
if (tp->avail != PA_AVAILABLE_NO)
|
if (tp->avail != PA_AVAILABLE_NO)
|
||||||
pa_device_port_set_available(tp->port, tp->avail);
|
pa_device_port_set_available(tp->port, tp->avail, false);
|
||||||
for (tp = tports; tp->port; tp++)
|
for (tp = tports; tp->port; tp++)
|
||||||
if (tp->avail == PA_AVAILABLE_NO)
|
if (tp->avail == PA_AVAILABLE_NO)
|
||||||
pa_device_port_set_available(tp->port, tp->avail);
|
pa_device_port_set_available(tp->port, tp->avail, false);
|
||||||
|
|
||||||
for (tp = tports; tp->port; tp++) {
|
for (tp = tports; tp->port; tp++) {
|
||||||
pa_alsa_port_data *data;
|
pa_alsa_port_data *data;
|
||||||
|
|
|
@ -2340,9 +2340,9 @@ static void handle_transport_state_change(struct userdata *u, struct pa_bluetoot
|
||||||
|
|
||||||
/* Update port availability */
|
/* Update port availability */
|
||||||
pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
|
pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
|
||||||
pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT));
|
pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT), false);
|
||||||
pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
|
pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
|
||||||
pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT));
|
pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT), false);
|
||||||
|
|
||||||
/* Acquire or release transport as needed */
|
/* Acquire or release transport as needed */
|
||||||
acquire = (t->state == PA_BLUETOOTH_TRANSPORT_STATE_PLAYING && u->profile == t->profile);
|
acquire = (t->state == PA_BLUETOOTH_TRANSPORT_STATE_PLAYING && u->profile == t->profile);
|
||||||
|
|
|
@ -163,10 +163,10 @@ static int card_message_handler(const char *object_path, const char *message, co
|
||||||
pa_card *c = userdata;
|
pa_card *c = userdata;
|
||||||
const char *port_name;
|
const char *port_name;
|
||||||
bool jack_detection;
|
bool jack_detection;
|
||||||
|
int64_t port_state;
|
||||||
void *state = NULL;
|
void *state = NULL;
|
||||||
pa_device_port *port = NULL;
|
pa_device_port *port = NULL;
|
||||||
const pa_json_object *o;
|
const pa_json_object *o;
|
||||||
int64_t current_state;
|
|
||||||
char *message_handler_path;
|
char *message_handler_path;
|
||||||
|
|
||||||
pa_assert(c);
|
pa_assert(c);
|
||||||
|
@ -240,7 +240,7 @@ static int card_message_handler(const char *object_path, const char *message, co
|
||||||
pa_log_info("Parameters type does not match message command");
|
pa_log_info("Parameters type does not match message command");
|
||||||
return -PA_ERR_INVALID;
|
return -PA_ERR_INVALID;
|
||||||
}
|
}
|
||||||
current_state = pa_json_object_get_int(o);
|
port_state = pa_json_object_get_int(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -256,15 +256,35 @@ static int card_message_handler(const char *object_path, const char *message, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state = NULL;
|
||||||
|
|
||||||
if (pa_streq(message, "set-jack-detection")) {
|
if (pa_streq(message, "set-jack-detection")) {
|
||||||
|
|
||||||
if (!port) {
|
if (!port) {
|
||||||
|
|
||||||
PA_HASHMAP_FOREACH(port, c->ports, state)
|
PA_HASHMAP_FOREACH(port, c->ports, state) {
|
||||||
port->jack_detection = jack_detection;
|
pa_available_t avail = PA_AVAILABLE_UNKNOWN;
|
||||||
|
|
||||||
|
/* If jack detection was enabled, set the port state
|
||||||
|
* to the hardware state. */
|
||||||
|
if (jack_detection)
|
||||||
|
avail = port->hw_available;
|
||||||
|
|
||||||
|
port->jack_detection = jack_detection;
|
||||||
|
pa_device_port_set_available(port, avail, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pa_available_t avail = PA_AVAILABLE_UNKNOWN;
|
||||||
|
|
||||||
|
/* If jack detection was enabled, set the port state
|
||||||
|
* to the hardware state. */
|
||||||
|
if (jack_detection)
|
||||||
|
avail = port->hw_available;
|
||||||
|
|
||||||
} else
|
|
||||||
port->jack_detection = jack_detection;
|
port->jack_detection = jack_detection;
|
||||||
|
pa_device_port_set_available(port, avail, true);
|
||||||
|
}
|
||||||
|
|
||||||
return PA_OK;
|
return PA_OK;
|
||||||
|
|
||||||
|
@ -291,10 +311,25 @@ static int card_message_handler(const char *object_path, const char *message, co
|
||||||
|
|
||||||
} else if (pa_streq(message, "set-port-state")) {
|
} else if (pa_streq(message, "set-port-state")) {
|
||||||
|
|
||||||
/* Not implemented because jack_detection is still unused
|
/* Validate port state parameter */
|
||||||
* and manually setting a port state would require to disable
|
if ((pa_available_t) port_state > PA_AVAILABLE_YES)
|
||||||
* jack detection */
|
return -PA_ERR_INVALID;
|
||||||
return -PA_ERR_NOTIMPLEMENTED;
|
|
||||||
|
if (!port) {
|
||||||
|
|
||||||
|
PA_HASHMAP_FOREACH(port, c->ports, state) {
|
||||||
|
|
||||||
|
port->jack_detection = false;
|
||||||
|
pa_device_port_set_available(port, (pa_available_t) port_state, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
port->jack_detection = false;
|
||||||
|
pa_device_port_set_available(port, (pa_available_t) port_state, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PA_OK;
|
||||||
|
|
||||||
} else if (pa_streq(message, "get-port-state")) {
|
} else if (pa_streq(message, "get-port-state")) {
|
||||||
pa_json_encoder *encoder;
|
pa_json_encoder *encoder;
|
||||||
|
@ -306,14 +341,14 @@ static int card_message_handler(const char *object_path, const char *message, co
|
||||||
|
|
||||||
pa_json_encoder_begin_member_object(encoder, "Port states");
|
pa_json_encoder_begin_member_object(encoder, "Port states");
|
||||||
PA_HASHMAP_FOREACH(port, c->ports, state) {
|
PA_HASHMAP_FOREACH(port, c->ports, state) {
|
||||||
current_state = port->available;
|
port_state = port->available;
|
||||||
pa_json_encoder_add_member_int(encoder, port->name, current_state);
|
pa_json_encoder_add_member_int(encoder, port->name, port_state);
|
||||||
}
|
}
|
||||||
pa_json_encoder_end_object(encoder);
|
pa_json_encoder_end_object(encoder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
current_state = port->available;
|
port_state = port->available;
|
||||||
pa_json_encoder_add_member_int(encoder, port->name, current_state);
|
pa_json_encoder_add_member_int(encoder, port->name, port_state);
|
||||||
}
|
}
|
||||||
pa_json_encoder_end_object(encoder);
|
pa_json_encoder_end_object(encoder);
|
||||||
|
|
||||||
|
|
|
@ -90,12 +90,25 @@ void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
|
void pa_device_port_set_available(pa_device_port *p, pa_available_t status, bool force) {
|
||||||
pa_assert(p);
|
pa_assert(p);
|
||||||
|
|
||||||
|
/* If force is not set, status reflects the state of the port from a
|
||||||
|
* hardware perspective. We need to keep track of the real port state
|
||||||
|
* so that we can go back to it once jack detection is enabled for the
|
||||||
|
* port. If force is set, we are updating the port state manually, so
|
||||||
|
* the hardware state is unaffected. */
|
||||||
|
if (!force)
|
||||||
|
p->hw_available = status;
|
||||||
|
|
||||||
if (p->available == status)
|
if (p->available == status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Do not set the port state if jack detection is disabled for the port
|
||||||
|
* unless we are setting the state manually. */
|
||||||
|
if (!force && !p->jack_detection)
|
||||||
|
return;
|
||||||
|
|
||||||
/* pa_assert(status != PA_AVAILABLE_UNKNOWN); */
|
/* pa_assert(status != PA_AVAILABLE_UNKNOWN); */
|
||||||
|
|
||||||
p->available = status;
|
p->available = status;
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct pa_device_port {
|
||||||
unsigned priority;
|
unsigned priority;
|
||||||
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
|
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
|
||||||
char *availability_group; /* a string indentifier which determine the group of devices handling the available state simulteneously */
|
char *availability_group; /* a string indentifier which determine the group of devices handling the available state simulteneously */
|
||||||
|
pa_available_t hw_available;
|
||||||
|
|
||||||
pa_proplist *proplist;
|
pa_proplist *proplist;
|
||||||
pa_hashmap *profiles; /* Does not own the profiles */
|
pa_hashmap *profiles; /* Does not own the profiles */
|
||||||
|
@ -88,7 +89,7 @@ void pa_device_port_new_data_done(pa_device_port_new_data *data);
|
||||||
pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, size_t extra);
|
pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, size_t extra);
|
||||||
|
|
||||||
/* The port's available status has changed */
|
/* The port's available status has changed */
|
||||||
void pa_device_port_set_available(pa_device_port *p, pa_available_t available);
|
void pa_device_port_set_available(pa_device_port *p, pa_available_t available, bool force);
|
||||||
|
|
||||||
void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
|
void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
|
||||||
void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp);
|
void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue