Merge branch 'topic/workq-update' into topic/misc
authorTakashi Iwai <tiwai@suse.de>
Mon, 13 Dec 2010 08:29:52 +0000 (09:29 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 13 Dec 2010 08:29:52 +0000 (09:29 +0100)
1  2 
sound/core/pcm_native.c
sound/core/sound.c
sound/pci/hda/patch_realtek.c
sound/pci/oxygen/oxygen_lib.c

diff --combined sound/core/pcm_native.c
index f91a439f675cd5fdf10404ed2bada575888e2797,e82c1f97d99e9736b20523f7bf6eca63498f2587..0db714e87a8078f25b9ca227d076f1eac39145e3
@@@ -22,7 -22,6 +22,6 @@@
  #include <linux/mm.h>
  #include <linux/file.h>
  #include <linux/slab.h>
- #include <linux/smp_lock.h>
  #include <linux/time.h>
  #include <linux/pm_qos_params.h>
  #include <linux/uio.h>
@@@ -423,9 -422,6 +422,9 @@@ static int snd_pcm_hw_params(struct snd
        runtime->info = params->info;
        runtime->rate_num = params->rate_num;
        runtime->rate_den = params->rate_den;
 +      runtime->no_period_wakeup =
 +                      (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
 +                      (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
  
        bits = snd_pcm_format_physical_width(runtime->format);
        runtime->sample_bits = bits;
diff --combined sound/core/sound.c
index 345caea2d7497547eb95cf9d8320f2748a312fc6,66691fe437e63315fad4a1af8c073e9fbba058e5..1c7a3efe17782b3f4a830efdc815f333b2aee3d6
@@@ -21,7 -21,6 +21,6 @@@
  
  #include <linux/init.h>
  #include <linux/slab.h>
- #include <linux/smp_lock.h>
  #include <linux/time.h>
  #include <linux/device.h>
  #include <linux/moduleparam.h>
@@@ -189,22 -188,14 +188,22 @@@ static const struct file_operations snd
  };
  
  #ifdef CONFIG_SND_DYNAMIC_MINORS
 -static int snd_find_free_minor(void)
 +static int snd_find_free_minor(int type)
  {
        int minor;
  
 +      /* static minors for module auto loading */
 +      if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
 +              return SNDRV_MINOR_SEQUENCER;
 +      if (type == SNDRV_DEVICE_TYPE_TIMER)
 +              return SNDRV_MINOR_TIMER;
 +
        for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
 -              /* skip minors still used statically for autoloading devices */
 -              if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL ||
 -                  minor == SNDRV_MINOR_SEQUENCER)
 +              /* skip static minors still used for module auto loading */
 +              if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
 +                      continue;
 +              if (minor == SNDRV_MINOR_SEQUENCER ||
 +                  minor == SNDRV_MINOR_TIMER)
                        continue;
                if (!snd_minors[minor])
                        return minor;
@@@ -278,7 -269,7 +277,7 @@@ int snd_register_device_for_dev(int typ
        preg->private_data = private_data;
        mutex_lock(&sound_mutex);
  #ifdef CONFIG_SND_DYNAMIC_MINORS
 -      minor = snd_find_free_minor();
 +      minor = snd_find_free_minor(type);
  #else
        minor = snd_kernel_minor(type, card, dev);
        if (minor >= 0 && snd_minors[minor])
index b7e234898fd83c896cf0f0070945db95ba9b10ff,8fddc9d08726670c8d67dc1ce9f31dd1f82a56c4..f17159d7dbe972600e2710093376f229a6265271
@@@ -1614,6 -1614,7 +1614,7 @@@ do_sku
                spec->init_amp = ALC_INIT_GPIO3;
                break;
        case 5:
+       default:
                spec->init_amp = ALC_INIT_DEFAULT;
                break;
        }
@@@ -2013,6 -2014,36 +2014,36 @@@ static struct hda_verb alc888_acer_aspi
        { }
  };
  
+ /*
+  *ALC888 Acer Aspire 7730G model
+  */
+ static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
+ /* Bias voltage on for external mic port */
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
+ /* Front Mic: set to PIN_IN (empty by default) */
+       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ /* Unselect Front Mic by default in input mixer 3 */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
+ /* Enable unsolicited event for HP jack */
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ /* Enable speaker output */
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ /* Enable headphone output */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ /*Enable internal subwoofer */
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
+       {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
+       { }
+ };
  /*
   * ALC889 Acer Aspire 8930G model
   */
@@@ -2200,6 -2231,16 +2231,16 @@@ static void alc888_acer_aspire_6530g_se
        spec->autocfg.speaker_pins[2] = 0x17;
  }
  
+ static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
+       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->autocfg.speaker_pins[1] = 0x16;
+       spec->autocfg.speaker_pins[2] = 0x17;
+ }
  static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
@@@ -9524,13 -9565,6 +9565,6 @@@ static struct hda_verb alc883_acer_eapd
        { }
  };
  
- static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-       { } /* end */
- };
  static void alc888_6st_dell_setup(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
@@@ -9831,7 -9865,6 +9865,6 @@@ static struct snd_pci_quirk alc882_cfg_
        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
-       SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
@@@ -10328,7 -10361,7 +10361,7 @@@ static struct alc_config_preset alc882_
                .const_channel_count = 6,
                .input_mux = &alc883_capture_source,
                .unsol_event = alc_automute_amp_unsol_event,
-               .setup = alc888_acer_aspire_6530g_setup,
+               .setup = alc888_acer_aspire_7730g_setup,
                .init_hook = alc_automute_amp,
        },
        [ALC883_MEDION] = {
@@@ -10816,9 -10849,6 +10849,9 @@@ static int alc_auto_add_mic_boost(struc
        return 0;
  }
  
 +static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 +                                           const struct auto_pin_cfg *cfg);
 +
  /* almost identical with ALC880 parser... */
  static int alc882_parse_auto_config(struct hda_codec *codec)
  {
        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
        if (err < 0)
                return err;
 -      err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
 +      if (codec->vendor_id == 0x10ec0887)
 +              err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
 +      else
 +              err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
        if (err < 0)
                return err;
        err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
@@@ -14629,7 -14656,10 +14662,10 @@@ static int alc275_setup_dual_adc(struc
  /* different alc269-variants */
  enum {
        ALC269_TYPE_NORMAL,
+       ALC269_TYPE_ALC258,
        ALC269_TYPE_ALC259,
+       ALC269_TYPE_ALC269VB,
+       ALC269_TYPE_ALC270,
        ALC269_TYPE_ALC271X,
  };
  
@@@ -15029,7 -15059,7 +15065,7 @@@ static int alc269_fill_coef(struct hda_
  static int patch_alc269(struct hda_codec *codec)
  {
        struct alc_spec *spec;
-       int board_config;
+       int board_config, coef;
        int err;
  
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  
        alc_auto_parse_customize_define(codec);
  
-       if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
+       coef = alc_read_coef_idx(codec, 0);
+       if ((coef & 0x00f0) == 0x0010) {
                if (codec->bus->pci->subsystem_vendor == 0x1025 &&
                    spec->cdefine.platform_type == 1) {
                        alc_codec_rename(codec, "ALC271X");
                        spec->codec_variant = ALC269_TYPE_ALC271X;
-               } else {
+               } else if ((coef & 0xf000) == 0x1000) {
+                       spec->codec_variant = ALC269_TYPE_ALC270;
+               } else if ((coef & 0xf000) == 0x2000) {
                        alc_codec_rename(codec, "ALC259");
                        spec->codec_variant = ALC269_TYPE_ALC259;
+               } else if ((coef & 0xf000) == 0x3000) {
+                       alc_codec_rename(codec, "ALC258");
+                       spec->codec_variant = ALC269_TYPE_ALC258;
+               } else {
+                       alc_codec_rename(codec, "ALC269VB");
+                       spec->codec_variant = ALC269_TYPE_ALC269VB;
                }
        } else
                alc_fix_pll_init(codec, 0x20, 0x04, 15);
        spec->stream_digital_capture = &alc269_pcm_digital_capture;
  
        if (!spec->adc_nids) { /* wasn't filled automatically? use default */
-               if (spec->codec_variant != ALC269_TYPE_NORMAL) {
+               if (spec->codec_variant == ALC269_TYPE_NORMAL) {
                        spec->adc_nids = alc269_adc_nids;
                        spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
                        spec->capsrc_nids = alc269_capsrc_nids;
@@@ -16904,7 -16943,7 +16949,7 @@@ static struct alc_config_preset alc861v
  static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
                                                const struct auto_pin_cfg *cfg)
  {
-       return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
+       return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
  }
  
  
@@@ -16969,7 -17008,7 +17014,7 @@@ static void alc861vd_auto_init_analog_i
  #define alc861vd_idx_to_mixer_switch(nid)     ((nid) + 0x0c)
  
  /* add playback controls from the parsed DAC table */
 -/* Based on ALC880 version. But ALC861VD has separate,
 +/* Based on ALC880 version. But ALC861VD and ALC887 have separate,
   * different NIDs for mute/unmute switch and volume control */
  static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
                                             const struct auto_pin_cfg *cfg)
@@@ -18958,6 -18997,8 +19003,8 @@@ static inline hda_nid_t alc662_mix_to_d
                return 0x02;
        else if (nid >= 0x0c && nid <= 0x0e)
                return nid - 0x0c + 0x02;
+       else if (nid == 0x26) /* ALC887-VD has this DAC too */
+               return 0x25;
        else
                return 0;
  }
  static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
                                   hda_nid_t dac)
  {
-       hda_nid_t mix[4];
+       hda_nid_t mix[5];
        int i, num;
  
        num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
@@@ -19426,7 -19467,10 +19473,10 @@@ static int patch_alc888(struct hda_code
  {
        if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
                kfree(codec->chip_name);
-               codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
+               if (codec->vendor_id == 0x10ec0887)
+                       codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
+               else
+                       codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
                if (!codec->chip_name) {
                        alc_free(codec);
                        return -ENOMEM;
@@@ -19916,7 -19960,7 +19966,7 @@@ static struct hda_codec_preset snd_hda_
        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
          .patch = patch_alc882 },
        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
-       { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
+       { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
          .patch = patch_alc882 },
        { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
index 3078ed66ad6197abede08cfc255688944ee81a3f,969605fbcb7f2727c6bee934635f83c875e44857..c44c91e6fb1883106be61d740f48e0a6dcf5e69b
@@@ -202,13 -202,7 +202,13 @@@ static void oxygen_proc_read(struct snd
        struct oxygen *chip = entry->private_data;
        int i, j;
  
 -      snd_iprintf(buffer, "CMI8788\n\n");
 +      switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
 +      case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
 +      case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
 +      case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
 +      default:                     i = '?'; break;
 +      }
 +      snd_iprintf(buffer, "CMI878%c:\n", i);
        for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
                snd_iprintf(buffer, "%02x:", i);
                for (j = 0; j < 0x10; ++j)
        if (mutex_lock_interruptible(&chip->mutex) < 0)
                return;
        if (chip->has_ac97_0) {
 -              snd_iprintf(buffer, "\nAC97\n");
 +              snd_iprintf(buffer, "\nAC97:\n");
                for (i = 0; i < 0x80; i += 0x10) {
                        snd_iprintf(buffer, "%02x:", i);
                        for (j = 0; j < 0x10; j += 2)
                }
        }
        if (chip->has_ac97_1) {
 -              snd_iprintf(buffer, "\nAC97 2\n");
 +              snd_iprintf(buffer, "\nAC97 2:\n");
                for (i = 0; i < 0x80; i += 0x10) {
                        snd_iprintf(buffer, "%02x:", i);
                        for (j = 0; j < 0x10; j += 2)
                }
        }
        mutex_unlock(&chip->mutex);
 +      if (chip->model.dump_registers)
 +              chip->model.dump_registers(chip, buffer);
  }
  
  static void oxygen_proc_init(struct oxygen *chip)
  {
        struct snd_info_entry *entry;
  
 -      if (!snd_card_proc_new(chip->card, "cmi8788", &entry))
 +      if (!snd_card_proc_new(chip->card, "oxygen", &entry))
                snd_info_set_text_ops(entry, chip, oxygen_proc_read);
  }
  #else
@@@ -270,7 -262,7 +270,7 @@@ oxygen_search_pci_id(struct oxygen *chi
         */
        subdevice = oxygen_read_eeprom(chip, 2);
        /* use default ID if EEPROM is missing */
 -      if (subdevice == 0xffff)
 +      if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
                subdevice = 0x8788;
        /*
         * We use only the subsystem device ID for searching because it is
@@@ -565,7 -557,8 +565,8 @@@ static void oxygen_card_free(struct snd
        oxygen_shutdown(chip);
        if (chip->irq >= 0)
                free_irq(chip->irq, chip);
-       flush_scheduled_work();
+       flush_work_sync(&chip->spdif_input_bits_work);
+       flush_work_sync(&chip->gpio_work);
        chip->model.cleanup(chip);
        kfree(chip->model_data);
        mutex_destroy(&chip->mutex);
@@@ -741,7 -734,8 +742,8 @@@ int oxygen_pci_suspend(struct pci_dev *
        spin_unlock_irq(&chip->reg_lock);
  
        synchronize_irq(chip->irq);
-       flush_scheduled_work();
+       flush_work_sync(&chip->spdif_input_bits_work);
+       flush_work_sync(&chip->gpio_work);
        chip->interrupt_mask = saved_interrupt_mask;
  
        pci_disable_device(pci);