Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/allwinner report hotplug status for AUDIO_GETDE...



details:   https://anonhg.NetBSD.org/src/rev/c9c91c2d6f6e
branches:  trunk
changeset: 333801:c9c91c2d6f6e
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Nov 17 01:38:00 2014 +0000

description:
report hotplug status for AUDIO_GETDEV fields, only allow playback if a capable display is connected

diffstat:

 sys/arch/arm/allwinner/awin_hdmi.c      |  42 ++++++++++++++++++++++++++++++--
 sys/arch/arm/allwinner/awin_hdmiaudio.c |  36 ++++++++++++++++++++++++---
 sys/arch/arm/allwinner/awin_var.h       |  11 +++++++-
 3 files changed, 80 insertions(+), 9 deletions(-)

diffs (192 lines):

diff -r 6e9a2e8a0ee7 -r c9c91c2d6f6e sys/arch/arm/allwinner/awin_hdmi.c
--- a/sys/arch/arm/allwinner/awin_hdmi.c        Mon Nov 17 01:01:57 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_hdmi.c        Mon Nov 17 01:38:00 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_hdmi.c,v 1.13 2014/11/17 00:49:32 jmcneill Exp $ */
+/* $NetBSD: awin_hdmi.c,v 1.14 2014/11/17 01:38:00 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -32,7 +32,7 @@
 #define AWIN_HDMI_PLL  3       /* PLL7 or PLL3 */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.13 2014/11/17 00:49:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.14 2014/11/17 01:38:00 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -64,8 +64,11 @@
        kmutex_t sc_ic_lock;
 
        bool sc_connected;
+       char sc_display_vendor[16];
+       char sc_display_product[16];
 
        u_int sc_display_mode;
+       u_int sc_current_display_mode;
 #define DISPLAY_MODE_AUTO      0
 #define DISPLAY_MODE_HDMI      1
 #define DISPLAY_MODE_DVI       2
@@ -522,6 +525,12 @@
        device_printf(sc->sc_dev, "%s mode (%s)\n",
            display_mode == DISPLAY_MODE_HDMI ? "HDMI" : "DVI", forced);
 
+       strlcpy(sc->sc_display_vendor, ei.edid_vendorname,
+           sizeof(sc->sc_display_vendor));
+       strlcpy(sc->sc_display_product, ei.edid_productname,
+           sizeof(sc->sc_display_product));
+       sc->sc_current_display_mode = display_mode;
+
        mode = ei.edid_preferred_mode;
        if (mode == NULL)
                mode = pick_mode_by_ref(640, 480, 60);
@@ -868,7 +877,6 @@
        if (sc->sc_connected == con)
                return;
 
-       sc->sc_connected = con;
        if (con) {
                device_printf(sc->sc_dev, "display connected\n");
                awin_hdmi_read_edid(sc);
@@ -876,6 +884,8 @@
                device_printf(sc->sc_dev, "display disconnected\n");
                awin_tcon_set_videomode(NULL);
        }
+
+       sc->sc_connected = con;
 }
 
 static void
@@ -908,6 +918,32 @@
 }
 #endif
 
+void
+awin_hdmi_get_info(struct awin_hdmi_info *info)
+{
+       struct awin_hdmi_softc *sc;
+       device_t dev;
+
+       memset(info, 0, sizeof(*info));
+
+       dev = device_find_by_driver_unit("awinhdmi", 0);
+       if (dev == NULL) {
+               info->display_connected = false;
+               return;
+       }
+       sc = device_private(dev);
+
+       info->display_connected = sc->sc_connected;
+       if (info->display_connected) {
+               strlcpy(info->display_vendor, sc->sc_display_vendor,
+                   sizeof(info->display_vendor));
+               strlcpy(info->display_product, sc->sc_display_product,
+                   sizeof(info->display_product));
+               info->display_hdmimode =
+                   sc->sc_current_display_mode == DISPLAY_MODE_HDMI;
+       }
+}
+
 #if defined(DDB)
 void
 awin_hdmi_dump_regs(void)
diff -r 6e9a2e8a0ee7 -r c9c91c2d6f6e sys/arch/arm/allwinner/awin_hdmiaudio.c
--- a/sys/arch/arm/allwinner/awin_hdmiaudio.c   Mon Nov 17 01:01:57 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_hdmiaudio.c   Mon Nov 17 01:38:00 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_hdmiaudio.c,v 1.3 2014/11/12 17:38:14 jmcneill Exp $ */
+/* $NetBSD: awin_hdmiaudio.c,v 1.4 2014/11/17 01:38:00 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_hdmiaudio.c,v 1.3 2014/11/12 17:38:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_hdmiaudio.c,v 1.4 2014/11/17 01:38:00 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -538,14 +538,35 @@
 awin_hdmiaudio_getdev(void *priv, struct audio_device *audiodev)
 {
        struct awin_hdmiaudio_softc *sc = priv;
+       struct awin_hdmi_info info;
+       const char *vendor = NULL, *product = NULL;
 
        const int vmaj = __SHIFTOUT(sc->sc_ver, AWIN_HDMI_VERSION_ID_H);
        const int vmin = __SHIFTOUT(sc->sc_ver, AWIN_HDMI_VERSION_ID_L);
 
-       snprintf(audiodev->name, sizeof(audiodev->name), "Allwinner");
-       snprintf(audiodev->version, sizeof(audiodev->version),
+       awin_hdmi_get_info(&info);
+
+       if (info.display_connected && info.display_hdmimode) {
+               if (strlen(info.display_vendor) > 0 &&
+                   strlen(info.display_product) > 0) {
+                       vendor = info.display_vendor;
+                       product = info.display_product;
+               } else {
+                       vendor = "HDMI";
+                       product = "";
+               }
+       } else if (info.display_connected) {
+               vendor = "DVI";
+               product = "(unsupported)";
+       } else {
+               vendor = "HDMI";
+               product = "(disconnected)";
+       }
+
+       strlcpy(audiodev->name, vendor, sizeof(audiodev->name));
+       strlcpy(audiodev->version, product, sizeof(audiodev->version));
+       snprintf(audiodev->config, sizeof(audiodev->config),
            "HDMI %d.%d", vmaj, vmin);
-       snprintf(audiodev->config, sizeof(audiodev->config), "awin_hdmiaudio");
        return 0;
 }
 
@@ -574,11 +595,16 @@
 {
        struct awin_hdmiaudio_softc *sc = priv;
        struct awin_hdmiaudio_dma *dma;
+       struct awin_hdmi_info info;
        bus_addr_t pstart;
        bus_size_t psize;
        uint32_t dmacfg;
        int error;
 
+       awin_hdmi_get_info(&info);
+       if (info.display_connected == false || info.display_hdmimode == false)
+               return ENXIO;
+
        pstart = 0;
        psize = (uintptr_t)end - (uintptr_t)start;
 
diff -r 6e9a2e8a0ee7 -r c9c91c2d6f6e sys/arch/arm/allwinner/awin_var.h
--- a/sys/arch/arm/allwinner/awin_var.h Mon Nov 17 01:01:57 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_var.h Mon Nov 17 01:38:00 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_var.h,v 1.24 2014/11/14 23:45:02 jmcneill Exp $ */
+/* $NetBSD: awin_var.h,v 1.25 2014/11/17 01:38:00 jmcneill Exp $ */
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -132,6 +132,15 @@
 void   awin_debe_set_videomode(const struct videomode *);
 void   awin_debe_enable(bool);
 int    awin_debe_ioctl(device_t, u_long, void *);
+
+struct awin_hdmi_info {
+       bool    display_connected;
+       char    display_vendor[16];
+       char    display_product[16];
+       bool    display_hdmimode;
+};
+void   awin_hdmi_get_info(struct awin_hdmi_info *);
+
 void   awin_fb_set_videomode(device_t, u_int, u_int);
 void   awin_fb_ddb_trap_callback(int);
 



Home | Main Index | Thread Index | Old Index