Commit d0d642a5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-fix-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

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
parents 26803bac bc55cfd5
...@@ -402,6 +402,7 @@ struct snd_pcm_runtime { ...@@ -402,6 +402,7 @@ struct snd_pcm_runtime {
struct fasync_struct *fasync; struct fasync_struct *fasync;
bool stop_operating; /* sync_stop will be called */ bool stop_operating; /* sync_stop will be called */
struct mutex buffer_mutex; /* protect for buffer changes */ struct mutex buffer_mutex; /* protect for buffer changes */
atomic_t buffer_accessing; /* >0: in r/w operation, <0: blocked */
/* -- private section -- */ /* -- private section -- */
void *private_data; void *private_data;
......
...@@ -970,6 +970,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, ...@@ -970,6 +970,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
runtime->status->state = SNDRV_PCM_STATE_OPEN; runtime->status->state = SNDRV_PCM_STATE_OPEN;
mutex_init(&runtime->buffer_mutex); mutex_init(&runtime->buffer_mutex);
atomic_set(&runtime->buffer_accessing, 0);
substream->runtime = runtime; substream->runtime = runtime;
substream->private_data = pcm->private_data; substream->private_data = pcm->private_data;
......
...@@ -1906,11 +1906,9 @@ static int wait_for_avail(struct snd_pcm_substream *substream, ...@@ -1906,11 +1906,9 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
if (avail >= runtime->twake) if (avail >= runtime->twake)
break; break;
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
mutex_unlock(&runtime->buffer_mutex);
tout = schedule_timeout(wait_time); tout = schedule_timeout(wait_time);
mutex_lock(&runtime->buffer_mutex);
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
switch (runtime->status->state) { switch (runtime->status->state) {
...@@ -2221,7 +2219,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, ...@@ -2221,7 +2219,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
nonblock = !!(substream->f_flags & O_NONBLOCK); nonblock = !!(substream->f_flags & O_NONBLOCK);
mutex_lock(&runtime->buffer_mutex);
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
err = pcm_accessible_state(runtime); err = pcm_accessible_state(runtime);
if (err < 0) if (err < 0)
...@@ -2276,6 +2273,10 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, ...@@ -2276,6 +2273,10 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
err = -EINVAL; err = -EINVAL;
goto _end_unlock; goto _end_unlock;
} }
if (!atomic_inc_unless_negative(&runtime->buffer_accessing)) {
err = -EBUSY;
goto _end_unlock;
}
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
if (!is_playback) if (!is_playback)
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_CPU); 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, ...@@ -2284,6 +2285,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
if (is_playback) if (is_playback)
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE); snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
atomic_dec(&runtime->buffer_accessing);
if (err < 0) if (err < 0)
goto _end_unlock; goto _end_unlock;
err = pcm_accessible_state(runtime); err = pcm_accessible_state(runtime);
...@@ -2313,7 +2315,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, ...@@ -2313,7 +2315,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
if (xfer > 0 && err >= 0) if (xfer > 0 && err >= 0)
snd_pcm_update_state(substream, runtime); snd_pcm_update_state(substream, runtime);
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
mutex_unlock(&runtime->buffer_mutex);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
} }
EXPORT_SYMBOL(__snd_pcm_lib_xfer); EXPORT_SYMBOL(__snd_pcm_lib_xfer);
......
...@@ -685,6 +685,24 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, ...@@ -685,6 +685,24 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
return 0; 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) #if IS_ENABLED(CONFIG_SND_PCM_OSS)
#define is_oss_stream(substream) ((substream)->oss.oss) #define is_oss_stream(substream) ((substream)->oss.oss)
#else #else
...@@ -695,14 +713,16 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -695,14 +713,16 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
int err = 0, usecs; int err, usecs;
unsigned int bits; unsigned int bits;
snd_pcm_uframes_t frames; snd_pcm_uframes_t frames;
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; 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); snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_OPEN: case SNDRV_PCM_STATE_OPEN:
...@@ -820,7 +840,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -820,7 +840,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_lib_free_pages(substream); snd_pcm_lib_free_pages(substream);
} }
unlock: unlock:
mutex_unlock(&runtime->buffer_mutex); snd_pcm_buffer_access_unlock(runtime);
return err; return err;
} }
...@@ -865,7 +885,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) ...@@ -865,7 +885,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; 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); snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_SETUP: case SNDRV_PCM_STATE_SETUP:
...@@ -884,7 +906,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) ...@@ -884,7 +906,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
cpu_latency_qos_remove_request(&substream->latency_pm_qos_req); cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
unlock: unlock:
mutex_unlock(&runtime->buffer_mutex); snd_pcm_buffer_access_unlock(runtime);
return result; return result;
} }
...@@ -1369,12 +1391,15 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops, ...@@ -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 */ /* Guarantee the group members won't change during non-atomic action */
down_read(&snd_pcm_link_rwsem); 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)) if (snd_pcm_stream_linked(substream))
res = snd_pcm_action_group(ops, substream, state, false); res = snd_pcm_action_group(ops, substream, state, false);
else else
res = snd_pcm_action_single(ops, substream, state); 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); up_read(&snd_pcm_link_rwsem);
return res; return res;
} }
......
...@@ -494,7 +494,7 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, ...@@ -494,7 +494,7 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
static int dev; static int dev;
int err; int err;
struct snd_card *card; struct snd_card *card;
struct pnp_dev *cdev; struct pnp_dev *cdev, *iter;
char cid[PNP_ID_LEN]; char cid[PNP_ID_LEN];
if (pnp_device_is_isapnp(pdev)) if (pnp_device_is_isapnp(pdev))
...@@ -510,9 +510,11 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, ...@@ -510,9 +510,11 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
strcpy(cid, pdev->id[0].id); strcpy(cid, pdev->id[0].id);
cid[5] = '1'; cid[5] = '1';
cdev = NULL; cdev = NULL;
list_for_each_entry(cdev, &(pdev->protocol->devices), protocol_list) { list_for_each_entry(iter, &(pdev->protocol->devices), protocol_list) {
if (!strcmp(cdev->id[0].id, cid)) if (!strcmp(iter->id[0].id, cid)) {
cdev = iter;
break; break;
}
} }
err = snd_cs423x_card_new(&pdev->dev, dev, &card); err = snd_cs423x_card_new(&pdev->dev, dev, &card);
if (err < 0) if (err < 0)
......
...@@ -478,28 +478,29 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { ...@@ -478,28 +478,29 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE),
SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE),
SND_PCI_QUIRK(0x1028, 0x0A2B, "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, 0x0AB0, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AB5, "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, 0x0AD9, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0ADC, "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, 0x0ADF, "Cyborg", CS8409_CYBORG),
SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG),
SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG),
...@@ -512,11 +513,30 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { ...@@ -512,11 +513,30 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG),
SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG),
SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG),
SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN), SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN), SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK),
SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN), SND_PCI_QUIRK(0x1028, 0x0B92, "Warlock MLK", CS8409_WARLOCK_MLK),
SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN), SND_PCI_QUIRK(0x1028, 0x0B93, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN), 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 */ {} /* terminator */
}; };
...@@ -524,6 +544,8 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { ...@@ -524,6 +544,8 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
const struct hda_model_fixup cs8409_models[] = { const struct hda_model_fixup cs8409_models[] = {
{ .id = CS8409_BULLSEYE, .name = "bullseye" }, { .id = CS8409_BULLSEYE, .name = "bullseye" },
{ .id = CS8409_WARLOCK, .name = "warlock" }, { .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_CYBORG, .name = "cyborg" },
{ .id = CS8409_DOLPHIN, .name = "dolphin" }, { .id = CS8409_DOLPHIN, .name = "dolphin" },
{} {}
...@@ -542,6 +564,18 @@ const struct hda_fixup cs8409_fixups[] = { ...@@ -542,6 +564,18 @@ const struct hda_fixup cs8409_fixups[] = {
.chained = true, .chained = true,
.chain_id = CS8409_FIXUPS, .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] = { [CS8409_CYBORG] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
.v.pins = cs8409_cs42l42_pincfgs, .v.pins = cs8409_cs42l42_pincfgs,
......
...@@ -733,6 +733,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) ...@@ -733,6 +733,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
{ 0x130A, 0x00 }, { 0x130A, 0x00 },
{ 0x130F, 0x00 }, { 0x130F, 0x00 },
}; };
int fsv_old, fsv_new;
/* Bring CS42L42 out of Reset */ /* Bring CS42L42 out of Reset */
gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); 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) ...@@ -749,8 +750,13 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
/* Clear interrupts, by reading interrupt status registers */ /* Clear interrupts, by reading interrupt status registers */
cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs));
if (cs42l42->full_scale_vol) fsv_old = cs8409_i2c_read(cs42l42, 0x2001);
cs8409_i2c_write(cs42l42, 0x2001, 0x01); 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 /* we have to explicitly allow unsol event handling even during the
* resume phase so that the jack event is processed properly * resume phase so that the jack event is processed properly
...@@ -906,9 +912,15 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) ...@@ -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); cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff);
} }
/* DMIC1_MO=00b, DMIC1/2_SR=1 */ switch (codec->fixup_id) {
if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) case CS8409_CYBORG:
cs8409_vendor_coef_set(codec, 0x09, 0x0003); 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); cs42l42_resume(cs42l42);
...@@ -993,25 +1005,17 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, ...@@ -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_HP_PIN_NID);
cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID); cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID);
/* Set TIP_SENSE_EN for analog front-end of tip sense. /* Set HSBIAS_SENSE_EN and Full Scale volume for some variants. */
* Additionally set HSBIAS_SENSE_EN and Full Scale volume for some variants.
*/
switch (codec->fixup_id) { 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]->hsbias_hiz = 0x0020;
spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB;
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;
break; break;
default: default:
spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0003; spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; spec->scodecs[CS8409_CODEC0]->full_scale_vol =
CS42L42_FULL_SCALE_VOL_MINUS6DB;
break; break;
} }
...@@ -1222,6 +1226,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac ...@@ -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_LO_PIN_NID);
cs8409_fix_caps(codec, DOLPHIN_AMIC_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; break;
case HDA_FIXUP_ACT_PROBE: case HDA_FIXUP_ACT_PROBE:
/* Fix Sample Rate to 48kHz */ /* Fix Sample Rate to 48kHz */
......
...@@ -235,6 +235,9 @@ enum cs8409_coefficient_index_registers { ...@@ -235,6 +235,9 @@ enum cs8409_coefficient_index_registers {
#define CS42L42_I2C_SLEEP_US (2000) #define CS42L42_I2C_SLEEP_US (2000)
#define CS42L42_PDN_TIMEOUT_US (250000) #define CS42L42_PDN_TIMEOUT_US (250000)
#define CS42L42_PDN_SLEEP_US (2000) #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 */ /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */
...@@ -264,6 +267,8 @@ enum cs8409_coefficient_index_registers { ...@@ -264,6 +267,8 @@ enum cs8409_coefficient_index_registers {
enum { enum {
CS8409_BULLSEYE, CS8409_BULLSEYE,
CS8409_WARLOCK, CS8409_WARLOCK,
CS8409_WARLOCK_MLK,
CS8409_WARLOCK_MLK_DUAL_MIC,
CS8409_CYBORG, CS8409_CYBORG,
CS8409_FIXUPS, CS8409_FIXUPS,
CS8409_DOLPHIN, CS8409_DOLPHIN,
......
...@@ -1625,6 +1625,7 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, ...@@ -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 hda_codec *codec = per_pin->codec;
struct hdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
struct hdmi_eld *eld = &spec->temp_eld; struct hdmi_eld *eld = &spec->temp_eld;
struct device *dev = hda_codec_dev(codec);
hda_nid_t pin_nid = per_pin->pin_nid; hda_nid_t pin_nid = per_pin->pin_nid;
int dev_id = per_pin->dev_id; 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, ...@@ -1638,8 +1639,13 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
int present; int present;
int ret; int ret;
#ifdef CONFIG_PM
if (dev->power.runtime_status == RPM_SUSPENDING)
return;
#endif
ret = snd_hda_power_up_pm(codec); 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; goto out;
present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id); present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
......
...@@ -3617,8 +3617,8 @@ static void alc256_shutup(struct hda_codec *codec) ...@@ -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 /* 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 * when booting with headset plugged. So skip setting it for the codec alc257
*/ */
if (spec->codec_variant != ALC269_TYPE_ALC257 && if (codec->core.vendor_id != 0x10ec0236 &&
spec->codec_variant != ALC269_TYPE_ALC256) codec->core.vendor_id != 0x10ec0257)
alc_update_coef_idx(codec, 0x46, 0, 3 << 12); alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
if (!spec->no_shutup_pins) if (!spec->no_shutup_pins)
...@@ -7006,6 +7006,7 @@ enum { ...@@ -7006,6 +7006,7 @@ enum {
ALC287_FIXUP_LEGION_16ACHG6, ALC287_FIXUP_LEGION_16ACHG6,
ALC287_FIXUP_CS35L41_I2C_2, ALC287_FIXUP_CS35L41_I2C_2,
ALC245_FIXUP_CS35L41_SPI_2, ALC245_FIXUP_CS35L41_SPI_2,
ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
ALC245_FIXUP_CS35L41_SPI_4, ALC245_FIXUP_CS35L41_SPI_4,
ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
...@@ -8771,6 +8772,12 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -8771,6 +8772,12 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = cs35l41_fixup_spi_two, .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] = { [ALC245_FIXUP_CS35L41_SPI_4] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = cs35l41_fixup_spi_four, .v.func = cs35l41_fixup_spi_four,
...@@ -9026,7 +9033,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -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, 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, 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, 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(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, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
...@@ -11140,6 +11147,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { ...@@ -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(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), 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, 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, 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, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN), SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
......
...@@ -107,6 +107,7 @@ int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt, ...@@ -107,6 +107,7 @@ int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt,
priv->mtkaif_protocol = mtkaif_protocol; priv->mtkaif_protocol = mtkaif_protocol;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_protocol);
static void playback_gpio_set(struct mt6358_priv *priv) static void playback_gpio_set(struct mt6358_priv *priv)
{ {
...@@ -273,6 +274,7 @@ int mt6358_mtkaif_calibration_enable(struct snd_soc_component *cmpnt) ...@@ -273,6 +274,7 @@ int mt6358_mtkaif_calibration_enable(struct snd_soc_component *cmpnt)
1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT); 1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_enable);
int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt) int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt)
{ {
...@@ -296,6 +298,7 @@ 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); capture_gpio_reset(priv);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_disable);
int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt, int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
int phase_1, int phase_2) int phase_1, int phase_2)
...@@ -310,6 +313,7 @@ int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt, ...@@ -310,6 +313,7 @@ int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT); phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_calibration_phase);
/* dl pga gain */ /* dl pga gain */
enum { enum {
......
...@@ -462,11 +462,9 @@ static int hp_jack_event(struct notifier_block *nb, unsigned long event, ...@@ -462,11 +462,9 @@ static int hp_jack_event(struct notifier_block *nb, unsigned long event,
if (event & SND_JACK_HEADPHONE) if (event & SND_JACK_HEADPHONE)
/* Disable speaker if headphone is plugged in */ /* 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 else
snd_soc_dapm_enable_pin(dapm, "Ext Spk"); return snd_soc_dapm_enable_pin(dapm, "Ext Spk");
return 0;
} }
static struct notifier_block hp_jack_nb = { static struct notifier_block hp_jack_nb = {
...@@ -481,11 +479,9 @@ static int mic_jack_event(struct notifier_block *nb, unsigned long event, ...@@ -481,11 +479,9 @@ static int mic_jack_event(struct notifier_block *nb, unsigned long event,
if (event & SND_JACK_MICROPHONE) if (event & SND_JACK_MICROPHONE)
/* Disable dmic if microphone is plugged in */ /* Disable dmic if microphone is plugged in */
snd_soc_dapm_disable_pin(dapm, "DMIC"); return snd_soc_dapm_disable_pin(dapm, "DMIC");
else else
snd_soc_dapm_enable_pin(dapm, "DMIC"); return snd_soc_dapm_enable_pin(dapm, "DMIC");
return 0;
} }
static struct notifier_block mic_jack_nb = { static struct notifier_block mic_jack_nb = {
......
...@@ -469,14 +469,14 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai, ...@@ -469,14 +469,14 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
txcr_val = I2S_TXCR_IBM_NORMAL; txcr_val = I2S_TXCR_IBM_NORMAL;
rxcr_val = I2S_RXCR_IBM_NORMAL; rxcr_val = I2S_RXCR_IBM_NORMAL;
break; break;
case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */ case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 mode */
txcr_val = I2S_TXCR_TFS_PCM;
rxcr_val = I2S_RXCR_TFS_PCM;
break;
case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */
txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
break; 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: default:
ret = -EINVAL; ret = -EINVAL;
goto err_pm_put; goto err_pm_put;
......
...@@ -84,6 +84,7 @@ if SND_SOC_SOF_PCI ...@@ -84,6 +84,7 @@ if SND_SOC_SOF_PCI
config SND_SOC_SOF_MERRIFIELD config SND_SOC_SOF_MERRIFIELD
tristate "SOF support for Tangier/Merrifield" tristate "SOF support for Tangier/Merrifield"
default SND_SOC_SOF_PCI default SND_SOC_SOF_PCI
select SND_SOC_SOF_PCI_DEV
select SND_SOC_SOF_INTEL_ATOM_HIFI_EP select SND_SOC_SOF_INTEL_ATOM_HIFI_EP
help help
This adds support for Sound Open Firmware for Intel(R) platforms This adds support for Sound Open Firmware for Intel(R) platforms
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment