]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'topic/misc' into for-next
authorTakashi Iwai <tiwai@suse.de>
Tue, 27 Jul 2010 08:21:30 +0000 (10:21 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 27 Jul 2010 08:21:30 +0000 (10:21 +0200)
1  2 
sound/pci/hda/hda_codec.c

index 8cd5da84447e1da677ff6093bff0d3b385e55302,3252945f3743a6e7a8f7d633440ff6c7a75c0252..28c01a0ad4a0d796946b4c7633e6c56eac7383c8
@@@ -731,7 -731,7 +731,7 @@@ static void /*__devinit*/ setup_fg_node
        for (i = 0; i < total_nodes; i++, nid++) {
                function_id = snd_hda_param_read(codec, nid,
                                                AC_PAR_FUNCTION_TYPE);
-               switch (function_id) {
+               switch (function_id & 0xff) {
                case AC_GRP_AUDIO_FUNCTION:
                        codec->afg = nid;
                        codec->afg_function_id = function_id & 0xff;
@@@ -786,9 -786,6 +786,9 @@@ static int read_pin_defaults(struct hda
                pin->nid = nid;
                pin->cfg = snd_hda_codec_read(codec, nid, 0,
                                              AC_VERB_GET_CONFIG_DEFAULT, 0);
 +              pin->ctrl = snd_hda_codec_read(codec, nid, 0,
 +                                             AC_VERB_GET_PIN_WIDGET_CONTROL,
 +                                             0);
        }
        return 0;
  }
@@@ -917,38 -914,15 +917,38 @@@ static void restore_pincfgs(struct hda_
  void snd_hda_shutup_pins(struct hda_codec *codec)
  {
        int i;
 +      /* don't shut up pins when unloading the driver; otherwise it breaks
 +       * the default pin setup at the next load of the driver
 +       */
 +      if (codec->bus->shutdown)
 +              return;
        for (i = 0; i < codec->init_pins.used; i++) {
                struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
                /* use read here for syncing after issuing each verb */
                snd_hda_codec_read(codec, pin->nid, 0,
                                   AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
        }
 +      codec->pins_shutup = 1;
  }
  EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
  
 +/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
 +static void restore_shutup_pins(struct hda_codec *codec)
 +{
 +      int i;
 +      if (!codec->pins_shutup)
 +              return;
 +      if (codec->bus->shutdown)
 +              return;
 +      for (i = 0; i < codec->init_pins.used; i++) {
 +              struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
 +              snd_hda_codec_write(codec, pin->nid, 0,
 +                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
 +                                  pin->ctrl);
 +      }
 +      codec->pins_shutup = 0;
 +}
 +
  static void init_hda_cache(struct hda_cache_rec *cache,
                           unsigned int record_size);
  static void free_hda_cache(struct hda_cache_rec *cache);
@@@ -1567,17 -1541,6 +1567,17 @@@ void snd_hda_codec_resume_amp(struct hd
  EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
  #endif /* SND_HDA_NEEDS_RESUME */
  
 +static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
 +                           unsigned int ofs)
 +{
 +      u32 caps = query_amp_caps(codec, nid, dir);
 +      /* get num steps */
 +      caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
 +      if (ofs < caps)
 +              caps -= ofs;
 +      return caps;
 +}
 +
  /**
   * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
   *
@@@ -1592,17 -1555,23 +1592,17 @@@ int snd_hda_mixer_amp_volume_info(struc
        u8 chs = get_amp_channels(kcontrol);
        int dir = get_amp_direction(kcontrol);
        unsigned int ofs = get_amp_offset(kcontrol);
 -      u32 caps;
  
 -      caps = query_amp_caps(codec, nid, dir);
 -      /* num steps */
 -      caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
 -      if (!caps) {
 +      uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 +      uinfo->count = chs == 3 ? 2 : 1;
 +      uinfo->value.integer.min = 0;
 +      uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs);
 +      if (!uinfo->value.integer.max) {
                printk(KERN_WARNING "hda_codec: "
                       "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid,
                       kcontrol->id.name);
                return -EINVAL;
        }
 -      if (ofs < caps)
 -              caps -= ofs;
 -      uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 -      uinfo->count = chs == 3 ? 2 : 1;
 -      uinfo->value.integer.min = 0;
 -      uinfo->value.integer.max = caps;
        return 0;
  }
  EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
@@@ -1627,14 -1596,8 +1627,14 @@@ update_amp_value(struct hda_codec *code
                 int ch, int dir, int idx, unsigned int ofs,
                 unsigned int val)
  {
 +      unsigned int maxval;
 +
        if (val > 0)
                val += ofs;
 +      /* ofs = 0: raw max value */
 +      maxval = get_amp_max_value(codec, nid, dir, 0);
 +      if (val > maxval)
 +              val = maxval;
        return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
                                        HDA_AMP_VOLMASK, val);
  }
@@@ -2946,7 -2909,6 +2946,7 @@@ static void hda_call_codec_resume(struc
                            codec->afg ? codec->afg : codec->mfg,
                            AC_PWRST_D0);
        restore_pincfgs(codec); /* restore all current pin configs */
 +      restore_shutup_pins(codec);
        hda_exec_init_verbs(codec);
        if (codec->patch_ops.resume)
                codec->patch_ops.resume(codec);