sound fixes for 4.9-rc5

this became a largish pull-request, as we've got a bunch of pending
 ASoC fixes at this time.  One noticeable change is the removal of
 error directive in uapi/sound/asoc.h.  We found that the API has
 been already used on Chromebooks, so we need to support it even now.
 
 A slight big LOC is found in Qualcomm lpass driver, but the rest are
 all small and easy fixes for ASoC drivers (sti, sun4i, Realtek codecs,
 Intel, tas571x, etc) in addition to the patches to harden the ALSA
 core proc file accesses.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABAgAGBQJYI3I4AAoJEGwxgFQ9KSmkgEMP/iGW/7T2AqD39pKtmfXH60gt
 hU9ccBt+gSrKqyMZHjrqp69o2//9JSsx6ezJXAWm5OeDwPJCxwSBIy2fGzxBZDwW
 0nhYbeoZFQbQucCTDLRO33n0xe7YIMtjp9H55PBBoaWKDdDoRiOdsKIRSFWToV2Q
 IOPY3pvYUP8RzYA2GC9Ud5xDb0U/J3je7PGhwM880sBlOxykTJJwrq95tG8EGIF8
 CAj/B/IJw0SuA79RDjBSziT9xAfHjiky4wYTw7HcjgBStLv3R2txM3775Cvhsnwr
 ISdXmh2ImibCh5ADIivXoNTkptq0mTurWi/6W1fENqZVxaAh7/MsWjlVKfAmgUKT
 kTRgLJLZIQ/P0ejKnbRI2+K4z0iLcF4w4GURi3iwEOKuvX1jDN/F9pte/ZCB3BIw
 IKxRZ2ClWAdlpPt/reNNH3fKICguLlktoZWUkZm1rVZ2ACieQVMmodYjIMP0egXr
 EHus0Pp+B9U3prvncGKSIG9+/8XFBdYh++811cVkT78W2nBmy9VjvbA2iBTo1Yzj
 mWzpU/Zp+wC44TyMHP+AtZj+XsAM0l0gQRMUKoMe1RTdOmBleGsiGaN/V9kTuX0S
 bHbPV1CKnfw/4mQDc9BGuVC6xz/kS3xgqqUscdIf0flN7/kYJbzOJlz2fM/svP7z
 w0yH9d7pvEGKJTqLlyOm
 =jmAA
 -----END PGP SIGNATURE-----

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

Pull sound fixes from Takashi Iwai:
 "This became a largish pull-request, as we've got a bunch of pending
  ASoC fixes at this time. One noticeable change is the removal of error
  directive in uapi/sound/asoc.h. We found that the API has been already
  used on Chromebooks, so we need to support it even now.

  A slight big LOC is found in Qualcomm lpass driver, but the rest are
  all small and easy fixes for ASoC drivers (sti, sun4i, Realtek codecs,
  Intel, tas571x, etc) in addition to the patches to harden the ALSA
  core proc file accesses"

* tag 'sound-4.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (26 commits)
  ALSA: info: Return error for invalid read/write
  ALSA: info: Limit the proc text input size
  ASoC: samsung: spdif: Fix DMA filter initialization
  ASoC: sun4i-codec: Enable bus clock after getting GPIO
  ASoC: lpass-cpu: add module licence and description
  ASoC: lpass-platform: Fix broken pcm data usage
  ASoC: sun4i-codec: return error code instead of NULL when create_card fails
  ASoC: hdmi-codec: Fix hdmi_of_xlate_dai_name when #sound-dai-cells = <0>
  ASoC: samsung: get access to DMA engine early to defer probe properly
  ASoC: da7219: Connect output enable register to DAIOUT
  ASoC: Intel: Skylake: Fix to turn off hdmi power on probe failure
  ASoC: sti-sas: enable fast io for regmap
  ASoC: sti: fix channel status update after playback start
  ASoC: PXA: Brownstone needs I2C
  ASoC: Intel: Skylake: Always acquire runtime pm ref on unload
  ASoC: Intel: Atom: add terminate entry for dmi_system_id tables
  ASoC: rt298: fix jack type detect error
  ASoC: rt5663: fix a debug statement
  ASoC: cs4270: fix DAPM stream name mismatch
  ASoC: Intel: haswell depends on sst-firmware
  ...
This commit is contained in:
Linus Torvalds 2016-11-09 11:39:02 -08:00
commit 27bcd37e02
25 changed files with 199 additions and 197 deletions

View File

@ -18,12 +18,6 @@
#include <linux/types.h>
#include <sound/asound.h>
#ifndef __KERNEL__
#error This API is an early revision and not enabled in the current
#error kernel release, it will be enabled in a future kernel version
#error with incompatible changes to what is here.
#endif
/*
* Maximum number of channels topology kcontrol can represent.
*/

View File

@ -325,10 +325,15 @@ static ssize_t snd_info_text_entry_write(struct file *file,
size_t next;
int err = 0;
if (!entry->c.text.write)
return -EIO;
pos = *offset;
if (!valid_pos(pos, count))
return -EIO;
next = pos + count;
/* don't handle too large text inputs */
if (next > 16 * 1024)
return -EIO;
mutex_lock(&entry->access);
buf = data->wbuffer;
if (!buf) {
@ -366,7 +371,9 @@ static int snd_info_seq_show(struct seq_file *seq, void *p)
struct snd_info_private_data *data = seq->private;
struct snd_info_entry *entry = data->entry;
if (entry->c.text.read) {
if (!entry->c.text.read) {
return -EIO;
} else {
data->rbuffer->buffer = (char *)seq; /* XXX hack! */
entry->c.text.read(entry, data->rbuffer);
}

View File

@ -148,11 +148,11 @@ SND_SOC_DAPM_OUTPUT("AOUTR"),
};
static const struct snd_soc_dapm_route cs4270_dapm_routes[] = {
{ "Capture", NULL, "AINA" },
{ "Capture", NULL, "AINB" },
{ "Capture", NULL, "AINL" },
{ "Capture", NULL, "AINR" },
{ "AOUTA", NULL, "Playback" },
{ "AOUTB", NULL, "Playback" },
{ "AOUTL", NULL, "Playback" },
{ "AOUTR", NULL, "Playback" },
};
/**

View File

@ -880,7 +880,8 @@ static const struct snd_soc_dapm_widget da7219_dapm_widgets[] = {
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
/* DAI */
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7219_DAI_TDM_CTRL,
DA7219_DAI_OE_SHIFT, DA7219_NO_INVERT),
SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
/* Output Muxes */

View File

@ -364,7 +364,12 @@ static int hdmi_of_xlate_dai_name(struct snd_soc_component *component,
struct of_phandle_args *args,
const char **dai_name)
{
int id = args->args[0];
int id;
if (args->args_count)
id = args->args[0];
else
id = 0;
if (id < ARRAY_SIZE(hdmi_dai_name)) {
*dai_name = hdmi_dai_name[id];

View File

@ -249,6 +249,11 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
snd_soc_dapm_force_enable_pin(dapm, "LDO1");
snd_soc_dapm_sync(dapm);
regmap_update_bits(rt298->regmap,
RT298_POWER_CTRL1, 0x1001, 0);
regmap_update_bits(rt298->regmap,
RT298_POWER_CTRL2, 0x4, 0x4);
regmap_write(rt298->regmap, RT298_SET_MIC1, 0x24);
msleep(50);

View File

@ -1547,11 +1547,11 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
msleep(sleep_time[i]);
val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) &
0x0003;
dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n",
__func__, val, sleep_time[i]);
i++;
if (val == 0x1 || val == 0x2 || val == 0x3)
break;
dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n",
__func__, val, sleep_time[i]);
}
dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
switch (val) {

View File

@ -424,7 +424,7 @@ static const struct snd_soc_dai_ops stih407_dac_ops = {
static const struct regmap_config stih407_sas_regmap = {
.reg_bits = 32,
.val_bits = 32,
.fast_io = true,
.max_register = STIH407_AUDIO_DAC_CTRL,
.reg_defaults = stih407_sas_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(stih407_sas_reg_defaults),

View File

@ -341,20 +341,9 @@ static int tas571x_set_bias_level(struct snd_soc_codec *codec,
return ret;
}
}
gpiod_set_value(priv->pdn_gpio, 0);
usleep_range(5000, 6000);
regcache_cache_only(priv->regmap, false);
ret = regcache_sync(priv->regmap);
if (ret)
return ret;
}
break;
case SND_SOC_BIAS_OFF:
regcache_cache_only(priv->regmap, true);
gpiod_set_value(priv->pdn_gpio, 1);
if (!IS_ERR(priv->mclk))
clk_disable_unprepare(priv->mclk);
break;
@ -401,16 +390,6 @@ static const struct snd_kcontrol_new tas5711_controls[] = {
TAS571X_SOFT_MUTE_REG,
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
1, 1),
SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",
TAS5717_CH1_LEFT_CH_MIX_REG,
TAS5717_CH1_RIGHT_CH_MIX_REG,
16, 0, 0x80, 0),
SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",
TAS5717_CH2_LEFT_CH_MIX_REG,
TAS5717_CH2_RIGHT_CH_MIX_REG,
16, 0, 0x80, 0),
};
static const struct regmap_range tas571x_readonly_regs_range[] = {
@ -488,6 +467,16 @@ static const struct snd_kcontrol_new tas5717_controls[] = {
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
1, 1),
SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",
TAS5717_CH1_LEFT_CH_MIX_REG,
TAS5717_CH1_RIGHT_CH_MIX_REG,
16, 0, 0x80, 0),
SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",
TAS5717_CH2_LEFT_CH_MIX_REG,
TAS5717_CH2_RIGHT_CH_MIX_REG,
16, 0, 0x80, 0),
/*
* The biquads are named according to the register names.
* Please note that TI's TAS57xx Graphical Development Environment
@ -747,13 +736,14 @@ static int tas571x_i2c_probe(struct i2c_client *client,
/* pulse the active low reset line for ~100us */
usleep_range(100, 200);
gpiod_set_value(priv->reset_gpio, 0);
usleep_range(12000, 20000);
usleep_range(13500, 20000);
}
ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);
if (ret)
return ret;
usleep_range(50000, 60000);
memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
priv->codec_driver.component_driver.controls = priv->chip->controls;
@ -770,9 +760,6 @@ static int tas571x_i2c_probe(struct i2c_client *client,
return ret;
}
regcache_cache_only(priv->regmap, true);
gpiod_set_value(priv->pdn_gpio, 1);
return snd_soc_register_codec(&client->dev, &priv->codec_driver,
&tas571x_dai, 1);
}

View File

@ -47,6 +47,7 @@ config SND_SOC_INTEL_SST_MATCH
config SND_SOC_INTEL_HASWELL
tristate
select SND_SOC_INTEL_SST_FIRMWARE
config SND_SOC_INTEL_BAYTRAIL
tristate
@ -56,7 +57,6 @@ config SND_SOC_INTEL_HASWELL_MACH
depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
depends on DW_DMAC_CORE
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SST_FIRMWARE
select SND_SOC_INTEL_HASWELL
select SND_SOC_RT5640
help
@ -138,7 +138,6 @@ config SND_SOC_INTEL_BROADWELL_MACH
I2C_DESIGNWARE_PLATFORM
depends on DW_DMAC_CORE
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SST_FIRMWARE
select SND_SOC_INTEL_HASWELL
select SND_SOC_RT286
help

View File

@ -416,6 +416,7 @@ static const struct dmi_system_id cht_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
},
},
{ }
};

View File

@ -130,8 +130,8 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
*/
ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3, &broxton_headset,
NULL, 0);
SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
&broxton_headset, NULL, 0);
if (ret) {
dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
return ret;

View File

@ -674,7 +674,7 @@ static int skl_probe(struct pci_dev *pci,
if (skl->nhlt == NULL) {
err = -ENODEV;
goto out_free;
goto out_display_power_off;
}
skl_nhlt_update_topology_bin(skl);
@ -746,6 +746,9 @@ out_mach_free:
skl_machine_device_unregister(skl);
out_nhlt_free:
skl_nhlt_free(skl->nhlt);
out_display_power_off:
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
snd_hdac_display_power(bus, false);
out_free:
skl->init_failed = 1;
skl_free(ebus);
@ -785,8 +788,7 @@ static void skl_remove(struct pci_dev *pci)
release_firmware(skl->tplg);
if (pci_dev_run_wake(pci))
pm_runtime_get_noresume(&pci->dev);
pm_runtime_get_noresume(&pci->dev);
/* codec removal, invoke bus_device_remove */
snd_hdac_ext_bus_device_remove(ebus);

View File

@ -208,7 +208,7 @@ config SND_PXA2XX_SOC_IMOTE2
config SND_MMP_SOC_BROWNSTONE
tristate "SoC Audio support for Marvell Brownstone"
depends on SND_MMP_SOC && MACH_BROWNSTONE
depends on SND_MMP_SOC && MACH_BROWNSTONE && I2C
select SND_MMP_SOC_SSPA
select MFD_WM8994
select SND_SOC_WM8994

View File

@ -586,3 +586,6 @@ int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev)
return 0;
}
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_remove);
MODULE_DESCRIPTION("QTi LPASS CPU Driver");
MODULE_LICENSE("GPL v2");

View File

@ -61,7 +61,40 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
int ret;
struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_variant *v = drvdata->variant;
int ret, dma_ch, dir = substream->stream;
struct lpass_pcm_data *data;
data = devm_kzalloc(soc_runtime->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->i2s_port = cpu_dai->driver->id;
runtime->private_data = data;
if (v->alloc_dma_channel)
dma_ch = v->alloc_dma_channel(drvdata, dir);
if (dma_ch < 0)
return dma_ch;
drvdata->substream[dma_ch] = substream;
ret = regmap_write(drvdata->lpaif_map,
LPAIF_DMACTL_REG(v, dma_ch, dir), 0);
if (ret) {
dev_err(soc_runtime->dev,
"%s() error writing to rdmactl reg: %d\n",
__func__, ret);
return ret;
}
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
data->rdma_ch = dma_ch;
else
data->wrdma_ch = dma_ch;
snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);
@ -80,13 +113,40 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
return 0;
}
static int lpass_platform_pcmops_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_variant *v = drvdata->variant;
struct lpass_pcm_data *data;
int dma_ch, dir = substream->stream;
data = runtime->private_data;
v = drvdata->variant;
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
dma_ch = data->rdma_ch;
else
dma_ch = data->wrdma_ch;
drvdata->substream[dma_ch] = NULL;
if (v->free_dma_channel)
v->free_dma_channel(drvdata, dma_ch);
return 0;
}
static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_pcm_data *pcm_data = drvdata->private_data;
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
struct lpass_variant *v = drvdata->variant;
snd_pcm_format_t format = params_format(params);
unsigned int channels = params_channels(params);
@ -179,7 +239,8 @@ static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_pcm_data *pcm_data = drvdata->private_data;
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
struct lpass_variant *v = drvdata->variant;
unsigned int reg;
int ret;
@ -203,7 +264,8 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_pcm_data *pcm_data = drvdata->private_data;
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
struct lpass_variant *v = drvdata->variant;
int ret, ch, dir = substream->stream;
@ -257,7 +319,8 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_pcm_data *pcm_data = drvdata->private_data;
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
struct lpass_variant *v = drvdata->variant;
int ret, ch, dir = substream->stream;
@ -333,7 +396,8 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_pcm_data *pcm_data = drvdata->private_data;
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
struct lpass_variant *v = drvdata->variant;
unsigned int base_addr, curr_addr;
int ret, ch, dir = substream->stream;
@ -374,6 +438,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
static const struct snd_pcm_ops lpass_platform_pcm_ops = {
.open = lpass_platform_pcmops_open,
.close = lpass_platform_pcmops_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = lpass_platform_pcmops_hw_params,
.hw_free = lpass_platform_pcmops_hw_free,
@ -470,117 +535,45 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
{
struct snd_pcm *pcm = soc_runtime->pcm;
struct snd_pcm_substream *psubstream, *csubstream;
struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
struct lpass_variant *v = drvdata->variant;
int ret = -EINVAL;
struct lpass_pcm_data *data;
size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
data = devm_kzalloc(soc_runtime->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->i2s_port = cpu_dai->driver->id;
drvdata->private_data = data;
psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (psubstream) {
if (v->alloc_dma_channel)
data->rdma_ch = v->alloc_dma_channel(drvdata,
SNDRV_PCM_STREAM_PLAYBACK);
if (data->rdma_ch < 0)
return data->rdma_ch;
drvdata->substream[data->rdma_ch] = psubstream;
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
soc_runtime->platform->dev,
size, &psubstream->dma_buffer);
if (ret)
goto playback_alloc_err;
ret = regmap_write(drvdata->lpaif_map,
LPAIF_RDMACTL_REG(v, data->rdma_ch), 0);
if (ret) {
dev_err(soc_runtime->dev,
"%s() error writing to rdmactl reg: %d\n",
__func__, ret);
goto capture_alloc_err;
dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
return ret;
}
}
csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
if (csubstream) {
if (v->alloc_dma_channel)
data->wrdma_ch = v->alloc_dma_channel(drvdata,
SNDRV_PCM_STREAM_CAPTURE);
if (data->wrdma_ch < 0) {
ret = data->wrdma_ch;
goto capture_alloc_err;
}
drvdata->substream[data->wrdma_ch] = csubstream;
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
soc_runtime->platform->dev,
size, &csubstream->dma_buffer);
if (ret)
goto capture_alloc_err;
ret = regmap_write(drvdata->lpaif_map,
LPAIF_WRDMACTL_REG(v, data->wrdma_ch), 0);
if (ret) {
dev_err(soc_runtime->dev,
"%s() error writing to wrdmactl reg: %d\n",
__func__, ret);
goto capture_reg_err;
dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
if (psubstream)
snd_dma_free_pages(&psubstream->dma_buffer);
return ret;
}
}
return 0;
capture_reg_err:
if (csubstream)
snd_dma_free_pages(&csubstream->dma_buffer);
capture_alloc_err:
if (psubstream)
snd_dma_free_pages(&psubstream->dma_buffer);
playback_alloc_err:
dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
return ret;
}
static void lpass_platform_pcm_free(struct snd_pcm *pcm)
{
struct snd_soc_pcm_runtime *rt;
struct lpass_data *drvdata;
struct lpass_pcm_data *data;
struct lpass_variant *v;
struct snd_pcm_substream *substream;
int ch, i;
int i;
for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
substream = pcm->streams[i].substream;
if (substream) {
rt = substream->private_data;
drvdata = snd_soc_platform_get_drvdata(rt->platform);
data = drvdata->private_data;
ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
? data->rdma_ch
: data->wrdma_ch;
v = drvdata->variant;
drvdata->substream[ch] = NULL;
if (v->free_dma_channel)
v->free_dma_channel(drvdata, ch);
snd_dma_free_pages(&substream->dma_buffer);
substream->dma_buffer.area = NULL;
substream->dma_buffer.addr = 0;

View File

@ -59,7 +59,6 @@ struct lpass_data {
struct clk *pcnoc_mport_clk;
struct clk *pcnoc_sway_clk;
void *private_data;
};
/* Vairant data per each SOC */

View File

@ -383,11 +383,6 @@ static int s3c_ac97_probe(struct platform_device *pdev)
goto err4;
}
ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
if (ret)
goto err5;
ret = samsung_asoc_dma_platform_register(&pdev->dev,
ac97_pdata->dma_filter,
NULL, NULL);
@ -396,6 +391,11 @@ static int s3c_ac97_probe(struct platform_device *pdev)
goto err5;
}
ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
if (ret)
goto err5;
return 0;
err5:
free_irq(irq_res->start, NULL);

View File

@ -1237,14 +1237,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Unable to get drvdata\n");
return -EFAULT;
}
ret = devm_snd_soc_register_component(&sec_dai->pdev->dev,
&samsung_i2s_component,
&sec_dai->i2s_dai_drv, 1);
ret = samsung_asoc_dma_platform_register(&pdev->dev,
sec_dai->filter, "tx-sec", NULL);
if (ret != 0)
return ret;
return samsung_asoc_dma_platform_register(&pdev->dev,
sec_dai->filter, "tx-sec", NULL);
return devm_snd_soc_register_component(&sec_dai->pdev->dev,
&samsung_i2s_component,
&sec_dai->i2s_dai_drv, 1);
}
pri_dai = i2s_alloc_dai(pdev, false);
@ -1314,6 +1314,11 @@ static int samsung_i2s_probe(struct platform_device *pdev)
if (quirks & QUIRK_PRI_6CHAN)
pri_dai->i2s_dai_drv.playback.channels_max = 6;
ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
NULL, NULL);
if (ret < 0)
goto err_disable_clk;
if (quirks & QUIRK_SEC_DAI) {
sec_dai = i2s_alloc_dai(pdev, true);
if (!sec_dai) {
@ -1353,10 +1358,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
if (ret < 0)
goto err_free_dai;
ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
NULL, NULL);
if (ret < 0)
goto err_free_dai;
pm_runtime_enable(&pdev->dev);

View File

@ -565,15 +565,6 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
pm_runtime_enable(&pdev->dev);
ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component,
&s3c_pcm_dai[pdev->id], 1);
if (ret != 0) {
dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
goto err5;
}
ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
NULL, NULL);
if (ret) {
@ -581,8 +572,18 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
goto err5;
}
return 0;
pm_runtime_enable(&pdev->dev);
ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component,
&s3c_pcm_dai[pdev->id], 1);
if (ret != 0) {
dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
goto err6;
}
return 0;
err6:
pm_runtime_disable(&pdev->dev);
err5:
clk_disable_unprepare(pcm->pclk);
err4:

View File

@ -168,19 +168,19 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD;
s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
ret = s3c_i2sv2_register_component(&pdev->dev, -1,
&s3c2412_i2s_component,
&s3c2412_i2s_dai);
if (ret) {
pr_err("failed to register the dai\n");
return ret;
}
ret = samsung_asoc_dma_platform_register(&pdev->dev,
pdata->dma_filter,
NULL, NULL);
if (ret)
if (ret) {
pr_err("failed to register the DMA: %d\n", ret);
return ret;
}
ret = s3c_i2sv2_register_component(&pdev->dev, -1,
&s3c2412_i2s_component,
&s3c2412_i2s_dai);
if (ret)
pr_err("failed to register the dai\n");
return ret;
}

View File

@ -474,18 +474,18 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
ret = devm_snd_soc_register_component(&pdev->dev,
&s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
if (ret) {
pr_err("failed to register the dai\n");
return ret;
}
ret = samsung_asoc_dma_platform_register(&pdev->dev,
pdata->dma_filter,
NULL, NULL);
if (ret)
if (ret) {
pr_err("failed to register the dma: %d\n", ret);
return ret;
}
ret = devm_snd_soc_register_component(&pdev->dev,
&s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
if (ret)
pr_err("failed to register the dai\n");
return ret;
}

View File

@ -416,15 +416,6 @@ static int spdif_probe(struct platform_device *pdev)
goto err3;
}
dev_set_drvdata(&pdev->dev, spdif);
ret = devm_snd_soc_register_component(&pdev->dev,
&samsung_spdif_component, &samsung_spdif_dai, 1);
if (ret != 0) {
dev_err(&pdev->dev, "fail to register dai\n");
goto err4;
}
spdif_stereo_out.addr_width = 2;
spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF;
filter = NULL;
@ -432,7 +423,6 @@ static int spdif_probe(struct platform_device *pdev)
spdif_stereo_out.filter_data = spdif_pdata->dma_playback;
filter = spdif_pdata->dma_filter;
}
spdif->dma_playback = &spdif_stereo_out;
ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
@ -442,6 +432,15 @@ static int spdif_probe(struct platform_device *pdev)
goto err4;
}
dev_set_drvdata(&pdev->dev, spdif);
ret = devm_snd_soc_register_component(&pdev->dev,
&samsung_spdif_component, &samsung_spdif_dai, 1);
if (ret != 0) {
dev_err(&pdev->dev, "fail to register dai\n");
goto err4;
}
return 0;
err4:
iounmap(spdif->regs);

View File

@ -614,7 +614,11 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
iec958->status[3] = ucontrol->value.iec958.status[3];
mutex_unlock(&player->ctrl_lock);
uni_player_set_channel_status(player, NULL);
if (player->substream && player->substream->runtime)
uni_player_set_channel_status(player,
player->substream->runtime);
else
uni_player_set_channel_status(player, NULL);
return 0;
}

View File

@ -765,11 +765,11 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
if (!card)
return NULL;
return ERR_PTR(-ENOMEM);
card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
if (!card->dai_link)
return NULL;
return ERR_PTR(-ENOMEM);
card->dev = dev;
card->name = "sun4i-codec";
@ -829,12 +829,6 @@ static int sun4i_codec_probe(struct platform_device *pdev)
return PTR_ERR(scodec->clk_module);
}
/* Enable the bus clock */
if (clk_prepare_enable(scodec->clk_apb)) {
dev_err(&pdev->dev, "Failed to enable the APB clock\n");
return -EINVAL;
}
scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
GPIOD_OUT_LOW);
if (IS_ERR(scodec->gpio_pa)) {
@ -844,6 +838,12 @@ static int sun4i_codec_probe(struct platform_device *pdev)
return ret;
}
/* Enable the bus clock */
if (clk_prepare_enable(scodec->clk_apb)) {
dev_err(&pdev->dev, "Failed to enable the APB clock\n");
return -EINVAL;
}
/* DMA configuration for TX FIFO */
scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
scodec->playback_dma_data.maxburst = 4;
@ -876,7 +876,8 @@ static int sun4i_codec_probe(struct platform_device *pdev)
}
card = sun4i_codec_create_card(&pdev->dev);
if (!card) {
if (IS_ERR(card)) {
ret = PTR_ERR(card);
dev_err(&pdev->dev, "Failed to create our card\n");
goto err_unregister_codec;
}