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-all
mailing list