This patch adds support for udev detection of sound card jack event
devices.
The udev methods used to detect ALSA sound cards and sound card input
devices (for jack insertion/removal) are similar and we duplicate the
method in order to detect whether a sound card also has an associated
input event device to report jack status.
If we find a sound card input device, we then load the jack detection
module and pass in details of the newly discovered input device.
Signed-off-by: Margarita Olaya Cabrera m...@slimlogic.co.uk
---
src/modules/module-udev-detect.c | 291 --
1 files changed, 279 insertions(+), 12 deletions(-)
diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
index 63ad195..be7a2dc 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -60,6 +60,7 @@ struct device {
struct userdata {
pa_core *core;
pa_hashmap *devices;
+pa_hashmap *input_devices;
pa_bool_t use_tsched:1;
pa_bool_t ignore_dB:1;
@@ -71,6 +72,9 @@ struct userdata {
int inotify_fd;
pa_io_event *inotify_io;
+
+int inotify_input_fd;
+pa_io_event *inotify_input_io;
};
static const char* const valid_modargs[] = {
@@ -81,6 +85,7 @@ static const char* const valid_modargs[] = {
};
static int setup_inotify(struct userdata *u);
+static int setup_input_notify(struct userdata *u);
static void device_free(struct device *d) {
pa_assert(d);
@@ -163,6 +168,21 @@ static pa_bool_t pcm_is_modem(const char
*card_idx, const char *pcm) {
return is_modem;
}
+static const char *path_get_input_id(const char *path) {
+const char *e;
+
+if (!path)
+return NULL;
+
+if (!(e = strrchr(path, '/')))
+return NULL;
+
+if (!pa_startswith(e, /event))
+return NULL;
+
+return e + 6;
+}
+
static pa_bool_t is_card_busy(const char *id) {
char *card_path = NULL, *pcm_path = NULL, *sub_status = NULL;
DIR *card_dir = NULL, *pcm_dir = NULL;
@@ -352,6 +372,40 @@ static void verify_access(struct userdata *u,
struct device *d) {
}
}
+static void verify_input_access(struct userdata *u, struct device *d) {
+char *cd;
+char *args;
+pa_card *card;
+pa_bool_t accessible;
+
+pa_assert(u);
+pa_assert(d);
+
+cd = pa_sprintf_malloc(%s/input/event%s,
udev_get_dev_path(u-udev), path_get_input_id(d-path));
+accessible = access(cd, R_OK) = 0;
+pa_log_debug(%s is accessible: %s, cd, pa_yes_no(accessible));
+
+if (d-module == PA_INVALID_INDEX) {
+
+/* If we are not loaded, try to load */
+if (accessible) {
+pa_module *m;
+
+args = pa_sprintf_malloc(device_id=\%s\
+card_name=\%s\ , cd, d-card_name);
+
+pa_log_debug(Loading module-alsa-jack detect with
arguments '%s', args);
+m = pa_module_load(u-core, module-alsa-jack-detect, args);
+if (m) {
+ d-module = m-index;
+ pa_log_info(Card %s (%s) jack module loaded.,
d-path, d-card_name);
+} else
+ pa_log_info(Card %s (%s) failed to load jack
module., d-path, d-card_name);
+}
+}
+pa_xfree(cd);
+}
+
static void card_changed(struct userdata *u, struct udev_device *dev) {
struct device *d;
const char *path;
@@ -364,6 +418,8 @@ static void card_changed(struct userdata *u,
struct udev_device *dev) {
/* Maybe /dev/snd is now available? */
setup_inotify(u);
+setup_input_notify(u);
+
path = udev_device_get_devpath(dev);
if ((d = pa_hashmap_get(u-devices, path))) {
@@ -421,6 +477,53 @@ static void remove_card(struct userdata *u,
struct udev_device *dev) {
device_free(d);
}
+static void input_changed(struct userdata *u, struct udev_device *dev) {
+struct device *d;
+const char *path;
+const char *t;
+char *n;
+
+pa_assert(u);
+pa_assert(dev);
+
+/* Maybe /dev/snd is now available? */
+setup_inotify(u);
+
+setup_input_notify(u);
+
+path = udev_device_get_devpath(dev);
+
+if ((d = pa_hashmap_get(u-input_devices, path))) {
+verify_input_access(u, d);
+return;
+}
+
+d = pa_xnew0(struct device, 1);
+d-path = pa_xstrdup(path);
+d-module = PA_INVALID_INDEX;
+PA_INIT_RATELIMIT(d-ratelimit, 10*PA_USEC_PER_SEC, 5);
+pa_hashmap_put(u-input_devices, d-path, d);
+
+verify_input_access(u, d);
+}
+
+static void remove_input(struct userdata *u, struct udev_device *dev) {
+struct device *d;
+
+pa_assert(u);
+pa_assert(dev);
+
+if (!(d = pa_hashmap_remove(u-input_devices,
udev_device_get_devpath(dev
+return;
+
+pa_log_info(Input %s removed., d-path);
+
+if (d-module != PA_INVALID_INDEX)
+pa_module_unload_request_by_index(u-core, d-module, TRUE);
+
+device_free(d);
+}
+
static void process_device(struct userdata *u, struct udev_device *dev) {
const char