FROMLIST: video: rmk's HDMI notification prototype
authorPhilipp Zabel <p.zabel@pengutronix.de>
Wed, 20 Apr 2016 08:59:59 +0000 (10:59 +0200)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 20 Dec 2016 12:02:17 +0000 (20:02 +0800)
This is Russell's HDMI notification prototype [1], currently waiting
for the HDMI CEC situation to resolve.

The use case for the notifications on MediaTek MT8173 is to let the
(dis)connection notifications control an ALSA jack object.

No Signed-off-by since this is not my code, and still up for discussion.

[1] https://patchwork.kernel.org/patch/8351501/

(am from https://patchwork.kernel.org/patch/8887261/)

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Change-Id: I87daa156de6cfa7ff8db9df9d8ecc8c42d76798f

drivers/video/Kconfig
drivers/video/Makefile
drivers/video/hdmi-notifier.c [new file with mode: 0644]
include/linux/hdmi-notifier.h [new file with mode: 0644]

index bdb38b883762b3efc653ec94fea1fa791c3ee1f6..836baa8265dfc4a65be9b877eded6b2eb9093881 100644 (file)
@@ -51,6 +51,9 @@ config VIDEOMODE_HELPERS
 config HDMI
        bool
 
+config HDMI_NOTIFIERS
+       bool
+
 if VT
        source "drivers/video/console/Kconfig"
 endif
index 52ae4ec8f04b1aa9e21a2abba1364e2b2ae2bca7..fee1e05a4df91bd896b7aefdbef26665fa7bb47a 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_VGASTATE)            += vgastate.o
 obj-$(CONFIG_HDMI)                += hdmi.o
+obj-$(CONFIG_HDMI_NOTIFIERS)      += hdmi-notifier.o
 
 obj-$(CONFIG_ADF)                += adf/
 obj-$(CONFIG_VT)                 += console/
diff --git a/drivers/video/hdmi-notifier.c b/drivers/video/hdmi-notifier.c
new file mode 100644 (file)
index 0000000..a233359
--- /dev/null
@@ -0,0 +1,61 @@
+#include <linux/export.h>
+#include <linux/hdmi-notifier.h>
+#include <linux/notifier.h>
+#include <linux/string.h>
+
+static BLOCKING_NOTIFIER_HEAD(hdmi_notifier);
+
+int hdmi_register_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_register(&hdmi_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(hdmi_register_notifier);
+
+int hdmi_unregister_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_unregister(&hdmi_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(hdmi_unregister_notifier);
+
+void hdmi_event_connect(struct device *dev)
+{
+       struct hdmi_event_base base;
+
+       base.source = dev;
+
+       blocking_notifier_call_chain(&hdmi_notifier, HDMI_CONNECTED, &base);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_connect);
+
+void hdmi_event_disconnect(struct device *dev)
+{
+       struct hdmi_event_base base;
+
+       base.source = dev;
+
+       blocking_notifier_call_chain(&hdmi_notifier, HDMI_DISCONNECTED, &base);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_disconnect);
+
+void hdmi_event_new_edid(struct device *dev, const void *edid, size_t size)
+{
+       struct hdmi_event_new_edid new_edid;
+
+       new_edid.base.source = dev;
+       new_edid.edid = edid;
+       new_edid.size = size;
+
+       blocking_notifier_call_chain(&hdmi_notifier, HDMI_NEW_EDID, &new_edid);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_new_edid);
+
+void hdmi_event_new_eld(struct device *dev, const void *eld)
+{
+       struct hdmi_event_new_eld new_eld;
+
+       new_eld.base.source = dev;
+       memcpy(new_eld.eld, eld, sizeof(new_eld.eld));
+
+       blocking_notifier_call_chain(&hdmi_notifier, HDMI_NEW_ELD, &new_eld);
+}
+EXPORT_SYMBOL_GPL(hdmi_event_new_eld);
diff --git a/include/linux/hdmi-notifier.h b/include/linux/hdmi-notifier.h
new file mode 100644 (file)
index 0000000..9c5ad49
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef LINUX_HDMI_NOTIFIER_H
+#define LINUX_HDMI_NOTIFIER_H
+
+#include <linux/types.h>
+
+enum {
+       HDMI_CONNECTED,
+       HDMI_DISCONNECTED,
+       HDMI_NEW_EDID,
+       HDMI_NEW_ELD,
+};
+
+struct hdmi_event_base {
+       struct device *source;
+};
+
+struct hdmi_event_new_edid {
+       struct hdmi_event_base base;
+       const void *edid;
+       size_t size;
+};
+
+struct hdmi_event_new_eld {
+       struct hdmi_event_base base;
+       unsigned char eld[128];
+};
+
+union hdmi_event {
+       struct hdmi_event_base base;
+       struct hdmi_event_new_edid edid;
+       struct hdmi_event_new_eld eld;
+};
+
+struct notifier_block;
+
+int hdmi_register_notifier(struct notifier_block *nb);
+int hdmi_unregister_notifier(struct notifier_block *nb);
+
+void hdmi_event_connect(struct device *dev);
+void hdmi_event_disconnect(struct device *dev);
+void hdmi_event_new_edid(struct device *dev, const void *edid, size_t size);
+void hdmi_event_new_eld(struct device *dev, const void *eld);
+
+#endif