Merge tag 'sound-fix-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2022 17:32:46 +0000 (10:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2022 17:32:46 +0000 (10:32 -0700)
Pull sound fixes from Takashi Iwai:
 "Just a few fixes that have been gathered since the previous pull:

   - An additional fix for potential PCM deadlocks

   - A series of HD-audio CS8409 codec patches for new models

   - Other device specific fixes for HD-audio, ASoC mediatek, Intel,
     fsl, rockchip"

* tag 'sound-fix-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
  ALSA: hda: Avoid unsol event during RPM suspending
  ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
  ALSA: hda/cs8409: Add new Dolphin HW variants
  ALSA: hda/cs8409: Disable HSBIAS_SENSE_EN for Cyborg
  ALSA: hda/cs8409: Support new Warlock MLK Variants
  ALSA: hda/cs8409: Fix Full Scale Volume setting for all variants
  ALSA: hda/cs8409: Re-order quirk table into ascending order
  ALSA: hda/cs8409: Fix Warlock to use mono mic configuration
  ALSA: cs4236: fix an incorrect NULL check on list iterator
  ALSA: hda/realtek: Enable headset mic on Lenovo P360
  ASoC: SOF: Intel: Fix build error without SND_SOC_SOF_PCI_DEV
  ALSA: hda/realtek: Add mute and micmut LED support for Zbook Fury 17 G9
  ASoC: rockchip: i2s_tdm: Fixup config for SND_SOC_DAIFMT_DSP_A/B
  ASoC: fsl-asoc-card: Fix jack_event() always return 0
  ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs

14 files changed:
include/sound/pcm.h
sound/core/pcm.c
sound/core/pcm_lib.c
sound/core/pcm_native.c
sound/isa/cs423x/cs4236.c
sound/pci/hda/patch_cs8409-tables.c
sound/pci/hda/patch_cs8409.c
sound/pci/hda/patch_cs8409.h
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/mt6358.c
sound/soc/fsl/fsl-asoc-card.c
sound/soc/rockchip/rockchip_i2s_tdm.c
sound/soc/sof/intel/Kconfig

index 314f2779cab52e290740e96628264a12f057395e..6b99310b5b8890bd7ceacbae4f347a30c6a0324f 100644 (file)
@@ -402,6 +402,7 @@ struct snd_pcm_runtime {
        struct fasync_struct *fasync;
        bool stop_operating;            /* sync_stop will be called */
        struct mutex buffer_mutex;      /* protect for buffer changes */
+       atomic_t buffer_accessing;      /* >0: in r/w operation, <0: blocked */
 
        /* -- private section -- */
        void *private_data;
index edd9849210f2d8b4a863f7dce327b3728d5e0a81..977d54320a5cabd858f6fce624de9c4f9fd430d0 100644 (file)
@@ -970,6 +970,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
 
        runtime->status->state = SNDRV_PCM_STATE_OPEN;
        mutex_init(&runtime->buffer_mutex);
+       atomic_set(&runtime->buffer_accessing, 0);
 
        substream->runtime = runtime;
        substream->private_data = pcm->private_data;
index a40a35e51fad7c842af674923e52aad9ce127f70..1fc7c50ffa625bc3ec38486b1cf251c96acb39b4 100644 (file)
@@ -1906,11 +1906,9 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
                if (avail >= runtime->twake)
                        break;
                snd_pcm_stream_unlock_irq(substream);
-               mutex_unlock(&runtime->buffer_mutex);
 
                tout = schedule_timeout(wait_time);
 
-               mutex_lock(&runtime->buffer_mutex);
                snd_pcm_stream_lock_irq(substream);
                set_current_state(TASK_INTERRUPTIBLE);
                switch (runtime->status->state) {
@@ -2221,7 +2219,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
 
        nonblock = !!(substream->f_flags & O_NONBLOCK);
 
-       mutex_lock(&runtime->buffer_mutex);
        snd_pcm_stream_lock_irq(substream);
        err = pcm_accessible_state(runtime);
        if (err < 0)
@@ -2276,6 +2273,10 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
                        err = -EINVAL;
                        goto _end_unlock;
                }
+               if (!atomic_inc_unless_negative(&runtime->buffer_accessing)) {
+                       err = -EBUSY;
+                       goto _end_unlock;
+               }
                snd_pcm_stream_unlock_irq(substream);
                if (!is_playback)
                        snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_CPU);
@@ -2284,6 +2285,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
                if (is_playback)
                        snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
                snd_pcm_stream_lock_irq(substream);
+               atomic_dec(&runtime->buffer_accessing);
                if (err < 0)
                        goto _end_unlock;
                err = pcm_accessible_state(runtime);
@@ -2313,7 +2315,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
        if (xfer > 0 && err >= 0)
                snd_pcm_update_state(substream, runtime);
        snd_pcm_stream_unlock_irq(substream);
-       mutex_unlock(&runtime->buffer_mutex);
        return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 EXPORT_SYMBOL(__snd_pcm_lib_xfer);
index 704fdc9ebf911a053397b6a92b5d1be77030ac23..4adaee62ef33329d2f3f4d967be9be7d9b26dbbd 100644 (file)
@@ -685,6 +685,24 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
        return 0;
 }
 
+/* acquire buffer_mutex; if it's in r/w operation, return -EBUSY, otherwise
+ * block the further r/w operations
+ */
+static int snd_pcm_buffer_access_lock(struct snd_pcm_runtime *runtime)
+{
+       if (!atomic_dec_unless_positive(&runtime->buffer_accessing))
+               return -EBUSY;
+       mutex_lock(&runtime->buffer_mutex);
+       return 0; /* keep buffer_mutex, unlocked by below */
+}
+
+/* release buffer_mutex and clear r/w access flag */
+static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
+{
+       mutex_unlock(&runtime->buffer_mutex);
+       atomic_inc(&runtime->buffer_accessing);
+}
+
 #if IS_ENABLED(CONFIG_SND_PCM_OSS)
 #define is_oss_stream(substream)       ((substream)->oss.oss)
 #else
@@ -695,14 +713,16 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params)
 {
        struct snd_pcm_runtime *runtime;
-       int err = 0, usecs;
+       int err, usecs;
        unsigned int bits;
        snd_pcm_uframes_t frames;
 
        if (PCM_RUNTIME_CHECK(substream))
                return -ENXIO;
        runtime = substream->runtime;
-       mutex_lock(&runtime->buffer_mutex);
+       err = snd_pcm_buffer_access_lock(runtime);
+       if (err < 0)
+               return err;
        snd_pcm_stream_lock_irq(substream);
        switch (runtime->status->state) {
        case SNDRV_PCM_STATE_OPEN:
@@ -820,7 +840,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
                        snd_pcm_lib_free_pages(substream);
        }
  unlock:
-       mutex_unlock(&runtime->buffer_mutex);
+       snd_pcm_buffer_access_unlock(runtime);
        return err;
 }
 
@@ -865,7 +885,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
        if (PCM_RUNTIME_CHECK(substream))
                return -ENXIO;
        runtime = substream->runtime;
-       mutex_lock(&runtime->buffer_mutex);
+       result = snd_pcm_buffer_access_lock(runtime);
+       if (result < 0)
+               return result;
        snd_pcm_stream_lock_irq(substream);
        switch (runtime->status->state) {
        case SNDRV_PCM_STATE_SETUP:
@@ -884,7 +906,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
        snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
        cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
  unlock:
-       mutex_unlock(&runtime->buffer_mutex);
+       snd_pcm_buffer_access_unlock(runtime);
        return result;
 }
 
@@ -1369,12 +1391,15 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
 
        /* Guarantee the group members won't change during non-atomic action */
        down_read(&snd_pcm_link_rwsem);
-       mutex_lock(&substream->runtime->buffer_mutex);
+       res = snd_pcm_buffer_access_lock(substream->runtime);
+       if (res < 0)
+               goto unlock;
        if (snd_pcm_stream_linked(substream))
                res = snd_pcm_action_group(ops, substream, state, false);
        else
                res = snd_pcm_action_single(ops, substream, state);
-       mutex_unlock(&substream->runtime->buffer_mutex);
+       snd_pcm_buffer_access_unlock(substream->runtime);
+ unlock:
        up_read(&snd_pcm_link_rwsem);
        return res;
 }
index b6bdebd9ef27577618d94ee59433de9cdb777a08..10112e1bb25dc2373c77ae3ef0d120d328a91030 100644 (file)
@@ -494,7 +494,7 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
        static int dev;
        int err;
        struct snd_card *card;
-       struct pnp_dev *cdev;
+       struct pnp_dev *cdev, *iter;
        char cid[PNP_ID_LEN];
 
        if (pnp_device_is_isapnp(pdev))
@@ -510,9 +510,11 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
        strcpy(cid, pdev->id[0].id);
        cid[5] = '1';
        cdev = NULL;
-       list_for_each_entry(cdev, &(pdev->protocol->devices), protocol_list) {
-               if (!strcmp(cdev->id[0].id, cid))
+       list_for_each_entry(iter, &(pdev->protocol->devices), protocol_list) {
+               if (!strcmp(iter->id[0].id, cid)) {
+                       cdev = iter;
                        break;
+               }
        }
        err = snd_cs423x_card_new(&pdev->dev, dev, &card);
        if (err < 0)
index 2d1fa706327b85291524fe8c13a7e1ed6bd26687..74c50ec040d9f2dfc3874bf918c8061cfef45e66 100644 (file)
@@ -478,28 +478,29 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE),
        SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE),
        SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE),
+       SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG),
+       SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG),
        SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK),
+       SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN),
        SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK),
        SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK),
-       SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK),
-       SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK),
-       SND_PCI_QUIRK(0x1028, 0x0BB5, "Warlock N3 15 TGL-U Nuvoton EC", CS8409_WARLOCK),
-       SND_PCI_QUIRK(0x1028, 0x0BB6, "Warlock V3 15 TGL-U Nuvoton EC", CS8409_WARLOCK),
-       SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG),
        SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG),
        SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG),
        SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG),
@@ -512,11 +513,30 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG),
        SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG),
        SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG),
-       SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN),
-       SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN),
-       SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN),
-       SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN),
-       SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK),
+       SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK),
+       SND_PCI_QUIRK(0x1028, 0x0B92, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0B93, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0B94, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0B95, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0B96, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0B97, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0BB2, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0BB3, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0BB4, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0BB5, "Warlock N3 15 TGL-U Nuvoton EC", CS8409_WARLOCK),
+       SND_PCI_QUIRK(0x1028, 0x0BB6, "Warlock V3 15 TGL-U Nuvoton EC", CS8409_WARLOCK),
+       SND_PCI_QUIRK(0x1028, 0x0BB8, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0BB9, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0BBA, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0BBB, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0BBC, "Warlock MLK", CS8409_WARLOCK_MLK),
+       SND_PCI_QUIRK(0x1028, 0x0BBD, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0BD4, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0BD5, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0BD6, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0BD7, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0BD8, "Dolphin", CS8409_DOLPHIN),
        {} /* terminator */
 };
 
@@ -524,6 +544,8 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
 const struct hda_model_fixup cs8409_models[] = {
        { .id = CS8409_BULLSEYE, .name = "bullseye" },
        { .id = CS8409_WARLOCK, .name = "warlock" },
+       { .id = CS8409_WARLOCK_MLK, .name = "warlock mlk" },
+       { .id = CS8409_WARLOCK_MLK_DUAL_MIC, .name = "warlock mlk dual mic" },
        { .id = CS8409_CYBORG, .name = "cyborg" },
        { .id = CS8409_DOLPHIN, .name = "dolphin" },
        {}
@@ -542,6 +564,18 @@ const struct hda_fixup cs8409_fixups[] = {
                .chained = true,
                .chain_id = CS8409_FIXUPS,
        },
+       [CS8409_WARLOCK_MLK] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = cs8409_cs42l42_pincfgs,
+               .chained = true,
+               .chain_id = CS8409_FIXUPS,
+       },
+       [CS8409_WARLOCK_MLK_DUAL_MIC] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = cs8409_cs42l42_pincfgs,
+               .chained = true,
+               .chain_id = CS8409_FIXUPS,
+       },
        [CS8409_CYBORG] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = cs8409_cs42l42_pincfgs,
index aff2b5abb81ea4f1e030f79157d38f0bcfbe0d94..343fabc4387da8630f87d2aa381c874220aacb9e 100644 (file)
@@ -733,6 +733,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
                { 0x130A, 0x00 },
                { 0x130F, 0x00 },
        };
+       int fsv_old, fsv_new;
 
        /* Bring CS42L42 out of Reset */
        gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
@@ -749,8 +750,13 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
        /* Clear interrupts, by reading interrupt status registers */
        cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs));
 
-       if (cs42l42->full_scale_vol)
-               cs8409_i2c_write(cs42l42, 0x2001, 0x01);
+       fsv_old = cs8409_i2c_read(cs42l42, 0x2001);
+       if (cs42l42->full_scale_vol == CS42L42_FULL_SCALE_VOL_0DB)
+               fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK;
+       else
+               fsv_new = fsv_old & CS42L42_FULL_SCALE_VOL_MASK;
+       if (fsv_new != fsv_old)
+               cs8409_i2c_write(cs42l42, 0x2001, fsv_new);
 
        /* we have to explicitly allow unsol event handling even during the
         * resume phase so that the jack event is processed properly
@@ -906,9 +912,15 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
                        cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff);
        }
 
-       /* DMIC1_MO=00b, DMIC1/2_SR=1 */
-       if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG)
-               cs8409_vendor_coef_set(codec, 0x09, 0x0003);
+       switch (codec->fixup_id) {
+       case CS8409_CYBORG:
+       case CS8409_WARLOCK_MLK_DUAL_MIC:
+               /* DMIC1_MO=00b, DMIC1/2_SR=1 */
+               cs8409_vendor_coef_set(codec, CS8409_DMIC_CFG, 0x0003);
+               break;
+       default:
+               break;
+       }
 
        cs42l42_resume(cs42l42);
 
@@ -993,25 +1005,17 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
                cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID);
                cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID);
 
-               /* Set TIP_SENSE_EN for analog front-end of tip sense.
-                * Additionally set HSBIAS_SENSE_EN and Full Scale volume for some variants.
-                */
+               /* Set HSBIAS_SENSE_EN and Full Scale volume for some variants. */
                switch (codec->fixup_id) {
-               case CS8409_WARLOCK:
+               case CS8409_WARLOCK_MLK:
+               case CS8409_WARLOCK_MLK_DUAL_MIC:
                        spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
-                       spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1;
-                       break;
-               case CS8409_BULLSEYE:
-                       spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
-                       spec->scodecs[CS8409_CODEC0]->full_scale_vol = 0;
-                       break;
-               case CS8409_CYBORG:
-                       spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x00a0;
-                       spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1;
+                       spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB;
                        break;
                default:
-                       spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0003;
-                       spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1;
+                       spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
+                       spec->scodecs[CS8409_CODEC0]->full_scale_vol =
+                               CS42L42_FULL_SCALE_VOL_MINUS6DB;
                        break;
                }
 
@@ -1222,6 +1226,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac
                cs8409_fix_caps(codec, DOLPHIN_LO_PIN_NID);
                cs8409_fix_caps(codec, DOLPHIN_AMIC_PIN_NID);
 
+               spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_MINUS6DB;
+               spec->scodecs[CS8409_CODEC1]->full_scale_vol = CS42L42_FULL_SCALE_VOL_MINUS6DB;
+
                break;
        case HDA_FIXUP_ACT_PROBE:
                /* Fix Sample Rate to 48kHz */
index d0b725c7285b60a4c9de67a1f5c845b26580a54f..7df46bd8d2dae0e8579a5e288c222c074324e038 100644 (file)
@@ -235,6 +235,9 @@ enum cs8409_coefficient_index_registers {
 #define CS42L42_I2C_SLEEP_US                   (2000)
 #define CS42L42_PDN_TIMEOUT_US                 (250000)
 #define CS42L42_PDN_SLEEP_US                   (2000)
+#define CS42L42_FULL_SCALE_VOL_MASK            (2)
+#define CS42L42_FULL_SCALE_VOL_0DB             (1)
+#define CS42L42_FULL_SCALE_VOL_MINUS6DB                (0)
 
 /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */
 
@@ -264,6 +267,8 @@ enum cs8409_coefficient_index_registers {
 enum {
        CS8409_BULLSEYE,
        CS8409_WARLOCK,
+       CS8409_WARLOCK_MLK,
+       CS8409_WARLOCK_MLK_DUAL_MIC,
        CS8409_CYBORG,
        CS8409_FIXUPS,
        CS8409_DOLPHIN,
index c85ed7bc121e6ac8a81b65a216490a11a69a6b58..3e086eebf88d007b508e1aee2746ceebaf2bfd18 100644 (file)
@@ -1625,6 +1625,7 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
        struct hda_codec *codec = per_pin->codec;
        struct hdmi_spec *spec = codec->spec;
        struct hdmi_eld *eld = &spec->temp_eld;
+       struct device *dev = hda_codec_dev(codec);
        hda_nid_t pin_nid = per_pin->pin_nid;
        int dev_id = per_pin->dev_id;
        /*
@@ -1638,8 +1639,13 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
        int present;
        int ret;
 
+#ifdef CONFIG_PM
+       if (dev->power.runtime_status == RPM_SUSPENDING)
+               return;
+#endif
+
        ret = snd_hda_power_up_pm(codec);
-       if (ret < 0 && pm_runtime_suspended(hda_codec_dev(codec)))
+       if (ret < 0 && pm_runtime_suspended(dev))
                goto out;
 
        present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
index c78f16944f431b253cd0a3db776b8ed4b90e36c9..4e12af24b4d35d3a58add1d4def14ac3425ad603 100644 (file)
@@ -3617,8 +3617,8 @@ static void alc256_shutup(struct hda_codec *codec)
        /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
         * when booting with headset plugged. So skip setting it for the codec alc257
         */
-       if (spec->codec_variant != ALC269_TYPE_ALC257 &&
-           spec->codec_variant != ALC269_TYPE_ALC256)
+       if (codec->core.vendor_id != 0x10ec0236 &&
+           codec->core.vendor_id != 0x10ec0257)
                alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
 
        if (!spec->no_shutup_pins)
@@ -7006,6 +7006,7 @@ enum {
        ALC287_FIXUP_LEGION_16ACHG6,
        ALC287_FIXUP_CS35L41_I2C_2,
        ALC245_FIXUP_CS35L41_SPI_2,
+       ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
        ALC245_FIXUP_CS35L41_SPI_4,
        ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
        ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
@@ -8771,6 +8772,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cs35l41_fixup_spi_two,
        },
+       [ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cs35l41_fixup_spi_two,
+               .chained = true,
+               .chain_id = ALC285_FIXUP_HP_GPIO_LED,
+       },
        [ALC245_FIXUP_CS35L41_SPI_4] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cs35l41_fixup_spi_four,
@@ -9026,7 +9033,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
-       SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
        SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
@@ -11140,6 +11147,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
        SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
+       SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
index 9b263a9a669dcb91c2e04414ca8bf03db835fff5..4c7b5d940799b09ab54d12a2bd6b20e59b4a6003 100644 (file)
@@ -107,6 +107,7 @@ int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt,
        priv->mtkaif_protocol = mtkaif_protocol;
        return 0;
 }
+EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_protocol);
 
 static void playback_gpio_set(struct mt6358_priv *priv)
 {
@@ -273,6 +274,7 @@ int mt6358_mtkaif_calibration_enable(struct snd_soc_component *cmpnt)
                           1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);
        return 0;
 }
+EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_enable);
 
 int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt)
 {
@@ -296,6 +298,7 @@ int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt)
        capture_gpio_reset(priv);
        return 0;
 }
+EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_disable);
 
 int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
                                        int phase_1, int phase_2)
@@ -310,6 +313,7 @@ int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
                           phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT);
        return 0;
 }
+EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_calibration_phase);
 
 /* dl pga gain */
 enum {
index 370bc790c6ba7f5b71ee13ba7262f29b7b6a734f..d9a0d4768c4d5627358a987544d405aae7940434 100644 (file)
@@ -462,11 +462,9 @@ static int hp_jack_event(struct notifier_block *nb, unsigned long event,
 
        if (event & SND_JACK_HEADPHONE)
                /* Disable speaker if headphone is plugged in */
-               snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+               return snd_soc_dapm_disable_pin(dapm, "Ext Spk");
        else
-               snd_soc_dapm_enable_pin(dapm, "Ext Spk");
-
-       return 0;
+               return snd_soc_dapm_enable_pin(dapm, "Ext Spk");
 }
 
 static struct notifier_block hp_jack_nb = {
@@ -481,11 +479,9 @@ static int mic_jack_event(struct notifier_block *nb, unsigned long event,
 
        if (event & SND_JACK_MICROPHONE)
                /* Disable dmic if microphone is plugged in */
-               snd_soc_dapm_disable_pin(dapm, "DMIC");
+               return snd_soc_dapm_disable_pin(dapm, "DMIC");
        else
-               snd_soc_dapm_enable_pin(dapm, "DMIC");
-
-       return 0;
+               return snd_soc_dapm_enable_pin(dapm, "DMIC");
 }
 
 static struct notifier_block mic_jack_nb = {
index d3b7104069411c7994c37d7ce3061fd118f0295f..98700e75b82a1fbce1877d884672f2bec5eb1331 100644 (file)
@@ -469,14 +469,14 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
                txcr_val = I2S_TXCR_IBM_NORMAL;
                rxcr_val = I2S_RXCR_IBM_NORMAL;
                break;
-       case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */
-               txcr_val = I2S_TXCR_TFS_PCM;
-               rxcr_val = I2S_RXCR_TFS_PCM;
-               break;
-       case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */
+       case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 mode */
                txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
                rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
                break;
+       case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */
+               txcr_val = I2S_TXCR_TFS_PCM;
+               rxcr_val = I2S_RXCR_TFS_PCM;
+               break;
        default:
                ret = -EINVAL;
                goto err_pm_put;
index b53f216d4ecc32291eb413602466a2f89d52eb3b..172419392b33820efb515b1c9c75205b1ad7e87b 100644 (file)
@@ -84,6 +84,7 @@ if SND_SOC_SOF_PCI
 config SND_SOC_SOF_MERRIFIELD
        tristate "SOF support for Tangier/Merrifield"
        default SND_SOC_SOF_PCI
+       select SND_SOC_SOF_PCI_DEV
        select SND_SOC_SOF_INTEL_ATOM_HIFI_EP
        help
          This adds support for Sound Open Firmware for Intel(R) platforms