Module Name:    src
Committed By:   jmcneill
Date:           Mon Nov 17 01:38:00 UTC 2014

Modified Files:
        src/sys/arch/arm/allwinner: awin_hdmi.c awin_hdmiaudio.c awin_var.h

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


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/allwinner/awin_hdmi.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/allwinner/awin_hdmiaudio.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/arm/allwinner/awin_var.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/allwinner/awin_hdmi.c
diff -u src/sys/arch/arm/allwinner/awin_hdmi.c:1.13 src/sys/arch/arm/allwinner/awin_hdmi.c:1.14
--- src/sys/arch/arm/allwinner/awin_hdmi.c:1.13	Mon Nov 17 00:49:32 2014
+++ src/sys/arch/arm/allwinner/awin_hdmi.c	Mon Nov 17 01:38:00 2014
@@ -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 <jmcne...@invisible.ca>
@@ -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 @@ struct awin_hdmi_softc {
 	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 @@ awin_hdmi_read_edid(struct awin_hdmi_sof
 	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 @@ awin_hdmi_hpd(struct awin_hdmi_softc *sc
 	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 @@ awin_hdmi_hpd(struct awin_hdmi_softc *sc
 		device_printf(sc->sc_dev, "display disconnected\n");
 		awin_tcon_set_videomode(NULL);
 	}
+
+	sc->sc_connected = con;
 }
 
 static void
@@ -908,6 +918,32 @@ awin_hdmi_intr(void *priv)
 }
 #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)

Index: src/sys/arch/arm/allwinner/awin_hdmiaudio.c
diff -u src/sys/arch/arm/allwinner/awin_hdmiaudio.c:1.3 src/sys/arch/arm/allwinner/awin_hdmiaudio.c:1.4
--- src/sys/arch/arm/allwinner/awin_hdmiaudio.c:1.3	Wed Nov 12 17:38:14 2014
+++ src/sys/arch/arm/allwinner/awin_hdmiaudio.c	Mon Nov 17 01:38:00 2014
@@ -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 <jmcne...@invisible.ca>
@@ -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 @@ static int
 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 @@ awin_hdmiaudio_trigger_output(void *priv
 {
 	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;
 

Index: src/sys/arch/arm/allwinner/awin_var.h
diff -u src/sys/arch/arm/allwinner/awin_var.h:1.24 src/sys/arch/arm/allwinner/awin_var.h:1.25
--- src/sys/arch/arm/allwinner/awin_var.h:1.24	Fri Nov 14 23:45:02 2014
+++ src/sys/arch/arm/allwinner/awin_var.h	Mon Nov 17 01:38:00 2014
@@ -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_tcon_enable(bool);
 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);
 

Reply via email to