ASoC: Fixes for v3.16

A bigger batch of changes than I would like as I didn't send any for a
 few weeks without noticing how many had built up.  They are almost all
 driver specific though, larger changes are:
 
  - Fixes to the newly added Baytrail/MAX98090 which look like some QA
    was missed on the microphone detection.
  - Deletion of some erroniously listed audio formats for Haswell.
  - Fix debugfs creation in the core so that we don't try to generate
    multiple directories with the same name, relatively large textually
    but simple to inspect by eye and test.
  - A couple of bugfixes for the rcar driver one of which which involves
    a bit of code motion to move initailisation of some hardware out of
    common paths into device specific ones.
  - Ensure both channels are powered up for mono outputs on Arizona
    devices, involving some simple data tables listing the outputs and a
    loop over them.
  - A couple of fixes to save and restore information on suspended and
    idle Samsung I2S controllers.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJTzafVAAoJELSic+t+oim9Vc8P/i3uOg6gc29twadHjPRxAQtH
 SYoL54ZB8Uu1yhODkKY3OoWNTGLT0RnCLnvtV4n7nGEAYLNcVmMFk8bHdrAocK0v
 2dfoo3bBgvnHsqDr2FO1c/qAXJ5UtQcIsib1lSynsgTOQSidio19yhJ6AE+wbLDQ
 WkfSuM2uqDI0SB3FYLvMYlV23j3mO/cVeYAa+fnjNJ769NijXGF9PJTals8XMYXi
 spvIJIjt8Z0J/WYKEtOx8zTVGFYlJ2hImWIm2Zbph1MlwEcclc1kcY/3xpMz8Rug
 fBb/h+aVkolV5I9uLOl+woGXZyzZbP4ConOnUWtyDn8kKmQx/TBybl4ZdD1ji8Dx
 VEvVRPAjnhb4y4ENSY1XTFGqrPHDCBp2WyR2X2Gb12hFjMQIceZwZ1wTfXMNALFN
 JSBkNjlxZf8GliGT5MUlqnfjzYLnlHcDW1EQLJLwrqga3lofvJIlqsI2hwoEC2CO
 9kHxJhJbwpkN8AArHT+Sgpds3EuIVTXlhdPUIvrlJvn8Xw0CQ8YTvT7R/dIna/NK
 44shkS6YXbWWSstaqAonl30ntiMVaRO97XZsrTUww+YAHkAZkNoCQMKf1pfHSyfN
 dKj3XAUe0x9daI/oar4S984FlQR24pdhw02B8eL1jNXFpn0cLKBCHaWogV8V/jMy
 8ioU3Qj7YPIlXI2haDZQ
 =aqRS
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v3.16-rc5' into asoc-linus

ASoC: Fixes for v3.16

A bigger batch of changes than I would like as I didn't send any for a
few weeks without noticing how many had built up.  They are almost all
driver specific though, larger changes are:

 - Fixes to the newly added Baytrail/MAX98090 which look like some QA
   was missed on the microphone detection.
 - Deletion of some erroniously listed audio formats for Haswell.
 - Fix debugfs creation in the core so that we don't try to generate
   multiple directories with the same name, relatively large textually
   but simple to inspect by eye and test.
 - A couple of bugfixes for the rcar driver one of which which involves
   a bit of code motion to move initailisation of some hardware out of
   common paths into device specific ones.
 - Ensure both channels are powered up for mono outputs on Arizona
   devices, involving some simple data tables listing the outputs and a
   loop over them.
 - A couple of fixes to save and restore information on suspended and
   idle Samsung I2S controllers.

# gpg: Signature made Tue 22 Jul 2014 00:52:53 BST using RSA key ID 7EA229BD
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg:                 aka "Mark Brown <broonie@debian.org>"
# gpg:                 aka "Mark Brown <broonie@kernel.org>"
# gpg:                 aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg:                 aka "Mark Brown <broonie@linaro.org>"
# gpg:                 aka "Mark Brown <Mark.Brown@linaro.org>"
This commit is contained in:
Mark Brown 2014-08-15 12:51:26 +01:00
commit 2fa4a285dd
24 changed files with 185 additions and 72 deletions

View File

@ -290,19 +290,19 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
unsigned int sample_size = runtime->sample_bits / 8;
void *buf = runtime->dma_area;
struct bf5xx_i2s_pcm_data *dma_data;
unsigned int offset, size;
unsigned int offset, samples;
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
if (dma_data->tdm_mode) {
offset = pos * 8 * sample_size;
size = count * 8 * sample_size;
samples = count * 8;
} else {
offset = frames_to_bytes(runtime, pos);
size = frames_to_bytes(runtime, count);
samples = count * runtime->channels;
}
snd_pcm_format_set_silence(runtime->format, buf + offset, size);
snd_pcm_format_set_silence(runtime->format, buf + offset, samples);
return 0;
}

View File

@ -230,8 +230,10 @@ static int adau1701_reg_read(void *context, unsigned int reg,
*value = 0;
for (i = 0; i < size; i++)
*value |= recv_buf[i] << (i * 8);
for (i = 0; i < size; i++) {
*value <<= 8;
*value |= recv_buf[i];
}
return 0;
}

View File

@ -243,6 +243,31 @@ int arizona_init_spk(struct snd_soc_codec *codec)
}
EXPORT_SYMBOL_GPL(arizona_init_spk);
static const struct snd_soc_dapm_route arizona_mono_routes[] = {
{ "OUT1R", NULL, "OUT1L" },
{ "OUT2R", NULL, "OUT2L" },
{ "OUT3R", NULL, "OUT3L" },
{ "OUT4R", NULL, "OUT4L" },
{ "OUT5R", NULL, "OUT5L" },
{ "OUT6R", NULL, "OUT6L" },
};
int arizona_init_mono(struct snd_soc_codec *codec)
{
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
int i;
for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
if (arizona->pdata.out_mono[i])
snd_soc_dapm_add_routes(&codec->dapm,
&arizona_mono_routes[i], 1);
}
return 0;
}
EXPORT_SYMBOL_GPL(arizona_init_mono);
int arizona_init_gpio(struct snd_soc_codec *codec)
{
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);

View File

@ -249,6 +249,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source,
extern int arizona_init_spk(struct snd_soc_codec *codec);
extern int arizona_init_gpio(struct snd_soc_codec *codec);
extern int arizona_init_mono(struct snd_soc_codec *codec);
extern int arizona_init_dai(struct arizona_priv *priv, int dai);

View File

@ -445,9 +445,9 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
CS42L56_HPA_VOLUME, 0, 0x44, 0x55, hl_tlv),
CS42L56_HPB_VOLUME, 0, 0x44, 0x55, hl_tlv),
SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
CS42L56_LOA_VOLUME, 0, 0x44, 0x55, hl_tlv),
CS42L56_LOB_VOLUME, 0, 0x44, 0x55, hl_tlv),
SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
0, 0x00, 1, tone_tlv),

View File

@ -2284,7 +2284,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
/* Register for interrupts */
dev_dbg(codec->dev, "irq = %d\n", max98090->irq);
ret = request_threaded_irq(max98090->irq, NULL,
ret = devm_request_threaded_irq(codec->dev, max98090->irq, NULL,
max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"max98090_interrupt", codec);
if (ret < 0) {

View File

@ -1277,7 +1277,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
return ret;
}
ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
if (ret)
goto err_ldo_remove;
@ -1285,13 +1285,16 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
if (ret)
goto err_ldo_remove;
goto err_regulator_free;
/* wait for all power rails bring up */
udelay(10);
return 0;
err_regulator_free:
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
err_ldo_remove:
if (!external_vddd)
ldo_regulator_remove(codec);
@ -1361,6 +1364,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
err:
regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
ldo_regulator_remove(codec);
return ret;
@ -1374,6 +1379,8 @@ static int sgtl5000_remove(struct snd_soc_codec *codec)
regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
ldo_regulator_remove(codec);
return 0;

View File

@ -879,7 +879,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_S20_3LE:
data |= (0x01 << 4);
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
data |= (0x02 << 4);
break;
case SNDRV_PCM_FORMAT_S32_LE:

View File

@ -1596,6 +1596,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
arizona_init_spk(codec);
arizona_init_gpio(codec);
arizona_init_mono(codec);
ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8);
if (ret != 0)

View File

@ -1758,3 +1758,5 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
return 0;
}
EXPORT_SYMBOL_GPL(wm_adsp2_init);
MODULE_LICENSE("GPL v2");

View File

@ -6,6 +6,7 @@ config SND_DAVINCI_SOC_I2S
tristate
config SND_DAVINCI_SOC_MCASP
depends on SND_DAVINCI_SOC || SND_OMAP_SOC
tristate
config SND_DAVINCI_SOC_VCIF

View File

@ -720,6 +720,10 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
case SNDRV_PCM_FORMAT_U24_LE:
case SNDRV_PCM_FORMAT_S24_LE:
dma_params->data_type = 4;
word_length = 24;
break;
case SNDRV_PCM_FORMAT_U32_LE:
case SNDRV_PCM_FORMAT_S32_LE:
dma_params->data_type = 4;
@ -1223,14 +1227,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err;
switch (mcasp->version) {
#if IS_BUILTIN(CONFIG_SND_DAVINCI_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
IS_MODULE(CONFIG_SND_DAVINCI_SOC))
case MCASP_VERSION_1:
case MCASP_VERSION_2:
case MCASP_VERSION_3:
ret = davinci_soc_platform_register(&pdev->dev);
break;
#endif
#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
(IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
IS_MODULE(CONFIG_SND_OMAP_SOC))
case MCASP_VERSION_4:
ret = omap_pcm_platform_register(&pdev->dev);
break;
#endif
default:
dev_err(&pdev->dev, "Invalid McASP version: %d\n",
mcasp->version);

View File

@ -106,7 +106,7 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
xcsr &= ~FSL_SAI_CSR_xF_MASK;
if (flags)
regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
out:
if (irq_none)
@ -371,10 +371,13 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
/* Check if the opposite FRDE is also disabled */
if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) {
/* Disable both directions and reset their FIFOs */
regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
FSL_SAI_CSR_TERE, 0);
FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
FSL_SAI_CSR_FR);
regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
FSL_SAI_CSR_TERE, 0);
FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
FSL_SAI_CSR_FR);
}
break;
default:

View File

@ -116,6 +116,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
{
struct device_node *node;
struct clk *clk;
u32 val;
int ret;
/*
@ -151,10 +152,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
}
dai->sysclk = clk_get_rate(clk);
} else if (of_property_read_bool(np, "system-clock-frequency")) {
of_property_read_u32(np,
"system-clock-frequency",
&dai->sysclk);
} else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
dai->sysclk = val;
} else {
clk = of_clk_get(node, 0);
if (!IS_ERR(clk))
@ -303,6 +302,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
{
struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
struct simple_dai_props *dai_props = priv->dai_props;
u32 val;
int ret;
/* parsing the card name from DT */
@ -325,8 +325,9 @@ static int asoc_simple_card_parse_of(struct device_node *node,
}
/* Factor to mclk, used in hw_params() */
of_property_read_u32(node, "simple-audio-card,mclk-fs",
&priv->mclk_fs);
ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val);
if (ret == 0)
priv->mclk_fs = val;
dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
priv->snd_card.name : "");

View File

@ -39,8 +39,7 @@ static const struct snd_soc_dapm_widget byt_max98090_widgets[] = {
static const struct snd_soc_dapm_route byt_max98090_audio_map[] = {
{"IN34", NULL, "Headset Mic"},
{"IN34", NULL, "MICBIAS"},
{"MICBIAS", NULL, "Headset Mic"},
{"Headset Mic", NULL, "MICBIAS"},
{"DMICL", NULL, "Int Mic"},
{"Headphone", NULL, "HPL"},
{"Headphone", NULL, "HPR"},
@ -84,7 +83,8 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = {
{
.name = "mic-gpio",
.idx = 1,
.report = SND_JACK_MICROPHONE | SND_JACK_LINEIN,
.invert = 1,
.report = SND_JACK_MICROPHONE,
.debounce_time = 200,
},
};
@ -108,7 +108,8 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
}
/* Enable jack detection */
ret = snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, jack);
ret = snd_soc_jack_new(codec, "Headset",
SND_JACK_LINEOUT | SND_JACK_HEADSET, jack);
if (ret)
return ret;
@ -117,13 +118,9 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
if (ret)
return ret;
ret = snd_soc_jack_add_gpiods(card->dev->parent, jack,
ARRAY_SIZE(hs_jack_gpios),
hs_jack_gpios);
if (ret)
return ret;
return max98090_mic_detect(codec, jack);
return snd_soc_jack_add_gpiods(card->dev->parent, jack,
ARRAY_SIZE(hs_jack_gpios),
hs_jack_gpios);
}
static struct snd_soc_dai_link byt_max98090_dais[] = {

View File

@ -32,7 +32,7 @@ static const struct snd_pcm_hardware sst_byt_pcm_hardware = {
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FORMAT_S24_LE,
SNDRV_PCM_FMTBIT_S24_LE,
.period_bytes_min = 384,
.period_bytes_max = 48000,
.periods_min = 2,

View File

@ -359,6 +359,17 @@ static u32 hsw_block_get_bit(struct sst_mem_block *block)
return bit;
}
/*dummy read a SRAM block.*/
static void sst_mem_block_dummy_read(struct sst_mem_block *block)
{
u32 size;
u8 tmp_buf[4];
struct sst_dsp *sst = block->dsp;
size = block->size > 4 ? 4 : block->size;
memcpy_fromio(tmp_buf, sst->addr.lpe + block->offset, size);
}
/* enable 32kB memory block - locks held by caller */
static int hsw_block_enable(struct sst_mem_block *block)
{
@ -378,6 +389,8 @@ static int hsw_block_enable(struct sst_mem_block *block)
/* wait 18 DSP clock ticks */
udelay(10);
/*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/
sst_mem_block_dummy_read(block);
return 0;
}

View File

@ -80,7 +80,7 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = {
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE |
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.period_bytes_min = PAGE_SIZE,
.period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE,
@ -400,7 +400,15 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16);
break;
case SNDRV_PCM_FORMAT_S24_LE:
bits = SST_HSW_DEPTH_24BIT;
bits = SST_HSW_DEPTH_32BIT;
sst_hsw_stream_set_valid(hsw, pcm_data->stream, 24);
break;
case SNDRV_PCM_FORMAT_S8:
bits = SST_HSW_DEPTH_8BIT;
sst_hsw_stream_set_valid(hsw, pcm_data->stream, 8);
break;
case SNDRV_PCM_FORMAT_S32_LE:
bits = SST_HSW_DEPTH_32BIT;
sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32);
break;
default:
@ -685,8 +693,9 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
}
#define HSW_FORMATS \
(SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
(SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S8)
static struct snd_soc_dai_driver hsw_dais[] = {
{
@ -696,7 +705,7 @@ static struct snd_soc_dai_driver hsw_dais[] = {
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
},
},
{
@ -727,8 +736,8 @@ static struct snd_soc_dai_driver hsw_dais[] = {
.stream_name = "Loopback Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = HSW_FORMATS,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
},
},
{
@ -737,8 +746,8 @@ static struct snd_soc_dai_driver hsw_dais[] = {
.stream_name = "Analog Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = HSW_FORMATS,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
},
},
};

View File

@ -570,7 +570,7 @@ static int s6000_i2s_probe(struct platform_device *pdev)
return ret;
}
static void s6000_i2s_remove(struct platform_device *pdev)
static int s6000_i2s_remove(struct platform_device *pdev)
{
struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
struct resource *region;
@ -597,6 +597,8 @@ static void s6000_i2s_remove(struct platform_device *pdev)
iounmap(mmio);
region = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_mem_region(region->start, resource_size(region));
return 0;
}
static struct platform_driver s6000_i2s_driver = {

View File

@ -68,6 +68,8 @@ struct i2s_dai {
#define DAI_OPENED (1 << 0) /* Dai is opened */
#define DAI_MANAGER (1 << 1) /* Dai is the manager */
unsigned mode;
/* CDCLK pin direction: 0 - input, 1 - output */
unsigned int cdclk_out:1;
/* Driver for this DAI */
struct snd_soc_dai_driver i2s_dai_drv;
/* DMA parameters */
@ -737,6 +739,9 @@ static int i2s_startup(struct snd_pcm_substream *substream,
spin_unlock_irqrestore(&lock, flags);
if (!is_opened(other) && i2s->cdclk_out)
i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
0, SND_SOC_CLOCK_OUT);
return 0;
}
@ -752,9 +757,13 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
i2s->mode &= ~DAI_OPENED;
i2s->mode &= ~DAI_MANAGER;
if (is_opened(other))
if (is_opened(other)) {
other->mode |= DAI_MANAGER;
} else {
u32 mod = readl(i2s->addr + I2SMOD);
i2s->cdclk_out = !(mod & MOD_CDCLKCON);
other->cdclk_out = i2s->cdclk_out;
}
/* Reset any constraint on RFS and BFS */
i2s->rfs = 0;
i2s->bfs = 0;
@ -920,11 +929,9 @@ static int i2s_suspend(struct snd_soc_dai *dai)
{
struct i2s_dai *i2s = to_info(dai);
if (dai->active) {
i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
}
i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
return 0;
}
@ -933,11 +940,9 @@ static int i2s_resume(struct snd_soc_dai *dai)
{
struct i2s_dai *i2s = to_info(dai);
if (dai->active) {
writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
}
writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
return 0;
}

View File

@ -297,7 +297,6 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
for (i = 1; i < MOD_MAX; i++) {
if (!src) {
mod[i] = ssi;
break;
} else if (!dvc) {
mod[i] = src;
src = NULL;
@ -308,6 +307,9 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
if (mod[i] == this)
index = i;
if (mod[i] == ssi)
break;
}
if (is_play) {

View File

@ -184,7 +184,7 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
void rsnd_gen_dma_addr(struct rsnd_priv *priv,
static void rsnd_gen2_dma_addr(struct rsnd_priv *priv,
struct rsnd_dma *dma,
struct dma_slave_config *cfg,
int is_play, int slave_id)
@ -226,17 +226,6 @@ void rsnd_gen_dma_addr(struct rsnd_priv *priv,
}
};
cfg->slave_id = slave_id;
cfg->src_addr = 0;
cfg->dst_addr = 0;
cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
/*
* gen1 uses default DMA addr
*/
if (rsnd_is_gen1(priv))
return;
/* it shouldn't happen */
if (use_dvc & !use_src) {
dev_err(dev, "DVC is selected without SRC\n");
@ -250,6 +239,26 @@ void rsnd_gen_dma_addr(struct rsnd_priv *priv,
id, cfg->src_addr, cfg->dst_addr);
}
void rsnd_gen_dma_addr(struct rsnd_priv *priv,
struct rsnd_dma *dma,
struct dma_slave_config *cfg,
int is_play, int slave_id)
{
cfg->slave_id = slave_id;
cfg->src_addr = 0;
cfg->dst_addr = 0;
cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
/*
* gen1 uses default DMA addr
*/
if (rsnd_is_gen1(priv))
return;
rsnd_gen2_dma_addr(priv, dma, cfg, is_play, slave_id);
}
/*
* Gen2
*/

View File

@ -270,12 +270,32 @@ static const struct file_operations codec_reg_fops = {
.llseek = default_llseek,
};
static struct dentry *soc_debugfs_create_dir(struct dentry *parent,
const char *fmt, ...)
{
struct dentry *de;
va_list ap;
char *s;
va_start(ap, fmt);
s = kvasprintf(GFP_KERNEL, fmt, ap);
va_end(ap);
if (!s)
return NULL;
de = debugfs_create_dir(s, parent);
kfree(s);
return de;
}
static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
{
struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
codec->debugfs_codec_root = debugfs_create_dir(codec->name,
debugfs_card_root);
codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root,
"codec:%s", codec->name);
if (!codec->debugfs_codec_root) {
dev_warn(codec->dev,
"ASoC: Failed to create codec debugfs directory\n");
@ -306,8 +326,8 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
{
struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
platform->debugfs_platform_root = debugfs_create_dir(platform->name,
debugfs_card_root);
platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root,
"platform:%s", platform->name);
if (!platform->debugfs_platform_root) {
dev_warn(platform->dev,
"ASoC: Failed to create platform debugfs directory\n");

View File

@ -2069,6 +2069,7 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card)
dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
}
dpcm_path_put(&list);
capture:
/* skip if FE doesn't have capture capability */
if (!fe->cpu_dai->driver->capture.channels_min)