ICH7 audio support?

Pyun YongHyeon pyunyh at gmail.com
Thu Nov 3 21:51:31 PST 2005


On Thu, Nov 03, 2005 at 11:27:04AM +0000, Brad Karp wrote:
 > > > 3) How back-compatible is the ICH7 audio hardware with previous
 > > > ICHes?
 > > >    That is, is there any chance that merely by hacking the device
 > > >    probe tables, I can "lie" to the current snd_ich driver that the
 > > >    ICH7 is some earlier-model ICH, and get it to work?
 > > > 
 > > ICH7 supposed to have new Intel High Definition Audio (HDA), which
 > > unfortunately isn't supported (yet). I'm not quite sure whether it is
 > > backward compatible with AC97, but you can try your luck hacking the
 > > driver (/usr/src/sys/dev/sound/pci/ich.c) by adding the appropriate
 > > pci id into ich_pci_probe() function. pciconf -l (chip=xxxx) should
 > > give you the appropriate value for that.
 > 
 > Thanks, Ariff.
 > 
 > When I received your reply, I was already done hacking the device ID
 > for the ICH7 into /sys/dev/sound/pci/ich.c. :-)
 > 
 > I'm happy to report that with this hack, snd_ich appears to support
 > the ICH7 just fine for both audio input and output!
 > 

Ok. Would you try attached patch?
It basically adds a new 80801GB AC97 audio id. to conventional ICH
driver. As the driver now supports so many variants I'd like to make
a table to ease of maintenance. The patch was generated against CURRENT.
I don't have these hardwares so it's just guess work.

-- 
Regards,
Pyun YongHyeon
-------------- next part --------------
--- sys/dev/sound/pci/ich.c.orig	Mon Oct 10 15:27:49 2005
+++ sys/dev/sound/pci/ich.c	Fri Nov  4 14:42:12 2005
@@ -41,11 +41,74 @@
 #define ICH_DEFAULT_BUFSZ 16384
 #define ICH_MAX_BUFSZ 65536
 
-#define SIS7012ID       0x70121039      /* SiS 7012 needs special handling */
-#define ICH4ID		0x24c58086	/* ICH4 needs special handling too */
-#define ICH5ID		0x24d58086	/* ICH5 needs to be treated as ICH4 */
-#define I6300ESBID	0x25a68086	/* 6300ESB needs to be treated as ICH4 */
-#define ICH6ID		0x266e8086	/* ICH6 needs to be treated as ICH4 */
+#define INTEL_VENDORID	0x8086
+#define SIS_VENDORID	0x1039
+#define NVIDIA_VENDORID	0x10de
+#define AMD_VENDORID	0x1022
+
+#define INTEL_82440MX	0x7195
+#define INTEL_82801AA	0x2415
+#define INTEL_82801AB	0x2425
+#define INTEL_82801BA	0x2445
+#define INTEL_82801CA	0x2485
+#define INTEL_82801DB	0x24c5	/* ICH4 needs special handling */
+#define INTEL_82801EB	0x24d5	/* ICH5 needs to be treated as ICH4 */
+#define INTEL_6300ESB	0x25a6	/* 6300ESB needs to be treated as ICH4 */
+#define INTEL_82801FB	0x266e	/* ICH6 needs to be treated as ICH4 */
+#define INTEL_82801GB	0x27de	/* ICH7 needs to be treated as ICH4 */
+#define SIS_7012	0x7012	/* SiS 7012 needs special handling */
+#define NVIDIA_NFORCE	0x01b1
+#define NVIDIA_NFORCE2	0x006a
+#define NVIDIA_NFORCE2_400	0x008a
+#define NVIDIA_NFORCE3	0x00da
+#define NVIDIA_NFORCE3_250	0x00ea
+#define AMD_768		0x7445
+#define AMD_8111	0x746d
+
+static const struct ich_type {
+        uint16_t	vendor;
+        uint16_t	devid;
+	uint32_t	options;
+#define PROBE_LOW	0x01
+        char		*name;
+} ich_devs[] = {
+	{ INTEL_VENDORID,	INTEL_82440MX,	0,
+		"Intel 440MX" },
+	{ INTEL_VENDORID,	INTEL_82801AA,	0,
+		"Intel ICH (82801AA)" },
+	{ INTEL_VENDORID,	INTEL_82801AB,	0,
+		"Intel ICH (82801AB)" },
+	{ INTEL_VENDORID,	INTEL_82801BA,	0,
+		"Intel ICH2 (82801BA)" },
+	{ INTEL_VENDORID,	INTEL_82801CA,	0,
+		"Intel ICH3 (82801CA)" },
+	{ INTEL_VENDORID,	INTEL_82801DB,	PROBE_LOW,
+		"Intel ICH4 (82801DB)" },
+	{ INTEL_VENDORID,	INTEL_82801EB,	PROBE_LOW,
+		"Intel ICH5 (82801EB)" },
+	{ INTEL_VENDORID,	INTEL_6300ESB,	PROBE_LOW,
+		"Intel 6300ESB" },
+	{ INTEL_VENDORID,	INTEL_82801FB,	PROBE_LOW,
+		"Intel ICH6 (82801FB)" },
+	{ INTEL_VENDORID,	INTEL_82801GB,	PROBE_LOW,
+		"Intel ICH7 (82801GB)" },
+	{ SIS_VENDORID,		SIS_7012,	0,
+		"SiS 7012" },
+	{ NVIDIA_VENDORID,	NVIDIA_NFORCE,	0,
+		"nVidia nForce" },
+	{ NVIDIA_VENDORID,	NVIDIA_NFORCE2,	0,
+		"nVidia nForce2" },
+	{ NVIDIA_VENDORID,	NVIDIA_NFORCE2_400,	0,
+		"nVidia nForce2 400" },
+	{ NVIDIA_VENDORID,	NVIDIA_NFORCE3,	0,
+		"nVidia nForce3" },
+	{ NVIDIA_VENDORID,	NVIDIA_NFORCE3_250,	0,
+		"nVidia nForce3 250" },
+	{ AMD_VENDORID,		AMD_768,	0,
+		"AMD-768" },
+	{ AMD_VENDORID,		AMD_8111,	0,
+		"AMD-8111" }
+};
 
 /* buffer descriptor */
 struct ich_desc {
@@ -93,6 +156,8 @@
 	bus_addr_t desc_addr;
 	struct intr_config_hook	intrhook;
 	int use_intrhook;
+	uint16_t vendor;
+	uint16_t devid;
 };
 
 /* -------------------------------------------------------------------- */
@@ -586,10 +651,10 @@
 
 	if ((stat & ICH_GLOB_STA_PCR) == 0) {
 		/* ICH4/ICH5 may fail when busmastering is enabled. Continue */
-		if ((pci_get_devid(sc->dev) != ICH4ID) &&
-		    (pci_get_devid(sc->dev) != ICH5ID) &&
-		    (pci_get_devid(sc->dev) != I6300ESBID) &&
-		    (pci_get_devid(sc->dev) != ICH6ID)) {
+		if (sc->vendor == INTEL_VENDORID && (
+		    sc->devid == INTEL_82801DB || sc->devid == INTEL_82801EB ||
+		    sc->devid == INTEL_6300ESB || sc->devid == INTEL_82801FB ||
+		    sc->devid == INTEL_82801GB)) {
 			return ENXIO;
 		}
 	}
@@ -616,88 +681,29 @@
 static int
 ich_pci_probe(device_t dev)
 {
-	switch(pci_get_devid(dev)) {
-	case 0x71958086:
-		device_set_desc(dev, "Intel 443MX");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x24158086:
-		device_set_desc(dev, "Intel ICH (82801AA)");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x24258086:
-		device_set_desc(dev, "Intel ICH (82801AB)");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x24458086:
-		device_set_desc(dev, "Intel ICH2 (82801BA)");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x24858086:
-		device_set_desc(dev, "Intel ICH3 (82801CA)");
-		return BUS_PROBE_DEFAULT;
-
-	case ICH4ID:
-		device_set_desc(dev, "Intel ICH4 (82801DB)");
-		return BUS_PROBE_LOW_PRIORITY;
-
-	case ICH5ID:
-		device_set_desc(dev, "Intel ICH5 (82801EB)");
-		return BUS_PROBE_LOW_PRIORITY;
-
-	case I6300ESBID:
-		device_set_desc(dev, "Intel 6300ESB");
-		return BUS_PROBE_LOW_PRIORITY;
-
-	case ICH6ID:
-		device_set_desc(dev, "Intel ICH6 (82801FB)");
-		return BUS_PROBE_LOW_PRIORITY;
-
-	case SIS7012ID:
-		device_set_desc(dev, "SiS 7012");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x01b110de:
-		device_set_desc(dev, "nVidia nForce");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x006a10de:
-		device_set_desc(dev, "nVidia nForce2");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x008a10de:
-		device_set_desc(dev, "nVidia nForce2 400");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x00da10de:
-		device_set_desc(dev, "nVidia nForce3");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x00ea10de:
-		device_set_desc(dev, "nVidia nForce3 250");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x005910de:
-		device_set_desc(dev, "nVidia nForce4");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x74451022:
-		device_set_desc(dev, "AMD-768");
-		return BUS_PROBE_DEFAULT;
-
-	case 0x746d1022:
-		device_set_desc(dev, "AMD-8111");
-		return BUS_PROBE_DEFAULT;
+	int i;
+	uint16_t devid, vendor;
 
-	default:
-		return ENXIO;
-	}
+	vendor = pci_get_vendor(dev);
+	devid = pci_get_device(dev);
+	for (i = 0; i < sizeof(ich_devs)/sizeof(ich_devs[0]); i++)
+		if (vendor == ich_devs[i].vendor &&
+		    devid == ich_devs[i].devid) {
+			device_set_desc(dev, ich_devs[i].name);
+			/* allow a better driver to override us */
+			if ((ich_devs[i].options & PROBE_LOW) != 0)
+				return (BUS_PROBE_LOW_PRIORITY);
+			return (BUS_PROBE_DEFAULT);
+		}
+
+	return (ENXIO);
 }
 
 static int
 ich_pci_attach(device_t dev)
 {
 	u_int16_t		extcaps;
+	uint16_t		devid, vendor;
 	struct sc_info 		*sc;
 	char 			status[SND_STATUSLEN];
 
@@ -709,11 +715,13 @@
 	bzero(sc, sizeof(*sc));
 	sc->dev = dev;
 
+	vendor = sc->vendor = pci_get_vendor(dev);
+	devid = sc->devid = pci_get_device(dev);
 	/*
 	 * The SiS 7012 register set isn't quite like the standard ich.
 	 * There really should be a general "quirks" mechanism.
 	 */
-	if (pci_get_devid(dev) == SIS7012ID) {
+	if (vendor == SIS_VENDORID && devid == SIS_7012) {
 		sc->swap_reg = 1;
 		sc->sample_size = 1;
 	} else {
@@ -728,7 +736,7 @@
 	 * but doing so will mess things up here.  ich4 has enough new
 	 * features it warrants it's own driver. 
 	 */
-	if (pci_get_devid(dev) == ICH4ID) {
+	if (vendor == INTEL_VENDORID && devid == INTEL_82801DB) {
 		pci_write_config(dev, PCIR_ICH_LEGACY, ICH_LEGACY_ENABLE, 1);
 	}
 
@@ -738,9 +746,9 @@
 	 */
 	pci_enable_busmaster(dev);
 
-	if (pci_get_devid(dev) == ICH5ID ||
-	    pci_get_devid(dev) == I6300ESBID ||
-	    pci_get_devid(dev) == ICH6ID) {
+	if (vendor == INTEL_VENDORID && (devid == INTEL_82801EB ||
+	    devid == INTEL_6300ESB || devid == INTEL_82801FB ||
+	    devid == INTEL_82801GB)) {
 		sc->nambarid = PCIR_MMBAR;
 		sc->nabmbarid = PCIR_MBBAR;
 		sc->regtype = SYS_RES_MEMORY;


More information about the freebsd-multimedia mailing list