- Gigabyte G33-S2H fixup, due to the present of multiple competing
authorHasso Tepper <hasso@dragonflybsd.org>
Fri, 30 Nov 2007 07:53:53 +0000 (07:53 +0000)
committerHasso Tepper <hasso@dragonflybsd.org>
Fri, 30 Nov 2007 07:53:53 +0000 (07:53 +0000)
  codecs. Codec at address 0 seems purely digital, or perhaps an HDMI
  interface. Let the driver skip it and continue scanning the codecs
  starting with address 2 (Realtek ALC885).

- Trivial headphone / speaker automute fixup for Fujitsu-Siemens
  AMILO Si 1848 laptop.

- Trivial headphone / speaker automute fixup for Fujitsu-Siemens
  Lifebook S7020D laptop.

- Some smart vendor trying to create interplanetary wormhole by
  screwing pci config space during their BIOS update. The side effects
  of their failure attempt includes mutilated hardware id, broken
  speaker automuting and loosing the entire analog CD connectivity,
  thus causing enough collateral damages to collapse the entire
  universe.  Move along with it.
  Please exercise extra cautious when applying BIOS updates.

- Fix no sound issues (on headphones) for Lenovo ThinkCentre A55 due
  to global automute table entry which is not applicable for
  non-laptops.

- Speaker mute control for HP DC7700 since the front headphone jack
  does not generate any interesting unsolicited signal/response.

Obtained-from: FreeBSD

sys/dev/sound/pci/hda/hdac.c

index 3491846..b89892e 100644 (file)
@@ -24,8 +24,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/sound/pci/hda/hdac.c,v 1.36.2.5 2007/07/12 06:39:08 ariff Exp $
- * $DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.11 2007/11/30 07:47:44 hasso Exp $
+ * $FreeBSD: src/sys/dev/sound/pci/hda/hdac.c,v 1.36.2.6 2007/10/26 20:48:18 ariff Exp $
+ * $DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.12 2007/11/30 07:53:53 hasso Exp $
  */
 
 /*
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV       "20070710_0047"
+#define HDA_DRV_TEST_REV       "20071020_0048"
 #define HDA_WIDGET_PARSER_REV  1
 
-SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.11 2007/11/30 07:47:44 hasso Exp $");
+SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.12 2007/11/30 07:53:53 hasso Exp $");
 
 #define HDA_BOOTVERBOSE(stmt)  do {                    \
        if (bootverbose != 0) {                         \
@@ -193,6 +193,7 @@ SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.11 2007/11/30
 #define HP_XW4300_SUBVENDOR    HDA_MODEL_CONSTRUCT(HP, 0x3013)
 #define HP_3010_SUBVENDOR      HDA_MODEL_CONSTRUCT(HP, 0x3010)
 #define HP_DV5000_SUBVENDOR    HDA_MODEL_CONSTRUCT(HP, 0x30a5)
+#define HP_DC7700_SUBVENDOR    HDA_MODEL_CONSTRUCT(HP, 0x2802)
 #define HP_ALL_SUBVENDOR       HDA_MODEL_CONSTRUCT(HP, 0xffff)
 /* What is wrong with XN 2563 anyway? (Got the picture ?) */
 #define HP_NX6325_SUBVENDORX   0x103c30b0
@@ -242,6 +243,7 @@ SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.11 2007/11/30
 /* Lenovo */
 #define LENOVO_VENDORID                0x17aa
 #define LENOVO_3KN100_SUBVENDOR        HDA_MODEL_CONSTRUCT(LENOVO, 0x2066)
+#define LENOVO_TCA55_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x1015)
 #define LENOVO_ALL_SUBVENDOR   HDA_MODEL_CONSTRUCT(LENOVO, 0xffff)
 
 /* Samsung */
@@ -269,8 +271,14 @@ SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.11 2007/11/30
 /* Fujitsu Siemens */
 #define FS_VENDORID            0x1734
 #define FS_PA1510_SUBVENDOR    HDA_MODEL_CONSTRUCT(FS, 0x10b8)
+#define FS_SI1848_SUBVENDOR    HDA_MODEL_CONSTRUCT(FS, 0x10cd)
 #define FS_ALL_SUBVENDOR       HDA_MODEL_CONSTRUCT(FS, 0xffff)
 
+/* Fujitsu Limited */
+#define FL_VENDORID            0x10cf
+#define FL_S7020D_SUBVENDOR    HDA_MODEL_CONSTRUCT(FL, 0x1326)
+#define FL_ALL_SUBVENDOR       HDA_MODEL_CONSTRUCT(FL, 0xffff)
+
 /* Toshiba */
 #define TOSHIBA_VENDORID       0x1179
 #define TOSHIBA_U200_SUBVENDOR HDA_MODEL_CONSTRUCT(TOSHIBA, 0x0001)
@@ -279,8 +287,14 @@ SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/hda/hdac.c,v 1.11 2007/11/30
 /* Micro-Star International (MSI) */
 #define MSI_VENDORID           0x1462
 #define MSI_MS1034_SUBVENDOR   HDA_MODEL_CONSTRUCT(MSI, 0x0349)
+#define MSI_MS034A_SUBVENDOR   HDA_MODEL_CONSTRUCT(MSI, 0x034a)
 #define MSI_ALL_SUBVENDOR      HDA_MODEL_CONSTRUCT(MSI, 0xffff)
 
+/* Giga-Byte Technology */
+#define GB_VENDORID            0x1458
+#define GB_G33S2H_SUBVENDOR    HDA_MODEL_CONSTRUCT(GB, 0xa022)
+#define GP_ALL_SUBVENDOR       HDA_MODEL_CONSTRUCT(GB, 0xffff)
+
 /* Uniwill ? */
 #define UNIWILL_VENDORID       0x1584
 #define UNIWILL_9075_SUBVENDOR HDA_MODEL_CONSTRUCT(UNIWILL, 0x9075)
@@ -640,14 +654,16 @@ static const struct {
            0, 0, -1, 17, { 16, -1 }, 16 },
        /* { HP_XW4300_SUBVENDOR, HDA_CODEC_ALC260, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 21, { 16, 17, -1 }, -1 } */
-       /*{ HP_3010_SUBVENDOR,  HDA_CODEC_ALC260, HDAC_HP_SWITCH_DEBUG,
-           0, 1, 0, 16, { 15, 18, 19, 20, 21, -1 }, -1 },*/
+       /* { HP_3010_SUBVENDOR,  HDA_CODEC_ALC260, HDAC_HP_SWITCH_DEBUG,
+           0, 1, 0, 16, { 15, 18, 19, 20, 21, -1 }, -1 }, */
        { HP_NX7400_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 6, { 5, -1 }, 5 },
        { HP_NX6310_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 6, { 5, -1 }, 5 },
        { HP_NX6325_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 6, { 5, -1 }, 5 },
+       /* { HP_DC7700_SUBVENDOR, HDA_CODEC_ALC262, HDAC_HP_SWITCH_CTL,
+           0, 0, -1, 21, { 22, 27, -1 }, -1 }, */
        { TOSHIBA_U200_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 6, { 5, -1 }, -1 },
        { DELL_D820_SUBVENDOR, HDA_CODEC_STAC9220, HDAC_HP_SWITCH_CTRL,
@@ -660,6 +676,8 @@ static const struct {
            0, 0, -1, 10, { 13, -1 }, -1 },
        { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDAC_HP_SWITCH_CTL,
            1, 0, -1, 26, { 27, -1 }, -1 },
+       /* { LENOVO_TCA55_SUBVENDOR, HDA_CODEC_AD1986A, HDAC_HP_SWITCH_CTL,
+           0, 0, -1, 26, { 27, 28, 29, 30, -1 }, -1 }, */
        { LG_LW20_SUBVENDOR, HDA_CODEC_ALC880, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 27, { 20, -1 }, -1 },
        { ACER_A5050_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL,
@@ -670,6 +688,12 @@ static const struct {
            0, 0, -1, 20, { 21, -1 }, -1 },
        { MSI_MS1034_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 20, { 27, -1 }, -1 },
+       { MSI_MS034A_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL,
+           0, 0, -1, 20, { 27, -1 }, -1 },
+       { FS_SI1848_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL,
+           0, 0, -1, 20, { 21, -1 }, -1 },
+       { FL_S7020D_SUBVENDOR, HDA_CODEC_ALC260, HDAC_HP_SWITCH_CTL,
+           0, 0, -1, 20, { 16, -1 }, -1 },
        /*
         * All models that at least come from the same vendor with
         * simmilar codec.
@@ -682,9 +706,9 @@ static const struct {
            0, 0, -1, 6, { 5, -1 }, -1 },
        { DELL_ALL_SUBVENDOR, HDA_CODEC_STAC9220, HDAC_HP_SWITCH_CTRL,
            0, 0, -1, 13, { 14, -1 }, -1 },
+#if 0
        { LENOVO_ALL_SUBVENDOR, HDA_CODEC_AD1986A, HDAC_HP_SWITCH_CTL,
            1, 0, -1, 26, { 27, -1 }, -1 },
-#if 0
        { ACER_ALL_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL,
            0, 0, -1, 20, { 21, -1 }, -1 },
 #endif
@@ -723,7 +747,7 @@ static void hdac_corb_init(struct hdac_softc *);
 static void    hdac_rirb_init(struct hdac_softc *);
 static void    hdac_corb_start(struct hdac_softc *);
 static void    hdac_rirb_start(struct hdac_softc *);
-static void    hdac_scan_codecs(struct hdac_softc *);
+static void    hdac_scan_codecs(struct hdac_softc *, int);
 static int     hdac_probe_codec(struct hdac_codec *);
 static struct  hdac_devinfo *hdac_probe_function(struct hdac_codec *, nid_t);
 static void    hdac_add_child(struct hdac_softc *, struct hdac_devinfo *);
@@ -1732,19 +1756,24 @@ hdac_rirb_start(struct hdac_softc *sc)
 
 
 /****************************************************************************
- * void hdac_scan_codecs(struct hdac_softc *)
+ * void hdac_scan_codecs(struct hdac_softc *, int)
  *
- * Scan the bus for available codecs.
+ * Scan the bus for available codecs, starting with num.
  ****************************************************************************/
 static void
-hdac_scan_codecs(struct hdac_softc *sc)
+hdac_scan_codecs(struct hdac_softc *sc, int num)
 {
        struct hdac_codec *codec;
        int i;
        uint16_t statests;
 
+       if (num < 0)
+               num = 0;
+       if (num >= HDAC_CODEC_MAX)
+               num = HDAC_CODEC_MAX - 1;
+
        statests = HDAC_READ_2(&sc->mem, HDAC_STATESTS);
-       for (i = 0; i < HDAC_CODEC_MAX; i++) {
+       for (i = num; i < HDAC_CODEC_MAX; i++) {
                if (HDAC_STATESTS_SDIWAKE(statests, i)) {
                        /* We have found a codec. */
                        codec = (struct hdac_codec *)kmalloc(sizeof(*codec),
@@ -2037,7 +2066,8 @@ hdac_widget_pin_getconfig(struct hdac_widget *w)
                        break;
                }
        } else if (id == HDA_CODEC_ALC883 &&
-           HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, sc->pci_subvendor)) {
+           (sc->pci_subvendor == MSI_MS034A_SUBVENDOR ||
+           HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, sc->pci_subvendor))) {
                switch (nid) {
                case 25:
                        config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
@@ -4250,6 +4280,20 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo)
                        }
                }
                break;
+       case HDA_CODEC_ALC262:
+               if (subvendor == HP_DC7700_SUBVENDOR) {
+                       ctl = hdac_audio_ctl_amp_get(devinfo, 22, 0, 1);
+                       if (ctl != NULL && ctl->widget != NULL) {
+                               ctl->ossmask = SOUND_MASK_SPEAKER;
+                               ctl->widget->ctlflags |= SOUND_MASK_SPEAKER;
+                       }
+                       ctl = hdac_audio_ctl_amp_get(devinfo, 27, 0, 1);
+                       if (ctl != NULL && ctl->widget != NULL) {
+                               ctl->ossmask = SOUND_MASK_SPEAKER;
+                               ctl->widget->ctlflags |= SOUND_MASK_SPEAKER;
+                       }
+               }
+               break;
        case HDA_CODEC_ALC861:
                ctl = hdac_audio_ctl_amp_get(devinfo, 21, 2, 1);
                if (ctl != NULL)
@@ -6043,7 +6087,7 @@ hdac_attach2(void *arg)
        struct hdac_widget *w;
        struct hdac_audio_ctl *ctl;
        uint32_t quirks_on, quirks_off;
-       int pcnt, rcnt;
+       int pcnt, rcnt, codec_index;
        int i;
        char status[SND_STATUSLEN];
        device_t *devlist = NULL;
@@ -6059,6 +6103,18 @@ hdac_attach2(void *arg)
                    quirks_on, quirks_off);
        );
 
+       if (resource_int_value(device_get_name(sc->dev),
+           device_get_unit(sc->dev), "codec_index", &codec_index) != 0) {
+               switch (sc->pci_subvendor) {
+               case GB_G33S2H_SUBVENDOR:
+                       codec_index = 2;
+                       break;
+               default:
+                       codec_index = 0;
+                       break;
+               }
+       }
+
        hdac_lock(sc);
 
        /* Remove ourselves from the config hooks */
@@ -6090,9 +6146,11 @@ hdac_attach2(void *arg)
        DELAY(1000);
 
        HDA_BOOTVERBOSE(
-               device_printf(sc->dev, "HDA_DEBUG: Scanning HDA codecs...\n");
+               device_printf(sc->dev,
+                   "HDA_DEBUG: Scanning HDA codecs [start index=%d] ...\n",
+                   codec_index);
        );
-       hdac_scan_codecs(sc);
+       hdac_scan_codecs(sc, codec_index);
 
        device_get_children(sc->dev, &devlist, &devcount);
        for (i = 0; devlist != NULL && i < devcount; i++) {