Commit 03cef710 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-4.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Here are a bunch of fixes as you can see in diffstat.

  One core change in ASoC is about the unexpected unbinding error, and
  another about debugfs cleanup.

  The rest are wide-spread driver-specific fixes: a series of LINE6 USB
  fixes, a HD-audio quirk, and various ASoC fixes including OMAP boot
  fixes and Intel SKL fixes"

* tag 'sound-4.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (22 commits)
  ALSA: hda/realtek - fix headset mic detection for MSI MS-B120
  ASoC: omap-mcpdm: Fix irq resource handling
  ASoC: max98371: Add terminate entry for i2c_device_id tables
  ALSA: line6: Fix POD sysfs attributes segfault
  ALSA: line6: Give up on the lock while URBs are released.
  ALSA: line6: Remove double line6_pcm_release() after failed acquire.
  ASoC: omap-abe-twl6040: Correct dmic-codec device registration
  ASoC: core: Clean up DAPM before the card debugfs
  ASoC: omap-mcpdm: Drop pdmclk clock handling
  ASoC: atmel_ssc_dai: Don't unconditionally reset SSC on stream startup
  ASoC: compress: Fix leak of a widget list in soc_compr_open_fe
  ASoC: Intel: Skylake: Fix error return code in skl_probe()
  ASoC: wm2000: Fix return of uninitialised varible
  ASoC: Fix leak of rtd in soc_bind_dai_link
  ASoC: da7213: Default to 64 BCLKs per WCLK to support all formats
  ASoC: nau8825: fix static check error about semaphone control
  ASoC: nau8825: fix bug in playback when suspend
  ASoC: samsung: Fix clock handling in S3C24XX_UDA134X card
  ASoC: simple-card-utils: add missing MODULE_xxx()
  ASoC: Intel: Skylake: Check list empty while getting module info
  ...
parents 28687b93 a820cd3d
...@@ -8,8 +8,6 @@ Required properties: ...@@ -8,8 +8,6 @@ Required properties:
- interrupts: Interrupt number for McPDM - interrupts: Interrupt number for McPDM
- interrupt-parent: The parent interrupt controller - interrupt-parent: The parent interrupt controller
- ti,hwmods: Name of the hwmod associated to the McPDM - ti,hwmods: Name of the hwmod associated to the McPDM
- clocks: phandle for the pdmclk provider, likely <&twl6040>
- clock-names: Must be "pdmclk"
Example: Example:
...@@ -21,11 +19,3 @@ mcpdm: mcpdm@40132000 { ...@@ -21,11 +19,3 @@ mcpdm: mcpdm@40132000 {
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
ti,hwmods = "mcpdm"; ti,hwmods = "mcpdm";
}; };
In board DTS file the pdmclk needs to be added:
&mcpdm {
clocks = <&twl6040>;
clock-names = "pdmclk";
status = "okay";
};
...@@ -4828,7 +4828,7 @@ enum { ...@@ -4828,7 +4828,7 @@ enum {
ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC292_FIXUP_TPT440_DOCK, ALC292_FIXUP_TPT440_DOCK,
ALC292_FIXUP_TPT440, ALC292_FIXUP_TPT440,
ALC283_FIXUP_BXBT2807_MIC, ALC283_FIXUP_HEADSET_MIC,
ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
ALC282_FIXUP_ASPIRE_V5_PINS, ALC282_FIXUP_ASPIRE_V5_PINS,
ALC280_FIXUP_HP_GPIO4, ALC280_FIXUP_HP_GPIO4,
...@@ -5321,7 +5321,7 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -5321,7 +5321,7 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC292_FIXUP_TPT440_DOCK, .chain_id = ALC292_FIXUP_TPT440_DOCK,
}, },
[ALC283_FIXUP_BXBT2807_MIC] = { [ALC283_FIXUP_HEADSET_MIC] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) { .v.pins = (const struct hda_pintbl[]) {
{ 0x19, 0x04a110f0 }, { 0x19, 0x04a110f0 },
...@@ -5651,7 +5651,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -5651,7 +5651,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
......
...@@ -299,8 +299,9 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, ...@@ -299,8 +299,9 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
clk_enable(ssc_p->ssc->clk); clk_enable(ssc_p->ssc->clk);
ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk); ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
/* Reset the SSC to keep it at a clean status */ /* Reset the SSC unless initialized to keep it in a clean state */
ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); if (!ssc_p->initialized)
ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dir = 0; dir = 0;
......
...@@ -1247,8 +1247,8 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ...@@ -1247,8 +1247,8 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
return -EINVAL; return -EINVAL;
} }
/* By default only 32 BCLK per WCLK is supported */ /* By default only 64 BCLK per WCLK is supported */
dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_32; dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_64;
snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode); snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK, snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
......
...@@ -412,6 +412,7 @@ static int max98371_i2c_remove(struct i2c_client *client) ...@@ -412,6 +412,7 @@ static int max98371_i2c_remove(struct i2c_client *client)
static const struct i2c_device_id max98371_i2c_id[] = { static const struct i2c_device_id max98371_i2c_id[] = {
{ "max98371", 0 }, { "max98371", 0 },
{ }
}; };
MODULE_DEVICE_TABLE(i2c, max98371_i2c_id); MODULE_DEVICE_TABLE(i2c, max98371_i2c_id);
......
...@@ -212,31 +212,6 @@ static const unsigned short logtable[256] = { ...@@ -212,31 +212,6 @@ static const unsigned short logtable[256] = {
0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
}; };
static struct snd_soc_dai *nau8825_get_codec_dai(struct nau8825 *nau8825)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(nau8825->dapm);
struct snd_soc_component *component = &codec->component;
struct snd_soc_dai *codec_dai, *_dai;
list_for_each_entry_safe(codec_dai, _dai, &component->dai_list, list) {
if (!strncmp(codec_dai->name, NUVOTON_CODEC_DAI,
strlen(NUVOTON_CODEC_DAI)))
return codec_dai;
}
return NULL;
}
static bool nau8825_dai_is_active(struct nau8825 *nau8825)
{
struct snd_soc_dai *codec_dai = nau8825_get_codec_dai(nau8825);
if (codec_dai) {
if (codec_dai->playback_active || codec_dai->capture_active)
return true;
}
return false;
}
/** /**
* nau8825_sema_acquire - acquire the semaphore of nau88l25 * nau8825_sema_acquire - acquire the semaphore of nau88l25
* @nau8825: component to register the codec private data with * @nau8825: component to register the codec private data with
...@@ -250,19 +225,26 @@ static bool nau8825_dai_is_active(struct nau8825 *nau8825) ...@@ -250,19 +225,26 @@ static bool nau8825_dai_is_active(struct nau8825 *nau8825)
* Acquires the semaphore without jiffies. If no more tasks are allowed * Acquires the semaphore without jiffies. If no more tasks are allowed
* to acquire the semaphore, calling this function will put the task to * to acquire the semaphore, calling this function will put the task to
* sleep until the semaphore is released. * sleep until the semaphore is released.
* It returns if the semaphore was acquired. * If the semaphore is not released within the specified number of jiffies,
* this function returns -ETIME.
* If the sleep is interrupted by a signal, this function will return -EINTR.
* It returns 0 if the semaphore was acquired successfully.
*/ */
static void nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
{ {
int ret; int ret;
if (timeout) if (timeout) {
ret = down_timeout(&nau8825->xtalk_sem, timeout); ret = down_timeout(&nau8825->xtalk_sem, timeout);
else if (ret < 0)
dev_warn(nau8825->dev, "Acquire semaphone timeout\n");
} else {
ret = down_interruptible(&nau8825->xtalk_sem); ret = down_interruptible(&nau8825->xtalk_sem);
if (ret < 0)
dev_warn(nau8825->dev, "Acquire semaphone fail\n");
}
if (ret < 0) return ret;
dev_warn(nau8825->dev, "Acquire semaphone fail\n");
} }
/** /**
...@@ -1205,6 +1187,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, ...@@ -1205,6 +1187,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
unsigned int val_len = 0; unsigned int val_len = 0;
nau8825_sema_acquire(nau8825, 2 * HZ);
switch (params_width(params)) { switch (params_width(params)) {
case 16: case 16:
val_len |= NAU8825_I2S_DL_16; val_len |= NAU8825_I2S_DL_16;
...@@ -1225,6 +1209,9 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, ...@@ -1225,6 +1209,9 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
NAU8825_I2S_DL_MASK, val_len); NAU8825_I2S_DL_MASK, val_len);
/* Release the semaphone. */
nau8825_sema_release(nau8825);
return 0; return 0;
} }
...@@ -1234,6 +1221,8 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ...@@ -1234,6 +1221,8 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
unsigned int ctrl1_val = 0, ctrl2_val = 0; unsigned int ctrl1_val = 0, ctrl2_val = 0;
nau8825_sema_acquire(nau8825, 2 * HZ);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
ctrl2_val |= NAU8825_I2S_MS_MASTER; ctrl2_val |= NAU8825_I2S_MS_MASTER;
...@@ -1282,6 +1271,9 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ...@@ -1282,6 +1271,9 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_MS_MASK, ctrl2_val); NAU8825_I2S_MS_MASK, ctrl2_val);
/* Release the semaphone. */
nau8825_sema_release(nau8825);
return 0; return 0;
} }
...@@ -1611,8 +1603,11 @@ static irqreturn_t nau8825_interrupt(int irq, void *data) ...@@ -1611,8 +1603,11 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
* cess and restore changes if process * cess and restore changes if process
* is ongoing when ejection. * is ongoing when ejection.
*/ */
int ret;
nau8825->xtalk_protect = true; nau8825->xtalk_protect = true;
nau8825_sema_acquire(nau8825, 0); ret = nau8825_sema_acquire(nau8825, 0);
if (ret < 0)
nau8825->xtalk_protect = false;
} }
/* Startup cross talk detection process */ /* Startup cross talk detection process */
nau8825->xtalk_state = NAU8825_XTALK_PREPARE; nau8825->xtalk_state = NAU8825_XTALK_PREPARE;
...@@ -2238,23 +2233,14 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec) ...@@ -2238,23 +2233,14 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec) static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
{ {
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
int ret;
regcache_cache_only(nau8825->regmap, false); regcache_cache_only(nau8825->regmap, false);
regcache_sync(nau8825->regmap); regcache_sync(nau8825->regmap);
if (nau8825_is_jack_inserted(nau8825->regmap)) { nau8825->xtalk_protect = true;
/* If the jack is inserted, we need to check whether the play- ret = nau8825_sema_acquire(nau8825, 0);
* back is active before suspend. If active, the driver has to if (ret < 0)
* raise the protection for cross talk function to avoid the nau8825->xtalk_protect = false;
* playback recovers before cross talk process finish. Other-
* wise, the playback will be interfered by cross talk func-
* tion. It is better to apply hardware related parameters
* before starting playback or record.
*/
if (nau8825_dai_is_active(nau8825)) {
nau8825->xtalk_protect = true;
nau8825_sema_acquire(nau8825, 0);
}
}
enable_irq(nau8825->irq); enable_irq(nau8825->irq);
return 0; return 0;
......
...@@ -581,7 +581,7 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, ...@@ -581,7 +581,7 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000,
if (anc_transitions[i].dest == ANC_OFF) if (anc_transitions[i].dest == ANC_OFF)
clk_disable_unprepare(wm2000->mclk); clk_disable_unprepare(wm2000->mclk);
return ret; return 0;
} }
static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
......
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) := simple-card-utils.o snd-soc-simple-card-utils-objs := simple-card-utils.o
snd-soc-simple-card-objs := simple-card.o snd-soc-simple-card-objs := simple-card.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <sound/simple_card_utils.h> #include <sound/simple_card_utils.h>
...@@ -95,3 +96,8 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card, ...@@ -95,3 +96,8 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
/* Module information */
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
MODULE_LICENSE("GPL v2");
...@@ -123,6 +123,11 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, ...@@ -123,6 +123,11 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
uuid_mod = (uuid_le *)uuid; uuid_mod = (uuid_le *)uuid;
if (list_empty(&ctx->uuid_list)) {
dev_err(ctx->dev, "Module list is empty\n");
return -EINVAL;
}
list_for_each_entry(module, &ctx->uuid_list, list) { list_for_each_entry(module, &ctx->uuid_list, list) {
if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
dfw_config->module_id = module->id; dfw_config->module_id = module->id;
......
...@@ -672,8 +672,10 @@ static int skl_probe(struct pci_dev *pci, ...@@ -672,8 +672,10 @@ static int skl_probe(struct pci_dev *pci,
skl->nhlt = skl_nhlt_init(bus->dev); skl->nhlt = skl_nhlt_init(bus->dev);
if (skl->nhlt == NULL) if (skl->nhlt == NULL) {
err = -ENODEV;
goto out_free; goto out_free;
}
skl_nhlt_update_topology_bin(skl); skl_nhlt_update_topology_bin(skl);
......
...@@ -38,10 +38,10 @@ ...@@ -38,10 +38,10 @@
struct abe_twl6040 { struct abe_twl6040 {
int jack_detection; /* board can detect jack events */ int jack_detection; /* board can detect jack events */
int mclk_freq; /* MCLK frequency speed for twl6040 */ int mclk_freq; /* MCLK frequency speed for twl6040 */
struct platform_device *dmic_codec_dev;
}; };
struct platform_device *dmic_codec_dev;
static int omap_abe_hw_params(struct snd_pcm_substream *substream, static int omap_abe_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
...@@ -258,8 +258,6 @@ static int omap_abe_probe(struct platform_device *pdev) ...@@ -258,8 +258,6 @@ static int omap_abe_probe(struct platform_device *pdev)
if (priv == NULL) if (priv == NULL)
return -ENOMEM; return -ENOMEM;
priv->dmic_codec_dev = ERR_PTR(-EINVAL);
if (snd_soc_of_parse_card_name(card, "ti,model")) { if (snd_soc_of_parse_card_name(card, "ti,model")) {
dev_err(&pdev->dev, "Card name is not provided\n"); dev_err(&pdev->dev, "Card name is not provided\n");
return -ENODEV; return -ENODEV;
...@@ -284,13 +282,6 @@ static int omap_abe_probe(struct platform_device *pdev) ...@@ -284,13 +282,6 @@ static int omap_abe_probe(struct platform_device *pdev)
num_links = 2; num_links = 2;
abe_twl6040_dai_links[1].cpu_of_node = dai_node; abe_twl6040_dai_links[1].cpu_of_node = dai_node;
abe_twl6040_dai_links[1].platform_of_node = dai_node; abe_twl6040_dai_links[1].platform_of_node = dai_node;
priv->dmic_codec_dev = platform_device_register_simple(
"dmic-codec", -1, NULL, 0);
if (IS_ERR(priv->dmic_codec_dev)) {
dev_err(&pdev->dev, "Can't instantiate dmic-codec\n");
return PTR_ERR(priv->dmic_codec_dev);
}
} else { } else {
num_links = 1; num_links = 1;
} }
...@@ -299,16 +290,14 @@ static int omap_abe_probe(struct platform_device *pdev) ...@@ -299,16 +290,14 @@ static int omap_abe_probe(struct platform_device *pdev)
of_property_read_u32(node, "ti,mclk-freq", &priv->mclk_freq); of_property_read_u32(node, "ti,mclk-freq", &priv->mclk_freq);
if (!priv->mclk_freq) { if (!priv->mclk_freq) {
dev_err(&pdev->dev, "MCLK frequency not provided\n"); dev_err(&pdev->dev, "MCLK frequency not provided\n");
ret = -EINVAL; return -EINVAL;
goto err_unregister;
} }
card->fully_routed = 1; card->fully_routed = 1;
if (!priv->mclk_freq) { if (!priv->mclk_freq) {
dev_err(&pdev->dev, "MCLK frequency missing\n"); dev_err(&pdev->dev, "MCLK frequency missing\n");
ret = -ENODEV; return -ENODEV;
goto err_unregister;
} }
card->dai_link = abe_twl6040_dai_links; card->dai_link = abe_twl6040_dai_links;
...@@ -317,17 +306,9 @@ static int omap_abe_probe(struct platform_device *pdev) ...@@ -317,17 +306,9 @@ static int omap_abe_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(card, priv); snd_soc_card_set_drvdata(card, priv);
ret = snd_soc_register_card(card); ret = snd_soc_register_card(card);
if (ret) { if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
goto err_unregister;
}
return 0;
err_unregister:
if (!IS_ERR(priv->dmic_codec_dev))
platform_device_unregister(priv->dmic_codec_dev);
return ret; return ret;
} }
...@@ -335,13 +316,9 @@ static int omap_abe_probe(struct platform_device *pdev) ...@@ -335,13 +316,9 @@ static int omap_abe_probe(struct platform_device *pdev)
static int omap_abe_remove(struct platform_device *pdev) static int omap_abe_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev); struct snd_soc_card *card = platform_get_drvdata(pdev);
struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card); snd_soc_unregister_card(card);
if (!IS_ERR(priv->dmic_codec_dev))
platform_device_unregister(priv->dmic_codec_dev);
return 0; return 0;
} }
...@@ -361,7 +338,33 @@ static struct platform_driver omap_abe_driver = { ...@@ -361,7 +338,33 @@ static struct platform_driver omap_abe_driver = {
.remove = omap_abe_remove, .remove = omap_abe_remove,
}; };
module_platform_driver(omap_abe_driver); static int __init omap_abe_init(void)
{
int ret;
dmic_codec_dev = platform_device_register_simple("dmic-codec", -1, NULL,
0);
if (IS_ERR(dmic_codec_dev)) {
pr_err("%s: dmic-codec device registration failed\n", __func__);
return PTR_ERR(dmic_codec_dev);
}
ret = platform_driver_register(&omap_abe_driver);
if (ret) {
pr_err("%s: platform driver registration failed\n", __func__);
platform_device_unregister(dmic_codec_dev);
}
return ret;
}
module_init(omap_abe_init);
static void __exit omap_abe_exit(void)
{
platform_driver_unregister(&omap_abe_driver);
platform_device_unregister(dmic_codec_dev);
}
module_exit(omap_abe_exit);
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec"); MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec");
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/clk.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of_device.h> #include <linux/of_device.h>
...@@ -55,7 +54,6 @@ struct omap_mcpdm { ...@@ -55,7 +54,6 @@ struct omap_mcpdm {
unsigned long phys_base; unsigned long phys_base;
void __iomem *io_base; void __iomem *io_base;
int irq; int irq;
struct clk *pdmclk;
struct mutex mutex; struct mutex mutex;
...@@ -390,15 +388,14 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) ...@@ -390,15 +388,14 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
int ret; int ret;
clk_prepare_enable(mcpdm->pdmclk);
pm_runtime_enable(mcpdm->dev); pm_runtime_enable(mcpdm->dev);
/* Disable lines while request is ongoing */ /* Disable lines while request is ongoing */
pm_runtime_get_sync(mcpdm->dev); pm_runtime_get_sync(mcpdm->dev);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler, ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 0, "McPDM",
0, "McPDM", (void *)mcpdm); (void *)mcpdm);
pm_runtime_put_sync(mcpdm->dev); pm_runtime_put_sync(mcpdm->dev);
...@@ -423,9 +420,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) ...@@ -423,9 +420,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
{ {
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
free_irq(mcpdm->irq, (void *)mcpdm);
pm_runtime_disable(mcpdm->dev); pm_runtime_disable(mcpdm->dev);
clk_disable_unprepare(mcpdm->pdmclk);
return 0; return 0;
} }
...@@ -445,8 +442,6 @@ static int omap_mcpdm_suspend(struct snd_soc_dai *dai) ...@@ -445,8 +442,6 @@ static int omap_mcpdm_suspend(struct snd_soc_dai *dai)
mcpdm->pm_active_count++; mcpdm->pm_active_count++;
} }
clk_disable_unprepare(mcpdm->pdmclk);
return 0; return 0;
} }
...@@ -454,8 +449,6 @@ static int omap_mcpdm_resume(struct snd_soc_dai *dai) ...@@ -454,8 +449,6 @@ static int omap_mcpdm_resume(struct snd_soc_dai *dai)
{ {
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
clk_prepare_enable(mcpdm->pdmclk);
if (mcpdm->pm_active_count) { if (mcpdm->pm_active_count) {
while (mcpdm->pm_active_count--) while (mcpdm->pm_active_count--)
pm_runtime_get_sync(mcpdm->dev); pm_runtime_get_sync(mcpdm->dev);
...@@ -549,15 +542,6 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) ...@@ -549,15 +542,6 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
mcpdm->dev = &pdev->dev; mcpdm->dev = &pdev->dev;
mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk");
if (IS_ERR(mcpdm->pdmclk)) {
if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n",
PTR_ERR(mcpdm->pdmclk));
mcpdm->pdmclk = NULL;
}
ret = devm_snd_soc_register_component(&pdev->dev, ret = devm_snd_soc_register_component(&pdev->dev,
&omap_mcpdm_component, &omap_mcpdm_component,
&omap_mcpdm_dai, 1); &omap_mcpdm_dai, 1);
......
...@@ -58,10 +58,12 @@ static struct platform_device *s3c24xx_uda134x_snd_device; ...@@ -58,10 +58,12 @@ static struct platform_device *s3c24xx_uda134x_snd_device;
static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
{ {
int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
#ifdef ENFORCE_RATES #ifdef ENFORCE_RATES
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
#endif #endif
int ret = 0;
mutex_lock(&clk_lock); mutex_lock(&clk_lock);
pr_debug("%s %d\n", __func__, clk_users); pr_debug("%s %d\n", __func__, clk_users);
...@@ -71,8 +73,7 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) ...@@ -71,8 +73,7 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
printk(KERN_ERR "%s cannot get xtal\n", __func__); printk(KERN_ERR "%s cannot get xtal\n", __func__);
ret = PTR_ERR(xtal); ret = PTR_ERR(xtal);
} else { } else {
pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, pclk = clk_get(cpu_dai->dev, "iis");
"pclk");
if (IS_ERR(pclk)) { if (IS_ERR(pclk)) {
printk(KERN_ERR "%s cannot get pclk\n", printk(KERN_ERR "%s cannot get pclk\n",
__func__); __func__);
......
...@@ -226,8 +226,12 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, ...@@ -226,8 +226,12 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
ifscr = 0; ifscr = 0;
fsrate = 0; fsrate = 0;
if (fin != fout) { if (fin != fout) {
u64 n;
ifscr = 1; ifscr = 1;
fsrate = 0x0400000 / fout * fin; n = (u64)0x0400000 * fin;
do_div(n, fout);
fsrate = n;
} }
/* /*
......
...@@ -121,7 +121,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) ...@@ -121,7 +121,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
dpcm_be_disconnect(fe, stream); dpcm_be_disconnect(fe, stream);
fe->dpcm[stream].runtime = NULL; fe->dpcm[stream].runtime = NULL;
goto fe_err; goto path_err;
} }
dpcm_clear_pending_state(fe, stream); dpcm_clear_pending_state(fe, stream);
...@@ -136,6 +136,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) ...@@ -136,6 +136,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
return 0; return 0;
path_err:
dpcm_path_put(&list);
fe_err: fe_err:
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown) if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
fe->dai_link->compr_ops->shutdown(cstream); fe->dai_link->compr_ops->shutdown(cstream);
......
...@@ -1056,7 +1056,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, ...@@ -1056,7 +1056,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
if (!rtd->platform) { if (!rtd->platform) {
dev_err(card->dev, "ASoC: platform %s not registered\n", dev_err(card->dev, "ASoC: platform %s not registered\n",
dai_link->platform_name); dai_link->platform_name);
return -EPROBE_DEFER; goto _err_defer;
} }
soc_add_pcm_runtime(card, rtd); soc_add_pcm_runtime(card, rtd);
...@@ -2083,14 +2083,13 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card) ...@@ -2083,14 +2083,13 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
/* remove auxiliary devices */ /* remove auxiliary devices */
soc_remove_aux_devices(card); soc_remove_aux_devices(card);
snd_soc_dapm_free(&card->dapm);
soc_cleanup_card_debugfs(card); soc_cleanup_card_debugfs(card);
/* remove the card */ /* remove the card */
if (card->remove) if (card->remove)
card->remove(card); card->remove(card);
snd_soc_dapm_free(&card->dapm);
snd_card_free(card->snd_card); snd_card_free(card->snd_card);
return 0; return 0;
......
...@@ -3493,6 +3493,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, ...@@ -3493,6 +3493,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
const struct snd_soc_pcm_stream *config = w->params + w->params_select; const struct snd_soc_pcm_stream *config = w->params + w->params_select;
struct snd_pcm_substream substream; struct snd_pcm_substream substream;
struct snd_pcm_hw_params *params = NULL; struct snd_pcm_hw_params *params = NULL;
struct snd_pcm_runtime *runtime = NULL;
u64 fmt; u64 fmt;
int ret; int ret;
...@@ -3541,6 +3542,14 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, ...@@ -3541,6 +3542,14 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
memset(&substream, 0, sizeof(substream)); memset(&substream, 0, sizeof(substream));
/* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
if (!runtime) {
ret = -ENOMEM;
goto out;
}
substream.runtime = runtime;
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
substream.stream = SNDRV_PCM_STREAM_CAPTURE; substream.stream = SNDRV_PCM_STREAM_CAPTURE;
...@@ -3606,6 +3615,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, ...@@ -3606,6 +3615,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
} }
out: out:
kfree(runtime);
kfree(params); kfree(params);
return ret; return ret;
} }
......
...@@ -55,7 +55,6 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol, ...@@ -55,7 +55,6 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE); err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE);
if (err < 0) { if (err < 0) {
line6pcm->impulse_volume = 0; line6pcm->impulse_volume = 0;
line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
return err; return err;
} }
} else { } else {
...@@ -211,7 +210,9 @@ static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction, ...@@ -211,7 +210,9 @@ static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction,
spin_lock_irqsave(&pstr->lock, flags); spin_lock_irqsave(&pstr->lock, flags);
clear_bit(type, &pstr->running); clear_bit(type, &pstr->running);
if (!pstr->running) { if (!pstr->running) {
spin_unlock_irqrestore(&pstr->lock, flags);
line6_unlink_audio_urbs(line6pcm, pstr); line6_unlink_audio_urbs(line6pcm, pstr);
spin_lock_irqsave(&pstr->lock, flags);
if (direction == SNDRV_PCM_STREAM_CAPTURE) { if (direction == SNDRV_PCM_STREAM_CAPTURE) {
line6pcm->prev_fbuf = NULL; line6pcm->prev_fbuf = NULL;
line6pcm->prev_fsize = 0; line6pcm->prev_fsize = 0;
......
...@@ -244,8 +244,8 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, ...@@ -244,8 +244,8 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
static ssize_t serial_number_show(struct device *dev, static ssize_t serial_number_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct usb_interface *interface = to_usb_interface(dev); struct snd_card *card = dev_to_snd_card(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface); struct usb_line6_pod *pod = card->private_data;
return sprintf(buf, "%u\n", pod->serial_number); return sprintf(buf, "%u\n", pod->serial_number);
} }
...@@ -256,8 +256,8 @@ static ssize_t serial_number_show(struct device *dev, ...@@ -256,8 +256,8 @@ static ssize_t serial_number_show(struct device *dev,
static ssize_t firmware_version_show(struct device *dev, static ssize_t firmware_version_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct usb_interface *interface = to_usb_interface(dev); struct snd_card *card = dev_to_snd_card(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface); struct usb_line6_pod *pod = card->private_data;
return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100, return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
pod->firmware_version % 100); pod->firmware_version % 100);
...@@ -269,8 +269,8 @@ static ssize_t firmware_version_show(struct device *dev, ...@@ -269,8 +269,8 @@ static ssize_t firmware_version_show(struct device *dev,
static ssize_t device_id_show(struct device *dev, static ssize_t device_id_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct usb_interface *interface = to_usb_interface(dev); struct snd_card *card = dev_to_snd_card(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface); struct usb_line6_pod *pod = card->private_data;
return sprintf(buf, "%d\n", pod->device_id); return sprintf(buf, "%d\n", pod->device_id);
} }
......
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