diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-10 01:15:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-10 01:15:08 -0400 |
commit | 39e4edfdf5016bb28438093d030a0ef90ce2d30a (patch) | |
tree | 84865f9975eac250efdf76c5f9079b553b4a1ce6 | |
parent | 6107cc58f33c0581d4bbd847ed9145b76e61d57c (diff) | |
parent | ba3021b2c79b2fa9114f92790a99deb27a65b728 (diff) |
Merge tag 'sound-4.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"This update contains a slightly hight amount of changes due to the
pending ASoC fixes:
- ALSA timer core got a couple of fixes for races between read and
ioctl, leading to potential read of uninitialized kmalloced memory
- ASoC core fixed the de-registration pattern for use-after-free bug
- The rewrite of probe code in ASoC Intel Skylake for i915 component
- ASoC R-snd got a series of fixes for SSI
- ASoC simple-card, atmel, da7213, and rt286 trivial fixes
- HD-audio ALC269 quirk and rearrangement of quirk table"
* tag 'sound-4.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: timer: Fix missing queue indices reset at SNDRV_TIMER_IOCTL_SELECT
ALSA: timer: Fix race between read and ioctl
ALSA: hda/realtek - Reorder ALC269 ASUS quirk entries
ALSA: hda/realtek: Fix mic and headset jack sense on Asus X705UD
ASoC: rsnd: fixup parent_clk_name of AUDIO_CLKOUTx
ASoC: Intel: Skylake: Fix to parse consecutive string tkns in manifest
ASoC: Intel: Skylake: Fix IPC rx_list corruption
ASoC: rsnd: SSI PIO adjust to 24bit mode
MAINTAINERS: Update email address for patches to Wolfson parts
ASoC: Fix use-after-free at card unregistration
ASoC: simple-card: fix mic jack initialization
ASoC: rsnd: don't call free_irq() on Parent SSI
ASoC: atmel-classd: sync regcache when resuming
ASoC: rsnd: don't use PDTA bit for 24bit on SSI
ASoC: da7213: Fix incorrect usage of bitwise '&' operator for SRM check
rt286: add Thinkpad Helix 2 to force_combo_jack_table
ASoC: Intel: Skylake: Move i915 registration to worker thread
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | sound/core/timer.c | 7 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 11 | ||||
-rw-r--r-- | sound/soc/atmel/atmel-classd.c | 9 | ||||
-rw-r--r-- | sound/soc/codecs/da7213.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/rt286.c | 7 | ||||
-rw-r--r-- | sound/soc/generic/simple-card.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst-ipc.c | 5 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl.c | 162 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl.h | 4 | ||||
-rw-r--r-- | sound/soc/sh/rcar/adg.c | 6 | ||||
-rw-r--r-- | sound/soc/sh/rcar/cmd.c | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 51 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 1 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 12 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 18 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssiu.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 5 |
20 files changed, 216 insertions, 96 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 67646b70b390..4d8e525b84ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -13861,7 +13861,7 @@ S: Odd fixes | |||
13861 | F: drivers/net/wireless/wl3501* | 13861 | F: drivers/net/wireless/wl3501* |
13862 | 13862 | ||
13863 | WOLFSON MICROELECTRONICS DRIVERS | 13863 | WOLFSON MICROELECTRONICS DRIVERS |
13864 | L: patches@opensource.wolfsonmicro.com | 13864 | L: patches@opensource.cirrus.com |
13865 | T: git https://github.com/CirrusLogic/linux-drivers.git | 13865 | T: git https://github.com/CirrusLogic/linux-drivers.git |
13866 | W: https://github.com/CirrusLogic/linux-drivers/wiki | 13866 | W: https://github.com/CirrusLogic/linux-drivers/wiki |
13867 | S: Supported | 13867 | S: Supported |
diff --git a/sound/core/timer.c b/sound/core/timer.c index 2f836ca09860..cd67d1c12cf1 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1618,6 +1618,7 @@ static int snd_timer_user_tselect(struct file *file, | |||
1618 | if (err < 0) | 1618 | if (err < 0) |
1619 | goto __err; | 1619 | goto __err; |
1620 | 1620 | ||
1621 | tu->qhead = tu->qtail = tu->qused = 0; | ||
1621 | kfree(tu->queue); | 1622 | kfree(tu->queue); |
1622 | tu->queue = NULL; | 1623 | tu->queue = NULL; |
1623 | kfree(tu->tqueue); | 1624 | kfree(tu->tqueue); |
@@ -1959,6 +1960,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, | |||
1959 | 1960 | ||
1960 | tu = file->private_data; | 1961 | tu = file->private_data; |
1961 | unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read); | 1962 | unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read); |
1963 | mutex_lock(&tu->ioctl_lock); | ||
1962 | spin_lock_irq(&tu->qlock); | 1964 | spin_lock_irq(&tu->qlock); |
1963 | while ((long)count - result >= unit) { | 1965 | while ((long)count - result >= unit) { |
1964 | while (!tu->qused) { | 1966 | while (!tu->qused) { |
@@ -1974,7 +1976,9 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, | |||
1974 | add_wait_queue(&tu->qchange_sleep, &wait); | 1976 | add_wait_queue(&tu->qchange_sleep, &wait); |
1975 | 1977 | ||
1976 | spin_unlock_irq(&tu->qlock); | 1978 | spin_unlock_irq(&tu->qlock); |
1979 | mutex_unlock(&tu->ioctl_lock); | ||
1977 | schedule(); | 1980 | schedule(); |
1981 | mutex_lock(&tu->ioctl_lock); | ||
1978 | spin_lock_irq(&tu->qlock); | 1982 | spin_lock_irq(&tu->qlock); |
1979 | 1983 | ||
1980 | remove_wait_queue(&tu->qchange_sleep, &wait); | 1984 | remove_wait_queue(&tu->qchange_sleep, &wait); |
@@ -1994,7 +1998,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, | |||
1994 | tu->qused--; | 1998 | tu->qused--; |
1995 | spin_unlock_irq(&tu->qlock); | 1999 | spin_unlock_irq(&tu->qlock); |
1996 | 2000 | ||
1997 | mutex_lock(&tu->ioctl_lock); | ||
1998 | if (tu->tread) { | 2001 | if (tu->tread) { |
1999 | if (copy_to_user(buffer, &tu->tqueue[qhead], | 2002 | if (copy_to_user(buffer, &tu->tqueue[qhead], |
2000 | sizeof(struct snd_timer_tread))) | 2003 | sizeof(struct snd_timer_tread))) |
@@ -2004,7 +2007,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, | |||
2004 | sizeof(struct snd_timer_read))) | 2007 | sizeof(struct snd_timer_read))) |
2005 | err = -EFAULT; | 2008 | err = -EFAULT; |
2006 | } | 2009 | } |
2007 | mutex_unlock(&tu->ioctl_lock); | ||
2008 | 2010 | ||
2009 | spin_lock_irq(&tu->qlock); | 2011 | spin_lock_irq(&tu->qlock); |
2010 | if (err < 0) | 2012 | if (err < 0) |
@@ -2014,6 +2016,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, | |||
2014 | } | 2016 | } |
2015 | _error: | 2017 | _error: |
2016 | spin_unlock_irq(&tu->qlock); | 2018 | spin_unlock_irq(&tu->qlock); |
2019 | mutex_unlock(&tu->ioctl_lock); | ||
2017 | return result > 0 ? result : err; | 2020 | return result > 0 ? result : err; |
2018 | } | 2021 | } |
2019 | 2022 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a57988d617e9..cbeebc0a9711 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -5854,7 +5854,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5854 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 5854 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
5855 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 5855 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
5856 | SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), | 5856 | SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), |
5857 | SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), | ||
5857 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 5858 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
5859 | SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), | ||
5860 | SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), | ||
5861 | SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), | ||
5858 | SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), | 5862 | SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), |
5859 | SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), | 5863 | SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), |
5860 | SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), | 5864 | SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), |
@@ -5862,13 +5866,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5862 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), | 5866 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
5863 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 5867 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
5864 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 5868 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
5869 | SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), | ||
5865 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | 5870 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
5866 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | ||
5867 | SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), | 5871 | SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), |
5868 | SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), | 5872 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
5869 | SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), | ||
5870 | SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), | ||
5871 | SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), | ||
5872 | SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), | 5873 | SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), |
5873 | SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), | 5874 | SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), |
5874 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 5875 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index 7ae46c2647d4..b7ef8c59b49a 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c | |||
@@ -301,6 +301,14 @@ static int atmel_classd_codec_probe(struct snd_soc_codec *codec) | |||
301 | return 0; | 301 | return 0; |
302 | } | 302 | } |
303 | 303 | ||
304 | static int atmel_classd_codec_resume(struct snd_soc_codec *codec) | ||
305 | { | ||
306 | struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec); | ||
307 | struct atmel_classd *dd = snd_soc_card_get_drvdata(card); | ||
308 | |||
309 | return regcache_sync(dd->regmap); | ||
310 | } | ||
311 | |||
304 | static struct regmap *atmel_classd_codec_get_remap(struct device *dev) | 312 | static struct regmap *atmel_classd_codec_get_remap(struct device *dev) |
305 | { | 313 | { |
306 | return dev_get_regmap(dev, NULL); | 314 | return dev_get_regmap(dev, NULL); |
@@ -308,6 +316,7 @@ static struct regmap *atmel_classd_codec_get_remap(struct device *dev) | |||
308 | 316 | ||
309 | static struct snd_soc_codec_driver soc_codec_dev_classd = { | 317 | static struct snd_soc_codec_driver soc_codec_dev_classd = { |
310 | .probe = atmel_classd_codec_probe, | 318 | .probe = atmel_classd_codec_probe, |
319 | .resume = atmel_classd_codec_resume, | ||
311 | .get_regmap = atmel_classd_codec_get_remap, | 320 | .get_regmap = atmel_classd_codec_get_remap, |
312 | .component_driver = { | 321 | .component_driver = { |
313 | .controls = atmel_classd_snd_controls, | 322 | .controls = atmel_classd_snd_controls, |
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 6dd7578f0bb8..024d83fa6a7f 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c | |||
@@ -772,7 +772,7 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, | |||
772 | ++i; | 772 | ++i; |
773 | msleep(50); | 773 | msleep(50); |
774 | } | 774 | } |
775 | } while ((i < DA7213_SRM_CHECK_RETRIES) & (!srm_lock)); | 775 | } while ((i < DA7213_SRM_CHECK_RETRIES) && (!srm_lock)); |
776 | 776 | ||
777 | if (!srm_lock) | 777 | if (!srm_lock) |
778 | dev_warn(codec->dev, "SRM failed to lock\n"); | 778 | dev_warn(codec->dev, "SRM failed to lock\n"); |
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 9c365a7f758d..7899a2cdeb42 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -1108,6 +1108,13 @@ static const struct dmi_system_id force_combo_jack_table[] = { | |||
1108 | DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform") | 1108 | DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform") |
1109 | } | 1109 | } |
1110 | }, | 1110 | }, |
1111 | { | ||
1112 | .ident = "Thinkpad Helix 2nd", | ||
1113 | .matches = { | ||
1114 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1115 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix 2nd") | ||
1116 | } | ||
1117 | }, | ||
1111 | 1118 | ||
1112 | { } | 1119 | { } |
1113 | }; | 1120 | }; |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 2c9dedab5184..bc136d2bd7cd 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -202,7 +202,7 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
202 | if (ret < 0) | 202 | if (ret < 0) |
203 | return ret; | 203 | return ret; |
204 | 204 | ||
205 | ret = asoc_simple_card_init_mic(rtd->card, &priv->hp_jack, PREFIX); | 205 | ret = asoc_simple_card_init_mic(rtd->card, &priv->mic_jack, PREFIX); |
206 | if (ret < 0) | 206 | if (ret < 0) |
207 | return ret; | 207 | return ret; |
208 | 208 | ||
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index 58c525096a7c..498b15345b1a 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c | |||
@@ -413,8 +413,11 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | |||
413 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; | 413 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; |
414 | u64 *ipc_header = (u64 *)(&header); | 414 | u64 *ipc_header = (u64 *)(&header); |
415 | struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); | 415 | struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); |
416 | unsigned long flags; | ||
416 | 417 | ||
418 | spin_lock_irqsave(&ipc->dsp->spinlock, flags); | ||
417 | msg = skl_ipc_reply_get_msg(ipc, *ipc_header); | 419 | msg = skl_ipc_reply_get_msg(ipc, *ipc_header); |
420 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); | ||
418 | if (msg == NULL) { | 421 | if (msg == NULL) { |
419 | dev_dbg(ipc->dev, "ipc: rx list is empty\n"); | 422 | dev_dbg(ipc->dev, "ipc: rx list is empty\n"); |
420 | return; | 423 | return; |
@@ -456,8 +459,10 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | |||
456 | } | 459 | } |
457 | } | 460 | } |
458 | 461 | ||
462 | spin_lock_irqsave(&ipc->dsp->spinlock, flags); | ||
459 | list_del(&msg->list); | 463 | list_del(&msg->list); |
460 | sst_ipc_tx_msg_reply_complete(ipc, msg); | 464 | sst_ipc_tx_msg_reply_complete(ipc, msg); |
465 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); | ||
461 | } | 466 | } |
462 | 467 | ||
463 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) | 468 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 3a99712e44a8..64a0f8ed33e1 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -2502,7 +2502,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, | |||
2502 | 2502 | ||
2503 | if (ret < 0) | 2503 | if (ret < 0) |
2504 | return ret; | 2504 | return ret; |
2505 | tkn_count += ret; | 2505 | tkn_count = ret; |
2506 | 2506 | ||
2507 | tuple_size += tkn_count * | 2507 | tuple_size += tkn_count * |
2508 | sizeof(struct snd_soc_tplg_vendor_string_elem); | 2508 | sizeof(struct snd_soc_tplg_vendor_string_elem); |
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 6df3b317a476..4c9b5781282b 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c | |||
@@ -410,7 +410,7 @@ static int skl_free(struct hdac_ext_bus *ebus) | |||
410 | struct skl *skl = ebus_to_skl(ebus); | 410 | struct skl *skl = ebus_to_skl(ebus); |
411 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 411 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
412 | 412 | ||
413 | skl->init_failed = 1; /* to be sure */ | 413 | skl->init_done = 0; /* to be sure */ |
414 | 414 | ||
415 | snd_hdac_ext_stop_streams(ebus); | 415 | snd_hdac_ext_stop_streams(ebus); |
416 | 416 | ||
@@ -428,8 +428,10 @@ static int skl_free(struct hdac_ext_bus *ebus) | |||
428 | 428 | ||
429 | snd_hdac_ext_bus_exit(ebus); | 429 | snd_hdac_ext_bus_exit(ebus); |
430 | 430 | ||
431 | cancel_work_sync(&skl->probe_work); | ||
431 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | 432 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) |
432 | snd_hdac_i915_exit(&ebus->bus); | 433 | snd_hdac_i915_exit(&ebus->bus); |
434 | |||
433 | return 0; | 435 | return 0; |
434 | } | 436 | } |
435 | 437 | ||
@@ -566,6 +568,84 @@ static const struct hdac_bus_ops bus_core_ops = { | |||
566 | .get_response = snd_hdac_bus_get_response, | 568 | .get_response = snd_hdac_bus_get_response, |
567 | }; | 569 | }; |
568 | 570 | ||
571 | static int skl_i915_init(struct hdac_bus *bus) | ||
572 | { | ||
573 | int err; | ||
574 | |||
575 | /* | ||
576 | * The HDMI codec is in GPU so we need to ensure that it is powered | ||
577 | * up and ready for probe | ||
578 | */ | ||
579 | err = snd_hdac_i915_init(bus); | ||
580 | if (err < 0) | ||
581 | return err; | ||
582 | |||
583 | err = snd_hdac_display_power(bus, true); | ||
584 | if (err < 0) | ||
585 | dev_err(bus->dev, "Cannot turn on display power on i915\n"); | ||
586 | |||
587 | return err; | ||
588 | } | ||
589 | |||
590 | static void skl_probe_work(struct work_struct *work) | ||
591 | { | ||
592 | struct skl *skl = container_of(work, struct skl, probe_work); | ||
593 | struct hdac_ext_bus *ebus = &skl->ebus; | ||
594 | struct hdac_bus *bus = ebus_to_hbus(ebus); | ||
595 | struct hdac_ext_link *hlink = NULL; | ||
596 | int err; | ||
597 | |||
598 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | ||
599 | err = skl_i915_init(bus); | ||
600 | if (err < 0) | ||
601 | return; | ||
602 | } | ||
603 | |||
604 | err = skl_init_chip(bus, true); | ||
605 | if (err < 0) { | ||
606 | dev_err(bus->dev, "Init chip failed with err: %d\n", err); | ||
607 | goto out_err; | ||
608 | } | ||
609 | |||
610 | /* codec detection */ | ||
611 | if (!bus->codec_mask) | ||
612 | dev_info(bus->dev, "no hda codecs found!\n"); | ||
613 | |||
614 | /* create codec instances */ | ||
615 | err = skl_codec_create(ebus); | ||
616 | if (err < 0) | ||
617 | goto out_err; | ||
618 | |||
619 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | ||
620 | err = snd_hdac_display_power(bus, false); | ||
621 | if (err < 0) { | ||
622 | dev_err(bus->dev, "Cannot turn off display power on i915\n"); | ||
623 | return; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | /* register platform dai and controls */ | ||
628 | err = skl_platform_register(bus->dev); | ||
629 | if (err < 0) | ||
630 | return; | ||
631 | /* | ||
632 | * we are done probing so decrement link counts | ||
633 | */ | ||
634 | list_for_each_entry(hlink, &ebus->hlink_list, list) | ||
635 | snd_hdac_ext_bus_link_put(ebus, hlink); | ||
636 | |||
637 | /* configure PM */ | ||
638 | pm_runtime_put_noidle(bus->dev); | ||
639 | pm_runtime_allow(bus->dev); | ||
640 | skl->init_done = 1; | ||
641 | |||
642 | return; | ||
643 | |||
644 | out_err: | ||
645 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | ||
646 | err = snd_hdac_display_power(bus, false); | ||
647 | } | ||
648 | |||
569 | /* | 649 | /* |
570 | * constructor | 650 | * constructor |
571 | */ | 651 | */ |
@@ -593,6 +673,7 @@ static int skl_create(struct pci_dev *pci, | |||
593 | snd_hdac_ext_bus_init(ebus, &pci->dev, &bus_core_ops, io_ops); | 673 | snd_hdac_ext_bus_init(ebus, &pci->dev, &bus_core_ops, io_ops); |
594 | ebus->bus.use_posbuf = 1; | 674 | ebus->bus.use_posbuf = 1; |
595 | skl->pci = pci; | 675 | skl->pci = pci; |
676 | INIT_WORK(&skl->probe_work, skl_probe_work); | ||
596 | 677 | ||
597 | ebus->bus.bdl_pos_adj = 0; | 678 | ebus->bus.bdl_pos_adj = 0; |
598 | 679 | ||
@@ -601,27 +682,6 @@ static int skl_create(struct pci_dev *pci, | |||
601 | return 0; | 682 | return 0; |
602 | } | 683 | } |
603 | 684 | ||
604 | static int skl_i915_init(struct hdac_bus *bus) | ||
605 | { | ||
606 | int err; | ||
607 | |||
608 | /* | ||
609 | * The HDMI codec is in GPU so we need to ensure that it is powered | ||
610 | * up and ready for probe | ||
611 | */ | ||
612 | err = snd_hdac_i915_init(bus); | ||
613 | if (err < 0) | ||
614 | return err; | ||
615 | |||
616 | err = snd_hdac_display_power(bus, true); | ||
617 | if (err < 0) { | ||
618 | dev_err(bus->dev, "Cannot turn on display power on i915\n"); | ||
619 | return err; | ||
620 | } | ||
621 | |||
622 | return err; | ||
623 | } | ||
624 | |||
625 | static int skl_first_init(struct hdac_ext_bus *ebus) | 685 | static int skl_first_init(struct hdac_ext_bus *ebus) |
626 | { | 686 | { |
627 | struct skl *skl = ebus_to_skl(ebus); | 687 | struct skl *skl = ebus_to_skl(ebus); |
@@ -684,20 +744,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus) | |||
684 | /* initialize chip */ | 744 | /* initialize chip */ |
685 | skl_init_pci(skl); | 745 | skl_init_pci(skl); |
686 | 746 | ||
687 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | 747 | return skl_init_chip(bus, true); |
688 | err = skl_i915_init(bus); | ||
689 | if (err < 0) | ||
690 | return err; | ||
691 | } | ||
692 | |||
693 | skl_init_chip(bus, true); | ||
694 | |||
695 | /* codec detection */ | ||
696 | if (!bus->codec_mask) { | ||
697 | dev_info(bus->dev, "no hda codecs found!\n"); | ||
698 | } | ||
699 | |||
700 | return 0; | ||
701 | } | 748 | } |
702 | 749 | ||
703 | static int skl_probe(struct pci_dev *pci, | 750 | static int skl_probe(struct pci_dev *pci, |
@@ -706,7 +753,6 @@ static int skl_probe(struct pci_dev *pci, | |||
706 | struct skl *skl; | 753 | struct skl *skl; |
707 | struct hdac_ext_bus *ebus = NULL; | 754 | struct hdac_ext_bus *ebus = NULL; |
708 | struct hdac_bus *bus = NULL; | 755 | struct hdac_bus *bus = NULL; |
709 | struct hdac_ext_link *hlink = NULL; | ||
710 | int err; | 756 | int err; |
711 | 757 | ||
712 | /* we use ext core ops, so provide NULL for ops here */ | 758 | /* we use ext core ops, so provide NULL for ops here */ |
@@ -729,7 +775,7 @@ static int skl_probe(struct pci_dev *pci, | |||
729 | 775 | ||
730 | if (skl->nhlt == NULL) { | 776 | if (skl->nhlt == NULL) { |
731 | err = -ENODEV; | 777 | err = -ENODEV; |
732 | goto out_display_power_off; | 778 | goto out_free; |
733 | } | 779 | } |
734 | 780 | ||
735 | err = skl_nhlt_create_sysfs(skl); | 781 | err = skl_nhlt_create_sysfs(skl); |
@@ -760,56 +806,24 @@ static int skl_probe(struct pci_dev *pci, | |||
760 | if (bus->mlcap) | 806 | if (bus->mlcap) |
761 | snd_hdac_ext_bus_get_ml_capabilities(ebus); | 807 | snd_hdac_ext_bus_get_ml_capabilities(ebus); |
762 | 808 | ||
809 | snd_hdac_bus_stop_chip(bus); | ||
810 | |||
763 | /* create device for soc dmic */ | 811 | /* create device for soc dmic */ |
764 | err = skl_dmic_device_register(skl); | 812 | err = skl_dmic_device_register(skl); |
765 | if (err < 0) | 813 | if (err < 0) |
766 | goto out_dsp_free; | 814 | goto out_dsp_free; |
767 | 815 | ||
768 | /* register platform dai and controls */ | 816 | schedule_work(&skl->probe_work); |
769 | err = skl_platform_register(bus->dev); | ||
770 | if (err < 0) | ||
771 | goto out_dmic_free; | ||
772 | |||
773 | /* create codec instances */ | ||
774 | err = skl_codec_create(ebus); | ||
775 | if (err < 0) | ||
776 | goto out_unregister; | ||
777 | |||
778 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | ||
779 | err = snd_hdac_display_power(bus, false); | ||
780 | if (err < 0) { | ||
781 | dev_err(bus->dev, "Cannot turn off display power on i915\n"); | ||
782 | return err; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | /* | ||
787 | * we are done probling so decrement link counts | ||
788 | */ | ||
789 | list_for_each_entry(hlink, &ebus->hlink_list, list) | ||
790 | snd_hdac_ext_bus_link_put(ebus, hlink); | ||
791 | |||
792 | /* configure PM */ | ||
793 | pm_runtime_put_noidle(bus->dev); | ||
794 | pm_runtime_allow(bus->dev); | ||
795 | 817 | ||
796 | return 0; | 818 | return 0; |
797 | 819 | ||
798 | out_unregister: | ||
799 | skl_platform_unregister(bus->dev); | ||
800 | out_dmic_free: | ||
801 | skl_dmic_device_unregister(skl); | ||
802 | out_dsp_free: | 820 | out_dsp_free: |
803 | skl_free_dsp(skl); | 821 | skl_free_dsp(skl); |
804 | out_mach_free: | 822 | out_mach_free: |
805 | skl_machine_device_unregister(skl); | 823 | skl_machine_device_unregister(skl); |
806 | out_nhlt_free: | 824 | out_nhlt_free: |
807 | skl_nhlt_free(skl->nhlt); | 825 | skl_nhlt_free(skl->nhlt); |
808 | out_display_power_off: | ||
809 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | ||
810 | snd_hdac_display_power(bus, false); | ||
811 | out_free: | 826 | out_free: |
812 | skl->init_failed = 1; | ||
813 | skl_free(ebus); | 827 | skl_free(ebus); |
814 | 828 | ||
815 | return err; | 829 | return err; |
@@ -828,7 +842,7 @@ static void skl_shutdown(struct pci_dev *pci) | |||
828 | 842 | ||
829 | skl = ebus_to_skl(ebus); | 843 | skl = ebus_to_skl(ebus); |
830 | 844 | ||
831 | if (skl->init_failed) | 845 | if (!skl->init_done) |
832 | return; | 846 | return; |
833 | 847 | ||
834 | snd_hdac_ext_stop_streams(ebus); | 848 | snd_hdac_ext_stop_streams(ebus); |
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index a454f6035f3e..2a630fcb7f08 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h | |||
@@ -46,7 +46,7 @@ struct skl { | |||
46 | struct hdac_ext_bus ebus; | 46 | struct hdac_ext_bus ebus; |
47 | struct pci_dev *pci; | 47 | struct pci_dev *pci; |
48 | 48 | ||
49 | unsigned int init_failed:1; /* delayed init failed */ | 49 | unsigned int init_done:1; /* delayed init status */ |
50 | struct platform_device *dmic_dev; | 50 | struct platform_device *dmic_dev; |
51 | struct platform_device *i2s_dev; | 51 | struct platform_device *i2s_dev; |
52 | struct snd_soc_platform *platform; | 52 | struct snd_soc_platform *platform; |
@@ -64,6 +64,8 @@ struct skl { | |||
64 | const struct firmware *tplg; | 64 | const struct firmware *tplg; |
65 | 65 | ||
66 | int supend_active; | 66 | int supend_active; |
67 | |||
68 | struct work_struct probe_work; | ||
67 | }; | 69 | }; |
68 | 70 | ||
69 | #define skl_to_ebus(s) (&(s)->ebus) | 71 | #define skl_to_ebus(s) (&(s)->ebus) |
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 66203d107a11..d3b0dc145a56 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c | |||
@@ -507,7 +507,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, | |||
507 | rbga = rbgx; | 507 | rbga = rbgx; |
508 | adg->rbga_rate_for_441khz = rate / div; | 508 | adg->rbga_rate_for_441khz = rate / div; |
509 | ckr |= brg_table[i] << 20; | 509 | ckr |= brg_table[i] << 20; |
510 | if (req_441kHz_rate) | 510 | if (req_441kHz_rate && |
511 | !(adg_mode_flags(adg) & AUDIO_OUT_48)) | ||
511 | parent_clk_name = __clk_get_name(clk); | 512 | parent_clk_name = __clk_get_name(clk); |
512 | } | 513 | } |
513 | } | 514 | } |
@@ -522,7 +523,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, | |||
522 | rbgb = rbgx; | 523 | rbgb = rbgx; |
523 | adg->rbgb_rate_for_48khz = rate / div; | 524 | adg->rbgb_rate_for_48khz = rate / div; |
524 | ckr |= brg_table[i] << 16; | 525 | ckr |= brg_table[i] << 16; |
525 | if (req_48kHz_rate) | 526 | if (req_48kHz_rate && |
527 | (adg_mode_flags(adg) & AUDIO_OUT_48)) | ||
526 | parent_clk_name = __clk_get_name(clk); | 528 | parent_clk_name = __clk_get_name(clk); |
527 | } | 529 | } |
528 | } | 530 | } |
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index 7d92a24b7cfa..d879c010cf03 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c | |||
@@ -89,6 +89,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod, | |||
89 | dev_dbg(dev, "ctu/mix path = 0x%08x", data); | 89 | dev_dbg(dev, "ctu/mix path = 0x%08x", data); |
90 | 90 | ||
91 | rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); | 91 | rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); |
92 | rsnd_mod_write(mod, CMD_BUSIF_MODE, rsnd_get_busif_shift(io, mod) | 1); | ||
92 | rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); | 93 | rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); |
93 | 94 | ||
94 | rsnd_adg_set_cmd_timsel_gen2(mod, io); | 95 | rsnd_adg_set_cmd_timsel_gen2(mod, io); |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1744015408c3..8c1f4e2e0c4f 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -343,6 +343,57 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) | |||
343 | return 0x76543210; | 343 | return 0x76543210; |
344 | } | 344 | } |
345 | 345 | ||
346 | u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod) | ||
347 | { | ||
348 | enum rsnd_mod_type playback_mods[] = { | ||
349 | RSND_MOD_SRC, | ||
350 | RSND_MOD_CMD, | ||
351 | RSND_MOD_SSIU, | ||
352 | }; | ||
353 | enum rsnd_mod_type capture_mods[] = { | ||
354 | RSND_MOD_CMD, | ||
355 | RSND_MOD_SRC, | ||
356 | RSND_MOD_SSIU, | ||
357 | }; | ||
358 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
359 | struct rsnd_mod *tmod = NULL; | ||
360 | enum rsnd_mod_type *mods = | ||
361 | rsnd_io_is_play(io) ? | ||
362 | playback_mods : capture_mods; | ||
363 | int i; | ||
364 | |||
365 | /* | ||
366 | * This is needed for 24bit data | ||
367 | * We need to shift 8bit | ||
368 | * | ||
369 | * Linux 24bit data is located as 0x00****** | ||
370 | * HW 24bit data is located as 0x******00 | ||
371 | * | ||
372 | */ | ||
373 | switch (runtime->sample_bits) { | ||
374 | case 16: | ||
375 | return 0; | ||
376 | case 32: | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | for (i = 0; i < ARRAY_SIZE(playback_mods); i++) { | ||
381 | tmod = rsnd_io_to_mod(io, mods[i]); | ||
382 | if (tmod) | ||
383 | break; | ||
384 | } | ||
385 | |||
386 | if (tmod != mod) | ||
387 | return 0; | ||
388 | |||
389 | if (rsnd_io_is_play(io)) | ||
390 | return (0 << 20) | /* shift to Left */ | ||
391 | (8 << 16); /* 8bit */ | ||
392 | else | ||
393 | return (1 << 20) | /* shift to Right */ | ||
394 | (8 << 16); /* 8bit */ | ||
395 | } | ||
396 | |||
346 | /* | 397 | /* |
347 | * rsnd_dai functions | 398 | * rsnd_dai functions |
348 | */ | 399 | */ |
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 63b6d3c28021..4b0980728e13 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -236,6 +236,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) | |||
236 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), | 236 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), |
237 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), | 237 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), |
238 | RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), | 238 | RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), |
239 | RSND_GEN_M_REG(CMD_BUSIF_MODE, 0x184, 0x20), | ||
239 | RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), | 240 | RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), |
240 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), | 241 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), |
241 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), | 242 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index dbf4163427e8..323af41ecfcb 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -73,6 +73,7 @@ enum rsnd_reg { | |||
73 | RSND_REG_SCU_SYS_INT_EN0, | 73 | RSND_REG_SCU_SYS_INT_EN0, |
74 | RSND_REG_SCU_SYS_INT_EN1, | 74 | RSND_REG_SCU_SYS_INT_EN1, |
75 | RSND_REG_CMD_CTRL, | 75 | RSND_REG_CMD_CTRL, |
76 | RSND_REG_CMD_BUSIF_MODE, | ||
76 | RSND_REG_CMD_BUSIF_DALIGN, | 77 | RSND_REG_CMD_BUSIF_DALIGN, |
77 | RSND_REG_CMD_ROUTE_SLCT, | 78 | RSND_REG_CMD_ROUTE_SLCT, |
78 | RSND_REG_CMDOUT_TIMSEL, | 79 | RSND_REG_CMDOUT_TIMSEL, |
@@ -204,6 +205,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | |||
204 | u32 mask, u32 data); | 205 | u32 mask, u32 data); |
205 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | 206 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
206 | u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | 207 | u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
208 | u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod); | ||
207 | 209 | ||
208 | /* | 210 | /* |
209 | * R-Car DMA | 211 | * R-Car DMA |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 20b5b2ec625e..76a477a3ccb5 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -190,11 +190,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
190 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 190 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
191 | struct device *dev = rsnd_priv_to_dev(priv); | 191 | struct device *dev = rsnd_priv_to_dev(priv); |
192 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 192 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
193 | int is_play = rsnd_io_is_play(io); | ||
193 | int use_src = 0; | 194 | int use_src = 0; |
194 | u32 fin, fout; | 195 | u32 fin, fout; |
195 | u32 ifscr, fsrate, adinr; | 196 | u32 ifscr, fsrate, adinr; |
196 | u32 cr, route; | 197 | u32 cr, route; |
197 | u32 bsdsr, bsisr; | 198 | u32 bsdsr, bsisr; |
199 | u32 i_busif, o_busif, tmp; | ||
198 | uint ratio; | 200 | uint ratio; |
199 | 201 | ||
200 | if (!runtime) | 202 | if (!runtime) |
@@ -270,6 +272,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
270 | break; | 272 | break; |
271 | } | 273 | } |
272 | 274 | ||
275 | /* BUSIF_MODE */ | ||
276 | tmp = rsnd_get_busif_shift(io, mod); | ||
277 | i_busif = ( is_play ? tmp : 0) | 1; | ||
278 | o_busif = (!is_play ? tmp : 0) | 1; | ||
279 | |||
273 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); | 280 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); |
274 | 281 | ||
275 | rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ | 282 | rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ |
@@ -281,8 +288,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
281 | rsnd_mod_write(mod, SRC_BSISR, bsisr); | 288 | rsnd_mod_write(mod, SRC_BSISR, bsisr); |
282 | rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ | 289 | rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ |
283 | 290 | ||
284 | rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1); | 291 | rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif); |
285 | rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1); | 292 | rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif); |
293 | |||
286 | rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); | 294 | rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); |
287 | 295 | ||
288 | rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout); | 296 | rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout); |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 135c5669f796..91e5c07911b4 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -302,7 +302,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, | |||
302 | * always use 32bit system word. | 302 | * always use 32bit system word. |
303 | * see also rsnd_ssi_master_clk_enable() | 303 | * see also rsnd_ssi_master_clk_enable() |
304 | */ | 304 | */ |
305 | cr_own = FORCE | SWL_32 | PDTA; | 305 | cr_own = FORCE | SWL_32; |
306 | 306 | ||
307 | if (rdai->bit_clk_inv) | 307 | if (rdai->bit_clk_inv) |
308 | cr_own |= SCKP; | 308 | cr_own |= SCKP; |
@@ -550,6 +550,13 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, | |||
550 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 550 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
551 | u32 *buf = (u32 *)(runtime->dma_area + | 551 | u32 *buf = (u32 *)(runtime->dma_area + |
552 | rsnd_dai_pointer_offset(io, 0)); | 552 | rsnd_dai_pointer_offset(io, 0)); |
553 | int shift = 0; | ||
554 | |||
555 | switch (runtime->sample_bits) { | ||
556 | case 32: | ||
557 | shift = 8; | ||
558 | break; | ||
559 | } | ||
553 | 560 | ||
554 | /* | 561 | /* |
555 | * 8/16/32 data can be assesse to TDR/RDR register | 562 | * 8/16/32 data can be assesse to TDR/RDR register |
@@ -557,9 +564,9 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, | |||
557 | * see rsnd_ssi_init() | 564 | * see rsnd_ssi_init() |
558 | */ | 565 | */ |
559 | if (rsnd_io_is_play(io)) | 566 | if (rsnd_io_is_play(io)) |
560 | rsnd_mod_write(mod, SSITDR, *buf); | 567 | rsnd_mod_write(mod, SSITDR, (*buf) << shift); |
561 | else | 568 | else |
562 | *buf = rsnd_mod_read(mod, SSIRDR); | 569 | *buf = (rsnd_mod_read(mod, SSIRDR) >> shift); |
563 | 570 | ||
564 | elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); | 571 | elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); |
565 | } | 572 | } |
@@ -709,6 +716,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
709 | struct rsnd_priv *priv) | 716 | struct rsnd_priv *priv) |
710 | { | 717 | { |
711 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 718 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
719 | struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); | ||
720 | |||
721 | /* Do nothing for SSI parent mod */ | ||
722 | if (ssi_parent_mod == mod) | ||
723 | return 0; | ||
712 | 724 | ||
713 | /* PIO will request IRQ again */ | 725 | /* PIO will request IRQ again */ |
714 | free_irq(ssi->irq, mod); | 726 | free_irq(ssi->irq, mod); |
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 14fafdaf1395..512d238b79e2 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c | |||
@@ -144,7 +144,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, | |||
144 | (rsnd_io_is_play(io) ? | 144 | (rsnd_io_is_play(io) ? |
145 | rsnd_runtime_channel_after_ctu(io) : | 145 | rsnd_runtime_channel_after_ctu(io) : |
146 | rsnd_runtime_channel_original(io))); | 146 | rsnd_runtime_channel_original(io))); |
147 | rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); | 147 | rsnd_mod_write(mod, SSI_BUSIF_MODE, |
148 | rsnd_get_busif_shift(io, mod) | 1); | ||
148 | rsnd_mod_write(mod, SSI_BUSIF_DALIGN, | 149 | rsnd_mod_write(mod, SSI_BUSIF_DALIGN, |
149 | rsnd_get_dalign(mod, io)); | 150 | rsnd_get_dalign(mod, io)); |
150 | } | 151 | } |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index aae099c0e502..754e3ef8d7ae 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -2286,6 +2286,9 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card) | |||
2286 | list_for_each_entry(rtd, &card->rtd_list, list) | 2286 | list_for_each_entry(rtd, &card->rtd_list, list) |
2287 | flush_delayed_work(&rtd->delayed_work); | 2287 | flush_delayed_work(&rtd->delayed_work); |
2288 | 2288 | ||
2289 | /* free the ALSA card at first; this syncs with pending operations */ | ||
2290 | snd_card_free(card->snd_card); | ||
2291 | |||
2289 | /* remove and free each DAI */ | 2292 | /* remove and free each DAI */ |
2290 | soc_remove_dai_links(card); | 2293 | soc_remove_dai_links(card); |
2291 | soc_remove_pcm_runtimes(card); | 2294 | soc_remove_pcm_runtimes(card); |
@@ -2300,9 +2303,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card) | |||
2300 | if (card->remove) | 2303 | if (card->remove) |
2301 | card->remove(card); | 2304 | card->remove(card); |
2302 | 2305 | ||
2303 | snd_card_free(card->snd_card); | ||
2304 | return 0; | 2306 | return 0; |
2305 | |||
2306 | } | 2307 | } |
2307 | 2308 | ||
2308 | /* removes a socdev */ | 2309 | /* removes a socdev */ |