]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge tag 'asoc-v3.12-4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorTakashi Iwai <tiwai@suse.de>
Wed, 11 Sep 2013 10:38:45 +0000 (12:38 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 11 Sep 2013 10:38:45 +0000 (12:38 +0200)
ASoC: Fixes for v3.12

A few small fixes, nothing with any broad impact but all useful for the
affected systems.  The Kirkwood compatible string change is fixing up a
string just added in the merge window so that we don't get any changes
in released kernels.

1  2 
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c

index 3a15225d69821523501d0f53cc31ce1ba428311e,24d82d6c34644e649c36332bfb070f9edb8d9186..3d8cd04455a623b888a9efccb7bdd31f92df8188
@@@ -44,8 -44,6 +44,8 @@@ static bool static_hdmi_pcm
  module_param(static_hdmi_pcm, bool, 0644);
  MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
  
 +#define is_haswell(codec)  ((codec)->vendor_id == 0x80862807)
 +
  struct hdmi_spec_per_cvt {
        hda_nid_t cvt_nid;
        int assigned;
@@@ -69,8 -67,6 +69,8 @@@ struct hdmi_spec_per_pin 
        struct delayed_work work;
        struct snd_kcontrol *eld_ctl;
        int repoll_count;
 +      bool setup; /* the stream has been set up by prepare callback */
 +      int channels; /* current number of channels */
        bool non_pcm;
        bool chmap_set;         /* channel-map override by ALSA API? */
        unsigned char chmap[8]; /* ALSA API channel-map */
@@@ -555,17 -551,6 +555,17 @@@ static int hdmi_channel_allocation(stru
                }
        }
  
 +      if (!ca) {
 +              /* if there was no match, select the regular ALSA channel
 +               * allocation with the matching number of channels */
 +              for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
 +                      if (channels == channel_allocations[i].channels) {
 +                              ca = channel_allocations[i].ca_index;
 +                              break;
 +                      }
 +              }
 +      }
 +
        snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf));
        snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
                    ca, channels, buf);
@@@ -883,24 -868,18 +883,24 @@@ static bool hdmi_infoframe_uptodate(str
        return true;
  }
  
 -static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
 -                                     bool non_pcm,
 -                                     struct snd_pcm_substream *substream)
 +static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
 +                                     struct hdmi_spec_per_pin *per_pin,
 +                                     bool non_pcm)
  {
 -      struct hdmi_spec *spec = codec->spec;
 -      struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
        hda_nid_t pin_nid = per_pin->pin_nid;
 -      int channels = substream->runtime->channels;
 +      int channels = per_pin->channels;
        struct hdmi_eld *eld;
        int ca;
        union audio_infoframe ai;
  
 +      if (!channels)
 +              return;
 +
 +      if (is_haswell(codec))
 +              snd_hda_codec_write(codec, pin_nid, 0,
 +                                          AC_VERB_SET_AMP_GAIN_MUTE,
 +                                          AMP_OUT_UNMUTE);
 +
        eld = &per_pin->sink_eld;
        if (!eld->monitor_present)
                return;
@@@ -1040,10 -1019,10 +1040,10 @@@ static void hdmi_unsol_event(struct hda
                hdmi_non_intrinsic_event(codec, res);
  }
  
 -static void haswell_verify_pin_D0(struct hda_codec *codec,
 +static void haswell_verify_D0(struct hda_codec *codec,
                hda_nid_t cvt_nid, hda_nid_t nid)
  {
 -      int pwr, lamp, ramp;
 +      int pwr;
  
        /* For Haswell, the converter 1/2 may keep in D3 state after bootup,
         * thus pins could only choose converter 0 for use. Make sure the
                pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT;
                snd_printd("Haswell HDMI audio: Power for pin 0x%x is now D%d\n", nid, pwr);
        }
 -
 -      lamp = snd_hda_codec_read(codec, nid, 0,
 -                                AC_VERB_GET_AMP_GAIN_MUTE,
 -                                AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT);
 -      ramp = snd_hda_codec_read(codec, nid, 0,
 -                                AC_VERB_GET_AMP_GAIN_MUTE,
 -                                AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT);
 -      if (lamp != ramp) {
 -              snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 -                                  AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT | lamp);
 -
 -              lamp = snd_hda_codec_read(codec, nid, 0,
 -                                AC_VERB_GET_AMP_GAIN_MUTE,
 -                                AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT);
 -              ramp = snd_hda_codec_read(codec, nid, 0,
 -                                AC_VERB_GET_AMP_GAIN_MUTE,
 -                                AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT);
 -              snd_printd("Haswell HDMI audio: Mute after set on pin 0x%x: [0x%x 0x%x]\n", nid, lamp, ramp);
 -      }
  }
  
  /*
@@@ -1075,8 -1073,8 +1075,8 @@@ static int hdmi_setup_stream(struct hda
        int pinctl;
        int new_pinctl = 0;
  
 -      if (codec->vendor_id == 0x80862807)
 -              haswell_verify_pin_D0(codec, cvt_nid, pin_nid);
 +      if (is_haswell(codec))
 +              haswell_verify_D0(codec, cvt_nid, pin_nid);
  
        if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
                pinctl = snd_hda_codec_read(codec, pin_nid, 0,
@@@ -1215,7 -1213,7 +1215,7 @@@ static int hdmi_pcm_open(struct hda_pcm
                            mux_idx);
  
        /* configure unused pins to choose other converters */
 -      if (codec->vendor_id == 0x80862807)
 +      if (is_haswell(codec))
                haswell_config_cvts(codec, pin_idx, mux_idx);
  
        snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
@@@ -1332,7 -1330,6 +1332,7 @@@ static void hdmi_present_sense(struct h
                eld_changed = true;
        }
        if (update_eld) {
 +              bool old_eld_valid = pin_eld->eld_valid;
                pin_eld->eld_valid = eld->eld_valid;
                eld_changed = pin_eld->eld_size != eld->eld_size ||
                              memcmp(pin_eld->eld_buffer, eld->eld_buffer,
                               eld->eld_size);
                pin_eld->eld_size = eld->eld_size;
                pin_eld->info = eld->info;
 +
 +              /* Haswell-specific workaround: re-setup when the transcoder is
 +               * changed during the stream playback
 +               */
 +              if (is_haswell(codec) &&
 +                  eld->eld_valid && !old_eld_valid && per_pin->setup)
 +                      hdmi_setup_audio_infoframe(codec, per_pin,
 +                                                 per_pin->non_pcm);
        }
        mutex_unlock(&pin_eld->lock);
  
@@@ -1389,7 -1378,7 +1389,7 @@@ static int hdmi_add_pin(struct hda_code
        if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
                return 0;
  
 -      if (codec->vendor_id == 0x80862807)
 +      if (is_haswell(codec))
                intel_haswell_fixup_connect_list(codec, pin_nid);
  
        pin_idx = spec->num_pins;
@@@ -1522,17 -1511,14 +1522,17 @@@ static int generic_hdmi_playback_pcm_pr
        hda_nid_t cvt_nid = hinfo->nid;
        struct hdmi_spec *spec = codec->spec;
        int pin_idx = hinfo_to_pin_index(spec, hinfo);
 -      hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid;
 +      struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
 +      hda_nid_t pin_nid = per_pin->pin_nid;
        bool non_pcm;
  
        non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
 +      per_pin->channels = substream->runtime->channels;
 +      per_pin->setup = true;
  
        hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
  
 -      hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
 +      hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
  
        return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
  }
@@@ -1572,9 -1558,6 +1572,9 @@@ static int hdmi_pcm_close(struct hda_pc
                snd_hda_spdif_ctls_unassign(codec, pin_idx);
                per_pin->chmap_set = false;
                memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
 +
 +              per_pin->setup = false;
 +              per_pin->channels = 0;
        }
  
        return 0;
@@@ -1710,7 -1693,8 +1710,7 @@@ static int hdmi_chmap_ctl_put(struct sn
        per_pin->chmap_set = true;
        memcpy(per_pin->chmap, chmap, sizeof(chmap));
        if (prepared)
 -              hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm,
 -                                         substream);
 +              hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
  
        return 0;
  }
@@@ -1798,6 -1782,9 +1798,9 @@@ static int generic_hdmi_build_controls(
                struct snd_pcm_chmap *chmap;
                struct snd_kcontrol *kctl;
                int i;
+               if (!codec->pcm_info[pin_idx].pcm)
+                       break;
                err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm,
                                             SNDRV_PCM_STREAM_PLAYBACK,
                                             NULL, 0, pin_idx, &chmap);
@@@ -1995,7 -1982,7 +1998,7 @@@ static int patch_generic_hdmi(struct hd
        codec->spec = spec;
        hdmi_array_init(spec, 4);
  
 -      if (codec->vendor_id == 0x80862807) {
 +      if (is_haswell(codec)) {
                intel_haswell_enable_all_pins(codec, true);
                intel_haswell_fixup_enable_dp12(codec);
        }
                return -EINVAL;
        }
        codec->patch_ops = generic_hdmi_patch_ops;
 -      if (codec->vendor_id == 0x80862807) {
 +      if (is_haswell(codec)) {
                codec->patch_ops.set_power_state = haswell_set_power_state;
                codec->dp_mst = true;
        }
index d38d6a04eb67c09c0ceb73b1775e91b0e6c8183e,9e9378cde8fa7c05005b8432878b662be74c1263..bc07d369fac43a548db7f1e45273627cc4e7246c
@@@ -3443,56 -3443,6 +3443,56 @@@ static void alc283_fixup_chromebook(str
        }
  }
  
 +/* mute tablet speaker pin (0x14) via dock plugging in addition */
 +static void asus_tx300_automute(struct hda_codec *codec)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      snd_hda_gen_update_outputs(codec);
 +      if (snd_hda_jack_detect(codec, 0x1b))
 +              spec->gen.mute_bits |= (1ULL << 0x14);
 +}
 +
 +static void alc282_fixup_asus_tx300(struct hda_codec *codec,
 +                                  const struct hda_fixup *fix, int action)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      /* TX300 needs to set up GPIO2 for the speaker amp */
 +      static const struct hda_verb gpio2_verbs[] = {
 +              { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
 +              { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
 +              { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
 +              {}
 +      };
 +      static const struct hda_pintbl dock_pins[] = {
 +              { 0x1b, 0x21114000 }, /* dock speaker pin */
 +              {}
 +      };
 +      struct snd_kcontrol *kctl;
 +
 +      switch (action) {
 +      case HDA_FIXUP_ACT_PRE_PROBE:
 +              snd_hda_add_verbs(codec, gpio2_verbs);
 +              snd_hda_apply_pincfgs(codec, dock_pins);
 +              spec->gen.auto_mute_via_amp = 1;
 +              spec->gen.automute_hook = asus_tx300_automute;
 +              snd_hda_jack_detect_enable_callback(codec, 0x1b,
 +                                                  HDA_GEN_HP_EVENT,
 +                                                  snd_hda_gen_hp_automute);
 +              break;
 +      case HDA_FIXUP_ACT_BUILD:
 +              /* this is a bit tricky; give more sane names for the main
 +               * (tablet) speaker and the dock speaker, respectively
 +               */
 +              kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
 +              if (kctl)
 +                      strcpy(kctl->id.name, "Dock Speaker Playback Switch");
 +              kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
 +              if (kctl)
 +                      strcpy(kctl->id.name, "Speaker Playback Switch");
 +              break;
 +      }
 +}
 +
  enum {
        ALC269_FIXUP_SONY_VAIO,
        ALC275_FIXUP_SONY_VAIO_GPIO2,
        ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
        ALC269VB_FIXUP_ORDISSIMO_EVE2,
        ALC283_FIXUP_CHROME_BOOK,
 +      ALC282_FIXUP_ASUS_TX300,
  };
  
  static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc283_fixup_chromebook,
        },
 +      [ALC282_FIXUP_ASUS_TX300] = {
 +              .type = HDA_FIXUP_FUNC,
 +              .v.func = alc282_fixup_asus_tx300,
 +      },
  };
  
  static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
 +      SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
        SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
@@@ -4546,6 -4490,7 +4546,7 @@@ static const struct hda_fixup alc662_fi
  
  static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),