mirror of https://gitee.com/openkylin/linux.git
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:
commit
2fa4a285dd
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 : "");
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue