[ALSA] hda-intel - correct a bug in detection of rate supported
[deliverable/linux.git] / sound / pci / hda / hda_codec.c
index d3ac7530ec898d98f8c9d669666abee7b29031d4..e067a14a2d9e5f914b415e0de9ccb37e39aadf44 100644 (file)
@@ -432,22 +432,26 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
 }
 
 /*
- * look for an AFG node
- *
- * return 0 if not found
+ * look for an AFG and MFG nodes
  */
-static int look_for_afg_node(struct hda_codec *codec)
+static void setup_fg_nodes(struct hda_codec *codec)
 {
        int i, total_nodes;
        hda_nid_t nid;
 
        total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
        for (i = 0; i < total_nodes; i++, nid++) {
-               if ((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff) ==
-                   AC_GRP_AUDIO_FUNCTION)
-                       return nid;
+               switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {
+               case AC_GRP_AUDIO_FUNCTION:
+                       codec->afg = nid;
+                       break;
+               case AC_GRP_MODEM_FUNCTION:
+                       codec->mfg = nid;
+                       break;
+               default:
+                       break;
+               }
        }
-       return 0;
 }
 
 /*
@@ -507,10 +511,9 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
        codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
        codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
 
-       /* FIXME: support for multiple AFGs? */
-       codec->afg = look_for_afg_node(codec);
-       if (! codec->afg) {
-               snd_printdd("hda_codec: no AFG node found\n");
+       setup_fg_nodes(codec);
+       if (! codec->afg && ! codec->mfg) {
+               snd_printdd("hda_codec: no AFG or MFG node found\n");
                snd_hda_codec_free(codec);
                return -ENODEV;
        }
@@ -749,12 +752,14 @@ int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
        long *valp = ucontrol->value.integer.value;
        int change = 0;
 
-       if (chs & 1)
+       if (chs & 1) {
                change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
                                                  0x7f, *valp);
+               valp++;
+       }
        if (chs & 2)
                change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
-                                                  0x7f, valp[1]);
+                                                  0x7f, *valp);
        return change;
 }
 
@@ -796,12 +801,15 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
        long *valp = ucontrol->value.integer.value;
        int change = 0;
 
-       if (chs & 1)
+       if (chs & 1) {
                change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
                                                  0x80, *valp ? 0 : 0x80);
+               valp++;
+       }
        if (chs & 2)
                change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
-                                                  0x80, valp[1] ? 0 : 0x80);
+                                                  0x80, *valp ? 0 : 0x80);
+       
        return change;
 }
 
@@ -1157,6 +1165,8 @@ int snd_hda_build_controls(struct hda_bus *bus)
  */
 static unsigned int rate_bits[][3] = {
        /* rate in Hz, ALSA rate bitmask, HDA format value */
+
+       /* autodetected value used in snd_hda_query_supported_pcm */
        { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
        { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
        { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
@@ -1168,6 +1178,9 @@ static unsigned int rate_bits[][3] = {
        { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
        { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
        { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
+
+       /* not autodetected value */
+       { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
        { 0 }
 };
 
This page took 0.02677 seconds and 5 git commands to generate.