device_free(d);
}
+#ifdef __TIZEN__
+static void dump_device(struct udev_device *dev) {
+ pa_log_debug("[ devpath = %s", udev_device_get_devpath(dev));
+ pa_log_debug(" subsystem = %s", udev_device_get_subsystem(dev));
+ pa_log_debug(" devtype = %s", udev_device_get_devtype(dev));
+ pa_log_debug(" syspath = %s", udev_device_get_syspath(dev));
+ pa_log_debug(" sysname = %s", udev_device_get_sysname(dev));
+ pa_log_debug(" sysnum = %s", udev_device_get_sysnum(dev));
+ pa_log_debug(" devnode = %s", udev_device_get_devnode(dev));
+ pa_log_debug(" parent subsystem = %s ]", udev_device_get_subsystem(udev_device_get_parent(dev)));
+}
+
+static bool is_devpath_hdmi_extcon(struct udev_device *dev) {
+ return (bool)strstr(udev_device_get_devpath(dev), "hdmi");
+}
+
+static void add_hdmi_card(struct userdata *u, const char *card) {
+ struct udev *udev;
+ struct udev_device *card_dev;
+ char *syspath;
+
+ if (!(udev = udev_new())) {
+ pa_log_error("Failed to allocate udev context.");
+ return;
+ }
+
+ syspath = pa_sprintf_malloc("/sys/class/sound/%s", card);
+
+ if ((card_dev = udev_device_new_from_syspath(udev, syspath))) {
+ card_changed(u, card_dev);
+ udev_device_unref(card_dev);
+ } else {
+ pa_log_error("Failed to get card object.");
+ }
+
+ pa_xfree(syspath);
+ udev_unref(udev);
+}
+
+/* NOTE : based from pa_card_choose_initial_profile() */
+pa_card_profile *find_best_card_profile(pa_card *card) {
+ pa_card_profile *profile;
+ void *state;
+ pa_card_profile *best = NULL;
+
+ pa_assert(card);
+
+ pa_log_info("Looking for best profile for card %s", card->name);
+ PA_HASHMAP_FOREACH(profile, card->profiles, state) {
+ pa_log_debug(" name(%s), avail(%s)", profile->name, pa_available_to_string(profile->available));
+ if (profile->available == PA_AVAILABLE_NO)
+ continue;
+
+ if (!best || profile->priority > best->priority)
+ best = profile;
+ }
+
+ if (!best) {
+ PA_HASHMAP_FOREACH(profile, card->profiles, state) {
+ if (!best || profile->priority > best->priority)
+ best = profile;
+ }
+ }
+
+ if (best)
+ pa_log_info("Found best profile %s", best->name);
+ else
+ pa_log_error("No best profile!");
+
+ return best;
+}
+
+static void process_hdmi_device(struct userdata *u, struct udev_device *dev) {
+ pa_card *card;
+ uint32_t idx;
+ bool is_removed;
+ const char *devtype;
+ const char *event_str[] = { "Added", "Removed" };
+ const char *sysfs_path;
+ char *card_to_find;
+ pa_card_profile *profile_to_set;
+
+ pa_assert(u);
+ pa_assert(dev);
+
+ devtype = udev_device_get_devtype(dev);
+ if (!devtype) {
+ pa_log_error("no parent devtype exist!");
+ return;
+ }
+
+ dump_device(dev);
+ is_removed = pa_safe_streq(udev_device_get_property_value(dev, "STATE"), "HDMI=0");
+
+ if (!pa_startswith(devtype, "extcon")) {
+ pa_log_error("invalid devtype %s", devtype);
+ return;
+ }
+
+ card_to_find = pa_replace(devtype, "extcon", "card");
+
+ pa_log_info("%s %s, devtype : %s", card_to_find, event_str[is_removed], devtype);
+
+ PA_IDXSET_FOREACH(card, u->core->cards, idx) {
+ sysfs_path = pa_proplist_gets(card->proplist, "sysfs.path");
+ if (!sysfs_path) {
+ pa_log_warn("no sysfs.path property...");
+ continue;
+ }
+ pa_log_info("sysfs.path : %s, finding : %s", sysfs_path, card_to_find);
+
+ if (pa_endswith(sysfs_path, card_to_find)) {
+ pa_log_info(" card exists, update proper profile for event (%s)", event_str[is_removed]);
+
+ profile_to_set = is_removed ? pa_hashmap_get(card->profiles, "off") : find_best_card_profile(card);
+
+ if (profile_to_set)
+ pa_card_set_profile(card, profile_to_set, false);
+ else
+ pa_log_error("no profile to set!");
+
+ goto profile_done;
+ }
+ }
+
+ pa_log_info("No card found, add new card (%s)", card_to_find);
+ add_hdmi_card(u, card_to_find);
+
+profile_done:
+ pa_xfree(card_to_find);
+}
+#endif /* __TIZEN__ */
+
static void process_device(struct userdata *u, struct udev_device *dev) {
const char *action, *ff;
}
#ifdef __TIZEN__
- pa_log_debug ("devpath = %s", udev_device_get_devpath(dev));
- pa_log_debug ("subsystem = %s", udev_device_get_subsystem(dev));
- pa_log_debug ("devtype = %s", udev_device_get_devtype(dev));
- pa_log_debug ("syspath = %s", udev_device_get_syspath(dev));
- pa_log_debug ("sysname = %s", udev_device_get_sysname(dev));
- pa_log_debug ("sysnum = %s", udev_device_get_sysnum(dev));
- pa_log_debug ("devnode = %s", udev_device_get_devnode(dev));
- pa_log_debug ("parent subsystem = %s", udev_device_get_subsystem(udev_device_get_parent(dev)));
+ dump_device(dev);
#endif
action = udev_device_get_action(dev);
goto fail;
}
+#ifdef __TIZEN__
+ if (is_devpath_hdmi_extcon(dev)) {
+ pa_log_info("HDMI, devpath : %s", udev_device_get_devpath(dev));
+ process_hdmi_device(u, dev);
+ udev_device_unref(dev);
+ return;
+ }
+#endif
if (!path_get_card_id(udev_device_get_devpath(dev))) {
udev_device_unref(dev);
return;
pa_log("Failed to subscribe to sound devices.");
goto fail;
}
+#ifdef __TIZEN__
+ if (udev_monitor_filter_add_match_subsystem_devtype(u->monitor, "extcon", NULL) < 0) {
+ pa_log("Failed to subscribe to extcon devices.");
+ goto fail;
+ }
+#endif
errno = 0;
if (udev_monitor_enable_receiving(u->monitor) < 0) {