Merge branch 'asoc-fixes' into for-linus
Takashi Iwai [Thu, 2 Oct 2008 10:50:50 +0000 (12:50 +0200)]
MAINTAINERS
sound/Kconfig
sound/core/pcm.c
sound/core/pcm_native.c
sound/core/rawmidi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/ppc/awacs.c
sound/soc/at32/at32-pcm.c
sound/soc/codecs/cs4270.c

index 28c69aa..657e0ff 100644 (file)
@@ -3826,11 +3826,12 @@ S:      Maintained
 
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
 P:     Liam Girdwood
-M:     liam.girdwood@wolfsonmicro.com
+M:     lrg@slimlogic.co.uk
 P:     Mark Brown
 M:     broonie@opensource.wolfsonmicro.com
 T:     git opensource.wolfsonmicro.com/linux-2.6-asoc
 L:     alsa-devel@alsa-project.org (subscribers-only)
+W:     http://alsa-project.org/main/index.php/ASoC
 S:     Supported
 
 SPI SUBSYSTEM
index a37bee0..8ebf512 100644 (file)
@@ -91,6 +91,9 @@ endif # SOUND_PRIME
 
 endif # !M68K
 
+endif # SOUND
+
+# AC97_BUS is used from both sound and ucb1400
 config AC97_BUS
        tristate
        help
@@ -99,4 +102,3 @@ config AC97_BUS
          sound although they're sharing the AC97 bus. Concerned drivers
          should "select" this.
 
-endif # SOUND
index 9dd9bc7..ece25c7 100644 (file)
@@ -781,7 +781,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
                return -ENODEV;
 
        card = pcm->card;
-       down_read(&card->controls_rwsem);
+       read_lock(&card->ctl_files_rwlock);
        list_for_each_entry(kctl, &card->ctl_files, list) {
                if (kctl->pid == current->pid) {
                        prefer_subdevice = kctl->prefer_pcm_subdevice;
@@ -789,7 +789,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
                                break;
                }
        }
-       up_read(&card->controls_rwsem);
+       read_unlock(&card->ctl_files_rwlock);
 
        switch (stream) {
        case SNDRV_PCM_STREAM_PLAYBACK:
index c49b9d9..c487025 100644 (file)
@@ -1546,16 +1546,10 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        card = substream->pcm->card;
 
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
-           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
+           runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
                return -EBADFD;
 
-       snd_power_lock(card);
-       if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-               result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
-               if (result < 0)
-                       goto _unlock;
-       }
-
        snd_pcm_stream_lock_irq(substream);
        /* resume pause */
        if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
@@ -1564,8 +1558,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
        /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
        snd_pcm_stream_unlock_irq(substream);
- _unlock:
-       snd_power_unlock(card);
+
        return result;
 }
 
index f7ea728..b917a9f 100644 (file)
@@ -418,7 +418,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
        mutex_lock(&rmidi->open_mutex);
        while (1) {
                subdevice = -1;
-               down_read(&card->controls_rwsem);
+               read_lock(&card->ctl_files_rwlock);
                list_for_each_entry(kctl, &card->ctl_files, list) {
                        if (kctl->pid == current->pid) {
                                subdevice = kctl->prefer_rawmidi_subdevice;
@@ -426,7 +426,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
                                        break;
                        }
                }
-               up_read(&card->controls_rwsem);
+               read_unlock(&card->ctl_files_rwlock);
                err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
                                              subdevice, fflags, rawmidi_file);
                if (err >= 0)
index d6ec9ee..6602516 100644 (file)
@@ -14066,6 +14066,13 @@ static struct hda_verb alc662_auto_init_verbs[] = {
        { }
 };
 
+/* additional verbs for ALC663 */
+static struct hda_verb alc663_auto_init_verbs[] = {
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       { }
+};
+
 static struct hda_verb alc663_m51va_init_verbs[] = {
        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -14594,6 +14601,14 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
        if (!pin)
                return 0;
 
+       if (pin == 0x17) {
+               /* ALC663 has a mono output pin on 0x17 */
+               sprintf(name, "%s Playback Switch", pfx);
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
+               return err;
+       }
+
        if (alc880_is_fixed_pin(pin)) {
                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
                 /* printk("DAC nid=%x\n",nid); */
@@ -14764,6 +14779,14 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux;
        
        spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
+       if (codec->vendor_id == 0x10ec0663)
+               spec->init_verbs[spec->num_init_verbs++] =
+                       alc663_auto_init_verbs;
+
+       err = alc_auto_add_mic_boost(codec);
+       if (err < 0)
+               return err;
+
        spec->mixers[spec->num_mixers] = alc662_capture_mixer;
        spec->num_mixers++;
        return 1;
index ad994fc..f3da621 100644 (file)
@@ -1683,8 +1683,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
        /* Dell 3 stack systems with verb table in BIOS */
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0227, "Dell Vostro 1400  ", STAC_DELL_BIOS),
-       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x022f, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x022e, "Dell     ", STAC_DELL_BIOS),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0242, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x0243, "Dell     ", STAC_DELL_BIOS),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL,  0x02ff, "Dell     ", STAC_DELL_BIOS),
index 566a6d0..106c482 100644 (file)
@@ -621,6 +621,13 @@ static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __initdata = {
        AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 };
 
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __initdata = {
+       AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
+       AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
+       AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
+       AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
+};
+
 static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = {
        AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
        AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
@@ -688,7 +695,10 @@ static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = {
 static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata =
 AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata =
+AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
+
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata =
 AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
 
 
@@ -765,11 +775,12 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip)
 
 #define IS_PM7500 (machine_is_compatible("AAPL,7500"))
 #define IS_BEIGE (machine_is_compatible("AAPL,Gossamer"))
-#define IS_IMAC (machine_is_compatible("PowerMac2,1") \
-               || machine_is_compatible("PowerMac2,2") \
+#define IS_IMAC1 (machine_is_compatible("PowerMac2,1"))
+#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \
                || machine_is_compatible("PowerMac4,1"))
+#define IS_G4AGP (machine_is_compatible("PowerMac3,1"))
 
-static int imac;
+static int imac1, imac2;
 
 #ifdef PMAC_SUPPORT_AUTOMUTE
 /*
@@ -815,13 +826,18 @@ static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
                {
                        int reg = chip->awacs_reg[1]
                                | (MASK_HDMUTE | MASK_SPKMUTE);
-                       if (imac) {
+                       if (imac1) {
+                               reg &= ~MASK_SPKMUTE;
+                               reg |= MASK_PAROUT1;
+                       } else if (imac2) {
                                reg &= ~MASK_SPKMUTE;
                                reg &= ~MASK_PAROUT1;
                        }
                        if (snd_pmac_awacs_detect_headphone(chip))
                                reg &= ~MASK_HDMUTE;
-                       else if (imac)
+                       else if (imac1)
+                               reg &= ~MASK_PAROUT1;
+                       else if (imac2)
                                reg |= MASK_PAROUT1;
                        else
                                reg &= ~MASK_SPKMUTE;
@@ -850,9 +866,13 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
 {
        int pm7500 = IS_PM7500;
        int beige = IS_BEIGE;
+       int g4agp = IS_G4AGP;
+       int imac;
        int err, vol;
 
-       imac = IS_IMAC;
+       imac1 = IS_IMAC1;
+       imac2 = IS_IMAC2;
+       imac = imac1 || imac2;
        /* looks like MASK_GAINLINE triggers something, so we set here
         * as start-up
         */
@@ -939,7 +959,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                                snd_pmac_awacs_mixers);
        if (err < 0)
                return err;
-       if (beige)
+       if (beige || g4agp)
                ;
        else if (chip->model == PMAC_SCREAMER)
                err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
@@ -961,13 +981,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                err = build_mixers(chip,
                                   ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
                                   snd_pmac_screamer_mixers_imac);
+       else if (g4agp)
+               err = build_mixers(chip,
+                                  ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
+                                  snd_pmac_screamer_mixers_g4agp);
        else
                err = build_mixers(chip,
                                   ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
                                   snd_pmac_awacs_mixers_pmac);
        if (err < 0)
                return err;
-       chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac)
+       chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp)
                        ? &snd_pmac_awacs_master_sw_imac
                        : &snd_pmac_awacs_master_sw, chip);
        err = snd_ctl_add(chip->card, chip->master_sw_ctl);
@@ -1004,15 +1028,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                                        snd_pmac_awacs_speaker_vol);
                if (err < 0)
                        return err;
-               chip->speaker_sw_ctl = snd_ctl_new1(imac
-                               ? &snd_pmac_awacs_speaker_sw_imac
+               chip->speaker_sw_ctl = snd_ctl_new1(imac1
+                               ? &snd_pmac_awacs_speaker_sw_imac1
+                               : imac2
+                               ? &snd_pmac_awacs_speaker_sw_imac2
                                : &snd_pmac_awacs_speaker_sw, chip);
                err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
                if (err < 0)
                        return err;
        }
 
-       if (beige)
+       if (beige || g4agp)
                err = build_mixers(chip,
                                ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
                                snd_pmac_screamer_mic_boost_beige);
index 435f1da..c83584f 100644 (file)
@@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev,
        params = prtd->params;
 
        /* Disable the PDC and save the PDC registers */
-       ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                  params->mask->pdc_disable);
 
        prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
        prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
@@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev,
        ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
        ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
 
-       ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
        return 0;
 }
 #else /* CONFIG_PM */
index 9deb8c7..0bbd945 100644 (file)
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
 
 #endif
 
-static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind);
-
-/*
- * Notify the driver that a new I2C bus has been found.
- *
- * This function is called for each I2C bus in the system.  The function
- * then asks the I2C subsystem to probe that bus at the addresses on which
- * our device (the CS4270) could exist.  If a device is found at one of
- * those addresses, then our probe function (cs4270_i2c_probe) is called.
- */
-static int cs4270_i2c_attach(struct i2c_adapter *adapter)
-{
-       return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
-}
-
-static int cs4270_i2c_detach(struct i2c_client *client)
-{
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-
-       i2c_detach_client(client);
-       codec->control_data = NULL;
-
-       kfree(codec->reg_cache);
-       codec->reg_cache = NULL;
-
-       kfree(client);
-       return 0;
-}
+static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
 
 /* A list of non-DAPM controls that the CS4270 supports */
 static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
                CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
 };
 
+static const struct i2c_device_id cs4270_id[] = {
+       {"cs4270", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, cs4270_id);
+
 static struct i2c_driver cs4270_i2c_driver = {
        .driver = {
                .name = "CS4270 I2C",
                .owner = THIS_MODULE,
        },
-       .id =             I2C_DRIVERID_CS4270,
-       .attach_adapter = cs4270_i2c_attach,
-       .detach_client =  cs4270_i2c_detach,
+       .id_table = cs4270_id,
+       .probe = cs4270_i2c_probe,
 };
 
 /*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
  * Note: snd_soc_new_pcms() must be called before this function can be called,
  * because of snd_ctl_add().
  */
-static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int cs4270_i2c_probe(struct i2c_client *i2c_client,
+       const struct i2c_device_id *id)
 {
        struct snd_soc_device *socdev = cs4270_socdev;
        struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c_client = NULL;
        int i;
        int ret = 0;
 
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
 
        /* Note: codec_dai->codec is NULL here */
 
-       i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!i2c_client) {
-               printk(KERN_ERR "cs4270: could not allocate I2C client\n");
-               return -ENOMEM;
-       }
-
        codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
        if (!codec->reg_cache) {
                printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       i2c_set_clientdata(i2c_client, codec);
-       strcpy(i2c_client->name, "CS4270");
-
-       i2c_client->driver = &cs4270_i2c_driver;
-       i2c_client->adapter = adapter;
-       i2c_client->addr = addr;
-
        /* Verify that we have a CS4270 */
 
        ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr);
+       printk(KERN_INFO "cs4270: found device at I2C address %X\n",
+               i2c_client->addr);
        printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
 
-       /* Tell the I2C layer a new client has arrived */
-
-       ret = i2c_attach_client(i2c_client);
-       if (ret) {
-               printk(KERN_ERR "cs4270: could not attach codec, "
-                       "I2C address %x, error code %i\n", addr, ret);
-               goto error;
-       }
-
        codec->control_data = i2c_client;
        codec->read = cs4270_read_reg_cache;
        codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                        goto error;
        }
 
+       i2c_set_clientdata(i2c_client, codec);
+
        return 0;
 
 error:
-       if (codec->control_data) {
-               i2c_detach_client(i2c_client);
-               codec->control_data = NULL;
-       }
+       codec->control_data = NULL;
 
        kfree(codec->reg_cache);
        codec->reg_cache = NULL;
        codec->reg_cache_size = 0;
 
-       kfree(i2c_client);
-
        return ret;
 }
 
@@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to create PCMs\n");
-               return ret;
+               goto error_free_codec;
        }
 
 #ifdef USE_I2C
@@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = i2c_add_driver(&cs4270_i2c_driver);
        if (ret) {
                printk(KERN_ERR "cs4270: failed to attach driver");
-               snd_soc_free_pcms(socdev);
-               return ret;
+               goto error_free_pcms;
        }
 
        /* Did we find a CS4270 on the I2C bus? */
@@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = snd_soc_register_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to register card\n");
-               snd_soc_free_pcms(socdev);
-               return ret;
+               goto error_del_driver;
        }
 
+       return 0;
+
+error_del_driver:
+#ifdef USE_I2C
+       i2c_del_driver(&cs4270_i2c_driver);
+
+error_free_pcms:
+#endif
+       snd_soc_free_pcms(socdev);
+
+error_free_codec:
+       kfree(socdev->codec);
+       socdev->codec = NULL;
+
        return ret;
 }
 
@@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
        snd_soc_free_pcms(socdev);
 
 #ifdef USE_I2C
-       if (socdev->codec->control_data)
-               i2c_del_driver(&cs4270_i2c_driver);
+       i2c_del_driver(&cs4270_i2c_driver);
 #endif
 
        kfree(socdev->codec);