svn commit: r195708 - in stable/7/sys: . contrib/pf dev/sound/pci/hda

Alexander Motin mav at FreeBSD.org
Wed Jul 15 10:08:20 UTC 2009


Author: mav
Date: Wed Jul 15 10:08:19 2009
New Revision: 195708
URL: http://svn.freebsd.org/changeset/base/195708

Log:
  MFC r188656, r189086, r189127, r190630, r193228, r193642, r194177, r194861,
      r195690.
  
  Sync snd_hda driver with HEAD, except latest "Sound Mega-commit" r193640.
  
  Except some fixes, this commit also enables MSI interrupts usage by default,
  when supported, except some reported to be broken chips.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/sound/pci/hda/hdac.c

Modified: stable/7/sys/dev/sound/pci/hda/hdac.c
==============================================================================
--- stable/7/sys/dev/sound/pci/hda/hdac.c	Wed Jul 15 09:19:01 2009	(r195707)
+++ stable/7/sys/dev/sound/pci/hda/hdac.c	Wed Jul 15 10:08:19 2009	(r195708)
@@ -83,7 +83,7 @@
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV	"20090329_0131"
+#define HDA_DRV_TEST_REV	"20090624_0136"
 
 SND_DECLARE_FILE("$FreeBSD$");
 
@@ -109,12 +109,6 @@ SND_DECLARE_FILE("$FreeBSD$");
 #define hdac_lockassert(sc)	snd_mtxassert((sc)->lock)
 #define hdac_lockowned(sc)	mtx_owned((sc)->lock)
 
-#undef HDAC_MSI_ENABLED
-#if __FreeBSD_version >= 700026 ||					\
-    (__FreeBSD_version < 700000 && __FreeBSD_version >= 602106)
-#define HDAC_MSI_ENABLED	1
-#endif
-
 #define HDA_FLAG_MATCH(fl, v)	(((fl) & (v)) == (v))
 #define HDA_DEV_MATCH(fl, v)	((fl) == (v) || \
 				(fl) == 0xffffffff || \
@@ -267,6 +261,7 @@ SND_DECLARE_FILE("$FreeBSD$");
 #define ASUS_A7T_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x13c2)
 #define ASUS_W2J_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1971)
 #define ASUS_M5200_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1993)
+#define ASUS_P5PL2_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x817f)
 #define ASUS_P1AH2_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
 #define ASUS_M2NPVMX_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
 #define ASUS_M2V_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81e7)
@@ -474,53 +469,57 @@ static uint32_t hdac_fmt[] = {
 
 static struct pcmchan_caps hdac_caps = {48000, 48000, hdac_fmt, 0};
 
+#define HDAC_NO_MSI	1
+#define HDAC_NO_64BIT	2
+
 static const struct {
 	uint32_t	model;
 	char		*desc;
+	char		flags;
 } hdac_devices[] = {
-	{ HDA_INTEL_82801F,  "Intel 82801F" },
-	{ HDA_INTEL_63XXESB, "Intel 631x/632xESB" },
-	{ HDA_INTEL_82801G,  "Intel 82801G" },
-	{ HDA_INTEL_82801H,  "Intel 82801H" },
-	{ HDA_INTEL_82801I,  "Intel 82801I" },
-	{ HDA_INTEL_82801J,  "Intel 82801J" },
-	{ HDA_INTEL_PCH,     "Intel PCH" },
-	{ HDA_INTEL_SCH,     "Intel SCH" },
-	{ HDA_NVIDIA_MCP51,  "NVidia MCP51" },
-	{ HDA_NVIDIA_MCP55,  "NVidia MCP55" },
-	{ HDA_NVIDIA_MCP61_1, "NVidia MCP61" },
-	{ HDA_NVIDIA_MCP61_2, "NVidia MCP61" },
-	{ HDA_NVIDIA_MCP65_1, "NVidia MCP65" },
-	{ HDA_NVIDIA_MCP65_2, "NVidia MCP65" },
-	{ HDA_NVIDIA_MCP67_1, "NVidia MCP67" },
-	{ HDA_NVIDIA_MCP67_2, "NVidia MCP67" },
-	{ HDA_NVIDIA_MCP73_1, "NVidia MCP73" },
-	{ HDA_NVIDIA_MCP73_2, "NVidia MCP73" },
-	{ HDA_NVIDIA_MCP78_1, "NVidia MCP78" },
-	{ HDA_NVIDIA_MCP78_2, "NVidia MCP78" },
-	{ HDA_NVIDIA_MCP78_3, "NVidia MCP78" },
-	{ HDA_NVIDIA_MCP78_4, "NVidia MCP78" },
-	{ HDA_NVIDIA_MCP79_1, "NVidia MCP79" },
-	{ HDA_NVIDIA_MCP79_2, "NVidia MCP79" },
-	{ HDA_NVIDIA_MCP79_3, "NVidia MCP79" },
-	{ HDA_NVIDIA_MCP79_4, "NVidia MCP79" },
-	{ HDA_ATI_SB450,     "ATI SB450"     },
-	{ HDA_ATI_SB600,     "ATI SB600"     },
-	{ HDA_ATI_RS600,     "ATI RS600"     },
-	{ HDA_ATI_RS690,     "ATI RS690"     },
-	{ HDA_ATI_RS780,     "ATI RS780"     },
-	{ HDA_ATI_R600,      "ATI R600"      },
-	{ HDA_ATI_RV610,     "ATI RV610"     },
-	{ HDA_ATI_RV620,     "ATI RV620"     },
-	{ HDA_ATI_RV630,     "ATI RV630"     },
-	{ HDA_ATI_RV635,     "ATI RV635"     },
-	{ HDA_ATI_RV710,     "ATI RV710"     },
-	{ HDA_ATI_RV730,     "ATI RV730"     },
-	{ HDA_ATI_RV740,     "ATI RV740"     },
-	{ HDA_ATI_RV770,     "ATI RV770"     },
-	{ HDA_VIA_VT82XX,    "VIA VT8251/8237A" },
-	{ HDA_SIS_966,       "SiS 966" },
-	{ HDA_ULI_M5461,     "ULI M5461" },
+	{ HDA_INTEL_82801F,  "Intel 82801F",	0 },
+	{ HDA_INTEL_63XXESB, "Intel 631x/632xESB",	0 },
+	{ HDA_INTEL_82801G,  "Intel 82801G",	0 },
+	{ HDA_INTEL_82801H,  "Intel 82801H",	0 },
+	{ HDA_INTEL_82801I,  "Intel 82801I",	0 },
+	{ HDA_INTEL_82801J,  "Intel 82801J",	0 },
+	{ HDA_INTEL_PCH,     "Intel PCH",	0 },
+	{ HDA_INTEL_SCH,     "Intel SCH",	0 },
+	{ HDA_NVIDIA_MCP51,  "NVidia MCP51",	HDAC_NO_MSI },
+	{ HDA_NVIDIA_MCP55,  "NVidia MCP55",	HDAC_NO_MSI },
+	{ HDA_NVIDIA_MCP61_1, "NVidia MCP61",	0 },
+	{ HDA_NVIDIA_MCP61_2, "NVidia MCP61",	0 },
+	{ HDA_NVIDIA_MCP65_1, "NVidia MCP65",	0 },
+	{ HDA_NVIDIA_MCP65_2, "NVidia MCP65",	0 },
+	{ HDA_NVIDIA_MCP67_1, "NVidia MCP67",	0 },
+	{ HDA_NVIDIA_MCP67_2, "NVidia MCP67",	0 },
+	{ HDA_NVIDIA_MCP73_1, "NVidia MCP73",	0 },
+	{ HDA_NVIDIA_MCP73_2, "NVidia MCP73",	0 },
+	{ HDA_NVIDIA_MCP78_1, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP78_2, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP78_3, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP78_4, "NVidia MCP78",	HDAC_NO_64BIT },
+	{ HDA_NVIDIA_MCP79_1, "NVidia MCP79",	0 },
+	{ HDA_NVIDIA_MCP79_2, "NVidia MCP79",	0 },
+	{ HDA_NVIDIA_MCP79_3, "NVidia MCP79",	0 },
+	{ HDA_NVIDIA_MCP79_4, "NVidia MCP79",	0 },
+	{ HDA_ATI_SB450,     "ATI SB450",	0 },
+	{ HDA_ATI_SB600,     "ATI SB600",	0 },
+	{ HDA_ATI_RS600,     "ATI RS600",	0 },
+	{ HDA_ATI_RS690,     "ATI RS690",	0 },
+	{ HDA_ATI_RS780,     "ATI RS780",	0 },
+	{ HDA_ATI_R600,      "ATI R600",	0 },
+	{ HDA_ATI_RV610,     "ATI RV610",	0 },
+	{ HDA_ATI_RV620,     "ATI RV620",	0 },
+	{ HDA_ATI_RV630,     "ATI RV630",	0 },
+	{ HDA_ATI_RV635,     "ATI RV635",	0 },
+	{ HDA_ATI_RV710,     "ATI RV710",	0 },
+	{ HDA_ATI_RV730,     "ATI RV730",	0 },
+	{ HDA_ATI_RV740,     "ATI RV740",	0 },
+	{ HDA_ATI_RV770,     "ATI RV770",	0 },
+	{ HDA_VIA_VT82XX,    "VIA VT8251/8237A",0 },
+	{ HDA_SIS_966,       "SiS 966",		0 },
+	{ HDA_ULI_M5461,     "ULI M5461",	0 },
 	/* Unknown */
 	{ HDA_INTEL_ALL,  "Intel (Unknown)"  },
 	{ HDA_NVIDIA_ALL, "NVidia (Unknown)" },
@@ -1593,20 +1592,19 @@ hdac_dma_alloc(struct hdac_softc *sc, st
 {
 	bus_size_t roundsz;
 	int result;
-	int lowaddr;
 
 	roundsz = roundup2(size, HDAC_DMA_ALIGNMENT);
-	lowaddr = (sc->support_64bit) ? BUS_SPACE_MAXADDR :
-	    BUS_SPACE_MAXADDR_32BIT;
 	bzero(dma, sizeof(*dma));
 
 	/*
 	 * Create a DMA tag
 	 */
-	result = bus_dma_tag_create(NULL,	/* parent */
+	result = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),		/* parent */
 	    HDAC_DMA_ALIGNMENT,			/* alignment */
 	    0,					/* boundary */
-	    lowaddr,				/* lowaddr */
+	    (sc->support_64bit) ? BUS_SPACE_MAXADDR :
+		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
 	    BUS_SPACE_MAXADDR,			/* highaddr */
 	    NULL,				/* filtfunc */
 	    NULL,				/* fistfuncarg */
@@ -1751,13 +1749,11 @@ hdac_irq_alloc(struct hdac_softc *sc)
 	irq = &sc->irq;
 	irq->irq_rid = 0x0;
 
-#ifdef HDAC_MSI_ENABLED
 	if ((sc->flags & HDAC_F_MSI) &&
 	    (result = pci_msi_count(sc->dev)) == 1 &&
 	    pci_alloc_msi(sc->dev, &result) == 0)
 		irq->irq_rid = 0x1;
 	else
-#endif
 		sc->flags &= ~HDAC_F_MSI;
 
 	irq->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
@@ -1800,10 +1796,8 @@ hdac_irq_free(struct hdac_softc *sc)
 	if (irq->irq_res != NULL)
 		bus_release_resource(sc->dev, SYS_RES_IRQ, irq->irq_rid,
 		    irq->irq_res);
-#ifdef HDAC_MSI_ENABLED
-	if ((sc->flags & HDAC_F_MSI) && irq->irq_rid == 0x1)
+	if (irq->irq_rid == 0x1)
 		pci_release_msi(sc->dev);
-#endif
 	irq->irq_handle = NULL;
 	irq->irq_res = NULL;
 	irq->irq_rid = 0x0;
@@ -2432,13 +2426,20 @@ hdac_widget_pin_getconfig(struct hdac_wi
 	/* New patches */
 	if (id == HDA_CODEC_AD1986A &&
 	    (sc->pci_subvendor == ASUS_M2NPVMX_SUBVENDOR ||
-	    sc->pci_subvendor == ASUS_A8NVMCSM_SUBVENDOR)) {
+	    sc->pci_subvendor == ASUS_A8NVMCSM_SUBVENDOR ||
+	    sc->pci_subvendor == ASUS_P5PL2_SUBVENDOR)) {
 		switch (nid) {
-		case 28: /* 5.1 out => 2.0 out + 2 inputs */
+		case 26: /* Headphones with redirection */
+			patch = "as=1 seq=15";
+			break;
+		case 28: /* 5.1 out => 2.0 out + 1 input */
 			patch = "device=Line-in as=8 seq=1";
 			break;
-		case 29:
-			patch = "device=Mic as=8 seq=2";
+		case 29: /* Can't use this as input, as the only available mic
+			  * preamplifier is busy by front panel mic (nid 31).
+			  * If you want to use this rear connector as mic input,
+			  * you have to disable the front panel one. */
+			patch = "as=0";
 			break;
 		case 31: /* Lot of inputs configured with as=15 and unusable */
 			patch = "as=8 seq=3";
@@ -3990,12 +3991,32 @@ hdac_attach(device_t dev)
 {
 	struct hdac_softc *sc;
 	int result;
-	int i;
+	int i, devid = -1;
+	uint32_t model;
+	uint16_t class, subclass;
 	uint16_t vendor;
 	uint8_t v;
 
 	device_printf(dev, "HDA Driver Revision: %s\n", HDA_DRV_TEST_REV);
 
+	model = (uint32_t)pci_get_device(dev) << 16;
+	model |= (uint32_t)pci_get_vendor(dev) & 0x0000ffff;
+	class = pci_get_class(dev);
+	subclass = pci_get_subclass(dev);
+
+	for (i = 0; i < HDAC_DEVICES_LEN; i++) {
+		if (hdac_devices[i].model == model) {
+			devid = i;
+			break;
+		}
+		if (HDA_DEV_MATCH(hdac_devices[i].model, model) &&
+		    class == PCIC_MULTIMEDIA &&
+		    subclass == PCIS_MULTIMEDIA_HDA) {
+			devid = i;
+			break;
+		}
+	}
+
 	sc = device_get_softc(dev);
 	sc->lock = snd_mtxcreate(device_get_nameunit(dev), HDAC_MTX_NAME);
 	sc->dev = dev;
@@ -4022,29 +4043,6 @@ hdac_attach(device_t dev)
 	else
 		sc->polling = 0;
 
-	result = bus_dma_tag_create(NULL,	/* parent */
-	    HDAC_DMA_ALIGNMENT,			/* alignment */
-	    0,					/* boundary */
-	    BUS_SPACE_MAXADDR_32BIT,		/* lowaddr */
-	    BUS_SPACE_MAXADDR,			/* highaddr */
-	    NULL,				/* filtfunc */
-	    NULL,				/* fistfuncarg */
-	    HDA_BUFSZ_MAX, 			/* maxsize */
-	    1,					/* nsegments */
-	    HDA_BUFSZ_MAX, 			/* maxsegsz */
-	    0,					/* flags */
-	    NULL,				/* lockfunc */
-	    NULL,				/* lockfuncarg */
-	    &sc->chan_dmat);			/* dmat */
-	if (result != 0) {
-		device_printf(dev, "%s: bus_dma_tag_create failed (%x)\n",
-		     __func__, result);
-		snd_mtxfree(sc->lock);
-		free(sc, M_DEVBUF);
-		return (ENXIO);
-	}
-
-
 	sc->hdabus = NULL;
 	for (i = 0; i < HDAC_CODEC_MAX; i++)
 		sc->codecs[i] = NULL;
@@ -4061,14 +4059,17 @@ hdac_attach(device_t dev)
 		);
 	}
 
-#ifdef HDAC_MSI_ENABLED
-	if (resource_int_value(device_get_name(dev),
-	    device_get_unit(dev), "msi", &i) == 0 && i != 0 &&
-	    pci_msi_count(dev) == 1)
-		sc->flags |= HDAC_F_MSI;
-	else
-#endif
+	if (devid >= 0 && (hdac_devices[devid].flags & HDAC_NO_MSI))
 		sc->flags &= ~HDAC_F_MSI;
+	else
+		sc->flags |= HDAC_F_MSI;
+	if (resource_int_value(device_get_name(dev),
+	    device_get_unit(dev), "msi", &i) == 0) {
+		if (i == 0)
+			sc->flags &= ~HDAC_F_MSI;
+		else
+			sc->flags |= HDAC_F_MSI;
+	}
 
 #if defined(__i386__) || defined(__amd64__)
 	sc->flags |= HDAC_F_DMA_NOCACHE;
@@ -4138,6 +4139,9 @@ hdac_attach(device_t dev)
 	if (result != 0)
 		goto hdac_attach_fail;
 
+	if (devid >= 0 && (hdac_devices[devid].flags & HDAC_NO_64BIT))
+		sc->support_64bit = 0;
+
 	/* Allocate CORB and RIRB dma memory */
 	result = hdac_dma_alloc(sc, &sc->corb_dma,
 	    sc->corb_size * sizeof(uint32_t));
@@ -4148,6 +4152,28 @@ hdac_attach(device_t dev)
 	if (result != 0)
 		goto hdac_attach_fail;
 
+	result = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),		/* parent */
+	    HDAC_DMA_ALIGNMENT,			/* alignment */
+	    0,					/* boundary */
+	    (sc->support_64bit) ? BUS_SPACE_MAXADDR :
+		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,			/* highaddr */
+	    NULL,				/* filtfunc */
+	    NULL,				/* fistfuncarg */
+	    HDA_BUFSZ_MAX, 			/* maxsize */
+	    1,					/* nsegments */
+	    HDA_BUFSZ_MAX, 			/* maxsegsz */
+	    0,					/* flags */
+	    NULL,				/* lockfunc */
+	    NULL,				/* lockfuncarg */
+	    &sc->chan_dmat);			/* dmat */
+	if (result != 0) {
+		device_printf(dev, "%s: bus_dma_tag_create failed (%x)\n",
+		     __func__, result);
+		goto hdac_attach_fail;
+	}
+
 	/* Quiesce everything */
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Reset controller...\n");
@@ -4633,6 +4659,7 @@ hdac_vendor_patch_parse(struct hdac_devi
 	}
 
 	switch (id) {
+#if 0
 	case HDA_CODEC_ALC883:
 		/*
 		 * nid: 24/25 = External (jack) or Internal (fixed) Mic.
@@ -4662,6 +4689,7 @@ hdac_vendor_patch_parse(struct hdac_devi
 		 * nid: 26 = Line-in, leave it alone.
 		 */
 		break;
+#endif
 	case HDA_CODEC_AD1983:
 		/*
 		 * This codec has several possible usages, but none
@@ -4715,6 +4743,35 @@ hdac_vendor_patch_parse(struct hdac_devi
 		w = hdac_widget_get(devinfo, 15);
 		if (w != NULL)
 			w->connsenable[3] = 0;
+		/* There is only one mic preamplifier, use it effectively. */
+		w = hdac_widget_get(devinfo, 31);
+		if (w != NULL) {
+			if ((w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
+				w = hdac_widget_get(devinfo, 16);
+				if (w != NULL)
+				    w->connsenable[2] = 0;
+			} else {
+				w = hdac_widget_get(devinfo, 15);
+				if (w != NULL)
+				    w->connsenable[0] = 0;
+			}
+		}
+		w = hdac_widget_get(devinfo, 32);
+		if (w != NULL) {
+			if ((w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
+				w = hdac_widget_get(devinfo, 16);
+				if (w != NULL)
+				    w->connsenable[0] = 0;
+			} else {
+				w = hdac_widget_get(devinfo, 15);
+				if (w != NULL)
+				    w->connsenable[1] = 0;
+			}
+		}
 
 		if (subvendor == ASUS_A8X_SUBVENDOR) {
 			/*


More information about the svn-src-stable mailing list