summaryrefslogtreecommitdiff
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-07-31 19:54:03 +0100
committerMark Brown <broonie@kernel.org>2020-07-31 19:54:03 +0100
commit84569f329f7fcb40b7b1860f273b2909dabf2a2b (patch)
treecd332fbb2947f20cc06e3b80da75b189c8ac624e /sound/soc/fsl
parentc8f7dbdbaa15c700ea02abf92b8d9bda2e91050b (diff)
parent8e34f1e867b572f1e20b5250c2897fe5f041c99f (diff)
Merge remote-tracking branch 'asoc/for-5.9' into asoc-next
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/Kconfig1
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c2
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c216
-rw-r--r--sound/soc/fsl/fsl_asrc.c103
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c4
-rw-r--r--sound/soc/fsl/fsl_audmix.c10
-rw-r--r--sound/soc/fsl/fsl_dma.c2
-rw-r--r--sound/soc/fsl/fsl_easrc.c49
-rw-r--r--sound/soc/fsl/fsl_esai.c34
-rw-r--r--sound/soc/fsl/fsl_sai.c3
-rw-r--r--sound/soc/fsl/fsl_spdif.c233
-rw-r--r--sound/soc/fsl/fsl_ssi.c78
-rw-r--r--sound/soc/fsl/fsl_ssi_dbg.c4
-rw-r--r--sound/soc/fsl/imx-audmix.c10
-rw-r--r--sound/soc/fsl/imx-audmux.c2
-rw-r--r--sound/soc/fsl/imx-mc13783.c2
-rw-r--r--sound/soc/fsl/mpc5200_dma.c8
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c2
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c4
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c2
-rw-r--r--sound/soc/fsl/p1022_rdk.c2
-rw-r--r--sound/soc/fsl/wm1133-ev1.c2
23 files changed, 547 insertions, 228 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index ea7b4787a8af..1c4ca5ec8caf 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -315,6 +315,7 @@ config SND_SOC_FSL_ASOC_CARD
depends on OF && I2C
# enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m:
depends on SND_AC97_CODEC || SND_AC97_CODEC=n
+ select SND_SIMPLE_CARD_UTILS
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_PCM_DMA
select SND_SOC_FSL_ESAI
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 4ff2d21bb32f..e13271ea84de 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -30,7 +30,7 @@
static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
int ret;
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 00be73900888..de136c0a497d 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -15,6 +15,8 @@
#endif
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/simple_card_utils.h>
#include "fsl_esai.h"
#include "fsl_sai.h"
@@ -33,8 +35,7 @@
#define DAI_FMT_BASE (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF)
/**
- * CODEC private data
- *
+ * struct codec_priv - CODEC private data
* @mclk_freq: Clock rate of MCLK
* @mclk_id: MCLK (or main clock) id for set_sysclk()
* @fll_id: FLL (or secordary clock) id for set_sysclk()
@@ -48,11 +49,10 @@ struct codec_priv {
};
/**
- * CPU private data
- *
- * @sysclk_freq[2]: SYSCLK rates for set_sysclk()
- * @sysclk_dir[2]: SYSCLK directions for set_sysclk()
- * @sysclk_id[2]: SYSCLK ids for set_sysclk()
+ * struct cpu_priv - CPU private data
+ * @sysclk_freq: SYSCLK rates for set_sysclk()
+ * @sysclk_dir: SYSCLK directions for set_sysclk()
+ * @sysclk_id: SYSCLK ids for set_sysclk()
* @slot_width: Slot width of each frame
*
* Note: [1] for tx and [0] for rx
@@ -65,9 +65,10 @@ struct cpu_priv {
};
/**
- * Freescale Generic ASOC card private data
- *
- * @dai_link[3]: DAI link structure including normal one and DPCM link
+ * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data
+ * @dai_link: DAI link structure including normal one and DPCM link
+ * @hp_jack: Headphone Jack structure
+ * @mic_jack: Microphone Jack structure
* @pdev: platform device pointer
* @codec_priv: CODEC private data
* @cpu_priv: CPU private data
@@ -82,6 +83,8 @@ struct cpu_priv {
struct fsl_asoc_card_priv {
struct snd_soc_dai_link dai_link[3];
+ struct asoc_simple_jack hp_jack;
+ struct asoc_simple_jack mic_jack;
struct platform_device *pdev;
struct codec_priv codec_priv;
struct cpu_priv cpu_priv;
@@ -94,8 +97,8 @@ struct fsl_asoc_card_priv {
char name[32];
};
-/**
- * This dapm route map exsits for DPCM link only.
+/*
+ * This dapm route map exists for DPCM link only.
* The other routes shall go through Device Tree.
*
* Note: keep all ASRC routes in the second half
@@ -119,6 +122,13 @@ static const struct snd_soc_dapm_route audio_map_ac97[] = {
{"ASRC-Capture", NULL, "AC97 Capture"},
};
+static const struct snd_soc_dapm_route audio_map_tx[] = {
+ /* 1st half -- Normal DAPM routes */
+ {"Playback", NULL, "CPU-Playback"},
+ /* 2nd half -- ASRC DAPM routes */
+ {"CPU-Playback", NULL, "ASRC-Playback"},
+};
+
/* Add all possible widgets into here without being redundant */
static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
SND_SOC_DAPM_LINE("Line Out Jack", NULL),
@@ -138,7 +148,7 @@ static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv)
static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct cpu_priv *cpu_priv = &priv->cpu_priv;
@@ -441,6 +451,44 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
return 0;
}
+static int hp_jack_event(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+ struct snd_soc_dapm_context *dapm = &jack->card->dapm;
+
+ if (event & SND_JACK_HEADPHONE)
+ /* Disable speaker if headphone is plugged in */
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+ else
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+
+ return 0;
+}
+
+static struct notifier_block hp_jack_nb = {
+ .notifier_call = hp_jack_event,
+};
+
+static int mic_jack_event(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+ struct snd_soc_dapm_context *dapm = &jack->card->dapm;
+
+ if (event & SND_JACK_MICROPHONE)
+ /* Disable dmic if microphone is plugged in */
+ snd_soc_dapm_disable_pin(dapm, "DMIC");
+ else
+ snd_soc_dapm_enable_pin(dapm, "DMIC");
+
+ return 0;
+}
+
+static struct notifier_block mic_jack_nb = {
+ .notifier_call = mic_jack_event,
+};
+
static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
{
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
@@ -483,10 +531,14 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
struct device_node *cpu_np, *codec_np, *asrc_np;
struct device_node *np = pdev->dev.of_node;
struct platform_device *asrc_pdev = NULL;
+ struct device_node *bitclkmaster = NULL;
+ struct device_node *framemaster = NULL;
struct platform_device *cpu_pdev;
struct fsl_asoc_card_priv *priv;
- struct i2c_client *codec_dev;
+ struct device *codec_dev = NULL;
const char *codec_dai_name;
+ const char *codec_dev_name;
+ unsigned int daifmt;
u32 width;
int ret;
@@ -512,10 +564,23 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
}
codec_np = of_parse_phandle(np, "audio-codec", 0);
- if (codec_np)
- codec_dev = of_find_i2c_device_by_node(codec_np);
- else
- codec_dev = NULL;
+ if (codec_np) {
+ struct platform_device *codec_pdev;
+ struct i2c_client *codec_i2c;
+
+ codec_i2c = of_find_i2c_device_by_node(codec_np);
+ if (codec_i2c) {
+ codec_dev = &codec_i2c->dev;
+ codec_dev_name = codec_i2c->name;
+ }
+ if (!codec_dev) {
+ codec_pdev = of_find_device_by_node(codec_np);
+ if (codec_pdev) {
+ codec_dev = &codec_pdev->dev;
+ codec_dev_name = codec_pdev->name;
+ }
+ }
+ }
asrc_np = of_parse_phandle(np, "audio-asrc", 0);
if (asrc_np)
@@ -523,7 +588,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
/* Get the MCLK rate only, and leave it controlled by CODEC drivers */
if (codec_dev) {
- struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
+ struct clk *codec_clk = clk_get(codec_dev, NULL);
if (!IS_ERR(codec_clk)) {
priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
@@ -538,6 +603,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
/* Assign a default DAI format, and allow each card to overwrite it */
priv->dai_fmt = DAI_FMT_BASE;
+ memcpy(priv->dai_link, fsl_asoc_card_dai,
+ sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
+
+ priv->card.dapm_routes = audio_map;
+ priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
/* Diversify the card configurations */
if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
codec_dai_name = "cs42888";
@@ -573,12 +643,58 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
codec_dai_name = "ac97-hifi";
priv->card.set_bias_level = NULL;
priv->dai_fmt = SND_SOC_DAIFMT_AC97;
+ priv->card.dapm_routes = audio_map_ac97;
+ priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
+ } else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
+ codec_dai_name = "fsl-mqs-dai";
+ priv->card.set_bias_level = NULL;
+ priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+ SND_SOC_DAIFMT_CBS_CFS |
+ SND_SOC_DAIFMT_NB_NF;
+ priv->dai_link[1].dpcm_capture = 0;
+ priv->dai_link[2].dpcm_capture = 0;
+ priv->card.dapm_routes = audio_map_tx;
+ priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
+ } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8524")) {
+ codec_dai_name = "wm8524-hifi";
+ priv->card.set_bias_level = NULL;
+ priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
+ priv->dai_link[1].dpcm_capture = 0;
+ priv->dai_link[2].dpcm_capture = 0;
+ priv->cpu_priv.slot_width = 32;
+ priv->card.dapm_routes = audio_map_tx;
+ priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else {
dev_err(&pdev->dev, "unknown Device Tree compatible\n");
ret = -EINVAL;
goto asrc_fail;
}
+ /* Format info from DT is optional. */
+ daifmt = snd_soc_of_parse_daifmt(np, NULL,
+ &bitclkmaster, &framemaster);
+ daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
+ if (bitclkmaster || framemaster) {
+ if (codec_np == bitclkmaster)
+ daifmt |= (codec_np == framemaster) ?
+ SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
+ else
+ daifmt |= (codec_np == framemaster) ?
+ SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
+
+ /* Override dai_fmt with value from DT */
+ priv->dai_fmt = daifmt;
+ }
+
+ /* Change direction according to format */
+ if (priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) {
+ priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_IN;
+ priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_IN;
+ }
+
+ of_node_put(bitclkmaster);
+ of_node_put(framemaster);
+
if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
dev_err(&pdev->dev, "failed to find codec device\n");
ret = -EPROBE_DEFER;
@@ -601,19 +717,17 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
}
- snprintf(priv->name, sizeof(priv->name), "%s-audio",
- fsl_asoc_card_is_ac97(priv) ? "ac97" :
- codec_dev->name);
-
/* Initialize sound card */
priv->pdev = pdev;
priv->card.dev = &pdev->dev;
- priv->card.name = priv->name;
+ ret = snd_soc_of_parse_card_name(&priv->card, "model");
+ if (ret) {
+ snprintf(priv->name, sizeof(priv->name), "%s-audio",
+ fsl_asoc_card_is_ac97(priv) ? "ac97" : codec_dev_name);
+ priv->card.name = priv->name;
+ }
priv->card.dai_link = priv->dai_link;
- priv->card.dapm_routes = fsl_asoc_card_is_ac97(priv) ?
- audio_map_ac97 : audio_map;
priv->card.late_probe = fsl_asoc_card_late_probe;
- priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;
priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets);
@@ -621,13 +735,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
if (!asrc_pdev)
priv->card.num_dapm_routes /= 2;
- memcpy(priv->dai_link, fsl_asoc_card_dai,
- sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
-
- ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
- if (ret) {
- dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
- goto asrc_fail;
+ if (of_property_read_bool(np, "audio-routing")) {
+ ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
+ goto asrc_fail;
+ }
}
/* Normal DAI Link */
@@ -704,8 +817,37 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(&priv->card, priv);
ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
- if (ret && ret != -EPROBE_DEFER)
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto asrc_fail;
+ }
+
+ /*
+ * Properties "hp-det-gpio" and "mic-det-gpio" are optional, and
+ * asoc_simple_init_jack uses these properties for creating
+ * Headphone Jack and Microphone Jack.
+ *
+ * The notifier is initialized in snd_soc_card_jack_new(), then
+ * snd_soc_jack_notifier_register can be called.
+ */
+ if (of_property_read_bool(np, "hp-det-gpio")) {
+ ret = asoc_simple_init_jack(&priv->card, &priv->hp_jack,
+ 1, NULL, "Headphone Jack");
+ if (ret)
+ goto asrc_fail;
+
+ snd_soc_jack_notifier_register(&priv->hp_jack.jack, &hp_jack_nb);
+ }
+
+ if (of_property_read_bool(np, "mic-det-gpio")) {
+ ret = asoc_simple_init_jack(&priv->card, &priv->mic_jack,
+ 0, NULL, "Mic Jack");
+ if (ret)
+ goto asrc_fail;
+
+ snd_soc_jack_notifier_register(&priv->mic_jack.jack, &mic_jack_nb);
+ }
asrc_fail:
of_node_put(asrc_np);
@@ -724,6 +866,8 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-sgtl5000", },
{ .compatible = "fsl,imx-audio-wm8962", },
{ .compatible = "fsl,imx-audio-wm8960", },
+ { .compatible = "fsl,imx-audio-mqs", },
+ { .compatible = "fsl,imx-audio-wm8524", },
{}
};
MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 95f6a9617b0b..02c81d2e34ad 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -37,7 +37,7 @@ static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
.list = supported_asrc_rate,
};
-/**
+/*
* The following tables map the relationship between asrc_inclk/asrc_outclk in
* fsl_asrc.h and the registers of ASRCSR
*/
@@ -68,7 +68,7 @@ static unsigned char output_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
};
-/**
+/*
* i.MX8QM/i.MX8QXP uses the same map for input and output.
* clk_map_imx8qm[0] is for i.MX8QM asrc0
* clk_map_imx8qm[1] is for i.MX8QM asrc1
@@ -102,16 +102,17 @@ static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
};
/**
- * Select the pre-processing and post-processing options
+ * fsl_asrc_sel_proc - Select the pre-processing and post-processing options
+ * @inrate: input sample rate
+ * @outrate: output sample rate
+ * @pre_proc: return value for pre-processing option
+ * @post_proc: return value for post-processing option
+ *
* Make sure to exclude following unsupported cases before
* calling this function:
* 1) inrate > 8.125 * outrate
* 2) inrate > 16.125 * outrate
*
- * inrate: input sample rate
- * outrate: output sample rate
- * pre_proc: return value for pre-processing option
- * post_proc: return value for post-processing option
*/
static void fsl_asrc_sel_proc(int inrate, int outrate,
int *pre_proc, int *post_proc)
@@ -148,7 +149,9 @@ static void fsl_asrc_sel_proc(int inrate, int outrate,
}
/**
- * Request ASRC pair
+ * fsl_asrc_request_pair - Request ASRC pair
+ * @channels: number of channels
+ * @pair: pointer to pair
*
* It assigns pair by the order of A->C->B because allocation of pair B,
* within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
@@ -193,7 +196,8 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
}
/**
- * Release ASRC pair
+ * fsl_asrc_release_pair - Release ASRC pair
+ * @pair: pair to release
*
* It clears the resource from asrc and releases the occupied channels.
*/
@@ -217,7 +221,10 @@ static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
}
/**
- * Configure input and output thresholds
+ * fsl_asrc_set_watermarks- configure input and output thresholds
+ * @pair: pointer to pair
+ * @in: input threshold
+ * @out: output threshold
*/
static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
{
@@ -234,7 +241,9 @@ static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
}
/**
- * Calculate the total divisor between asrck clock rate and sample rate
+ * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
+ * @pair: pointer to pair
+ * @div: divider
*
* It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
*/
@@ -250,7 +259,10 @@ static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
}
/**
- * Calculate and set the ratio for Ideal Ratio mode only
+ * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only
+ * @pair: pointer to pair
+ * @inrate: input rate
+ * @outrate: output rate
*
* The ratio is a 32-bit fixed point value with 26 fractional bits.
*/
@@ -293,7 +305,9 @@ static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
}
/**
- * Configure the assigned ASRC pair
+ * fsl_asrc_config_pair - Configure the assigned ASRC pair
+ * @pair: pointer to pair
+ * @use_ideal_rate: boolean configuration
*
* It configures those ASRC registers according to a configuration instance
* of struct asrc_config which includes in/output sample rate, width, channel
@@ -508,7 +522,8 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
}
/**
- * Start the assigned ASRC pair
+ * fsl_asrc_start_pair - Start the assigned ASRC pair
+ * @pair: pointer to pair
*
* It enables the assigned pair and makes it stopped at the stall level.
*/
@@ -539,7 +554,8 @@ static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
}
/**
- * Stop the assigned ASRC pair
+ * fsl_asrc_stop_pair - Stop the assigned ASRC pair
+ * @pair: pointer to pair
*/
static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
{
@@ -552,7 +568,9 @@ static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
}
/**
- * Get DMA channel according to the pair and direction.
+ * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
+ * @pair: pointer to pair
+ * @dir: DMA direction
*/
static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
bool dir)
@@ -582,11 +600,51 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
}
+/* Select proper clock source for internal ratio mode */
+static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
+ struct fsl_asrc_pair *pair,
+ int in_rate,
+ int out_rate)
+{
+ struct fsl_asrc_pair_priv *pair_priv = pair->private;
+ struct asrc_config *config = pair_priv->config;
+ int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
+ int clk_rate, clk_index;
+ int i = 0, j = 0;
+
+ rate[IN] = in_rate;
+ rate[OUT] = out_rate;
+
+ /* Select proper clock source for internal ratio mode */
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
+ clk_index = asrc_priv->clk_map[j][i];
+ clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);
+ /* Only match a perfect clock source with no remainder */
+ if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
+ (clk_rate % rate[j]) == 0)
+ break;
+ }
+
+ select_clk[j] = i;
+ }
+
+ /* Switch to ideal ratio mode if there is no proper clock source */
+ if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == ASRC_CLK_MAP_LEN) {
+ select_clk[IN] = INCLK_NONE;
+ select_clk[OUT] = OUTCLK_ASRCK1_CLK;
+ }
+
+ config->inclk = select_clk[IN];
+ config->outclk = select_clk[OUT];
+}
+
static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
+ struct fsl_asrc_priv *asrc_priv = asrc->private;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc_pair_priv *pair_priv = pair->private;
@@ -605,8 +663,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
config.pair = pair->index;
config.channel_num = channels;
- config.inclk = INCLK_NONE;
- config.outclk = OUTCLK_ASRCK1_CLK;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_format = params_format(params);
@@ -620,6 +676,10 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
config.output_sample_rate = rate;
}
+ fsl_asrc_select_clk(asrc_priv, pair,
+ config.input_sample_rate,
+ config.output_sample_rate);
+
ret = fsl_asrc_config_pair(pair, false);
if (ret) {
dev_err(dai->dev, "fail to config asrc pair\n");
@@ -854,7 +914,8 @@ static const struct regmap_config fsl_asrc_regmap_config = {
};
/**
- * Initialize ASRC registers with a default configurations
+ * fsl_asrc_init - Initialize ASRC registers with a default configuration
+ * @asrc: ASRC context
*/
static int fsl_asrc_init(struct fsl_asrc *asrc)
{
@@ -888,7 +949,9 @@ static int fsl_asrc_init(struct fsl_asrc *asrc)
}
/**
- * Interrupt handler for ASRC
+ * fsl_asrc_isr- Interrupt handler for ASRC
+ * @irq: irq number
+ * @dev_id: ASRC context
*/
static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
{
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index 5f01a58f422a..29f91cdecbc3 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -129,7 +129,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
struct snd_pcm_hw_params *params)
{
enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
@@ -313,7 +313,7 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dmaengine_dai_dma_data *dma_data;
struct device *dev = component->dev;
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index 8b9027f76d8a..a447bafa00d2 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -116,13 +116,9 @@ static int fsl_audmix_put_mix_clk_src(struct snd_kcontrol *kcontrol,
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int *item = ucontrol->value.enumerated.item;
unsigned int reg_val, val, mix_clk;
- int ret;
/* Get current state */
- ret = snd_soc_component_read(comp, FSL_AUDMIX_CTR, &reg_val);
- if (ret)
- return ret;
-
+ reg_val = snd_soc_component_read(comp, FSL_AUDMIX_CTR);
mix_clk = ((reg_val & FSL_AUDMIX_CTR_MIXCLK_MASK)
>> FSL_AUDMIX_CTR_MIXCLK_SHIFT);
val = snd_soc_enum_item_to_val(e, item[0]);
@@ -162,9 +158,7 @@ static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol,
int ret;
/* Get current state */
- ret = snd_soc_component_read(comp, FSL_AUDMIX_CTR, &reg_val);
- if (ret)
- return ret;
+ reg_val = snd_soc_component_read(comp, FSL_AUDMIX_CTR);
/* "From" state */
out_src = ((reg_val & FSL_AUDMIX_CTR_OUTSRC_MASK)
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 13ae089c1911..be021250d6e9 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -200,7 +200,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
{
struct fsl_dma_private *dma_private = dev_id;
struct snd_pcm_substream *substream = dma_private->substream;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct device *dev = rtd->dev;
struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
irqreturn_t ret = IRQ_NONE;
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index c6b5eb2d2af7..60951a8aabd3 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -79,11 +79,8 @@ static int fsl_easrc_get_reg(struct snd_kcontrol *kcontrol,
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
unsigned int regval;
- int ret;
- ret = snd_soc_component_read(component, mc->regbase, &regval);
- if (ret < 0)
- return ret;
+ regval = snd_soc_component_read(component, mc->regbase);
ucontrol->value.integer.value[0] = regval;
@@ -179,22 +176,21 @@ static int fsl_easrc_set_rs_ratio(struct fsl_asrc_pair *ctx)
struct fsl_easrc_ctx_priv *ctx_priv = ctx->private;
unsigned int in_rate = ctx_priv->in_params.norm_rate;
unsigned int out_rate = ctx_priv->out_params.norm_rate;
- unsigned int int_bits;
unsigned int frac_bits;
u64 val;
u32 *r;
switch (easrc_priv->rs_num_taps) {
case EASRC_RS_32_TAPS:
- int_bits = 5;
+ /* integer bits = 5; */
frac_bits = 39;
break;
case EASRC_RS_64_TAPS:
- int_bits = 6;
+ /* integer bits = 6; */
frac_bits = 38;
break;
case EASRC_RS_128_TAPS:
- int_bits = 7;
+ /* integer bits = 7; */
frac_bits = 37;
break;
default:
@@ -390,11 +386,11 @@ static int fsl_easrc_resampler_config(struct fsl_asrc *easrc)
* For input int[16, 24, 32] -> output float32
* scale it by multiplying filter coefficients by 2^-15, 2^-23, 2^-31
* input:
- * asrc: Structure pointer of fsl_asrc
- * infilter : Pointer to non-scaled input filter
- * shift: The multiply factor
+ * @easrc: Structure pointer of fsl_asrc
+ * @infilter : Pointer to non-scaled input filter
+ * @shift: The multiply factor
* output:
- * outfilter: scaled filter
+ * @outfilter: scaled filter
*/
static int fsl_easrc_normalize_filter(struct fsl_asrc *easrc,
u64 *infilter,
@@ -964,7 +960,7 @@ static int fsl_easrc_release_slot(struct fsl_asrc *easrc, unsigned int ctx_id)
*
* Configure the register relate with context.
*/
-int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
+static int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
{
struct fsl_easrc_ctx_priv *ctx_priv;
struct fsl_asrc_pair *ctx;
@@ -1125,15 +1121,15 @@ static int fsl_easrc_process_format(struct fsl_asrc_pair *ctx,
return 0;
}
-int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
- snd_pcm_format_t *in_raw_format,
- snd_pcm_format_t *out_raw_format)
+static int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
+ snd_pcm_format_t *in_raw_format,
+ snd_pcm_format_t *out_raw_format)
{
struct fsl_asrc *easrc = ctx->asrc;
struct fsl_easrc_ctx_priv *ctx_priv = ctx->private;
struct fsl_easrc_data_fmt *in_fmt = &ctx_priv->in_params.fmt;
struct fsl_easrc_data_fmt *out_fmt = &ctx_priv->out_params.fmt;
- int ret;
+ int ret = 0;
/* Get the bitfield values for input data format */
if (in_raw_format && out_raw_format) {
@@ -1198,10 +1194,9 @@ int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
* to conform with this format. Interleaving parameters are accessed
* through the ASRC_CTRL_IN_ACCESSa and ASRC_CTRL_OUT_ACCESSa registers
*/
-int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
+static int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
{
struct fsl_easrc_ctx_priv *ctx_priv;
- struct device *dev;
struct fsl_asrc *easrc;
if (!ctx)
@@ -1209,7 +1204,6 @@ int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
easrc = ctx->asrc;
ctx_priv = ctx->private;
- dev = &easrc->pdev->dev;
/* input interleaving parameters */
regmap_update_bits(easrc->regmap, REG_EASRC_CIA(ctx->index),
@@ -1242,7 +1236,7 @@ int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
* Returns a negative number on error and >=0 as context id
* on success
*/
-int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
+static int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
{
enum asrc_pair_index index = ASRC_INVALID_PAIR;
struct fsl_asrc *easrc = ctx->asrc;
@@ -1287,17 +1281,15 @@ int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
*
* This funciton is mainly doing the revert thing in request context
*/
-void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
+static void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
{
unsigned long lock_flags;
struct fsl_asrc *easrc;
- struct device *dev;
if (!ctx)
return;
easrc = ctx->asrc;
- dev = &easrc->pdev->dev;
spin_lock_irqsave(&easrc->lock, lock_flags);
@@ -1314,7 +1306,7 @@ void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
*
* Enable the DMA request and context
*/
-int fsl_easrc_start_context(struct fsl_asrc_pair *ctx)
+static int fsl_easrc_start_context(struct fsl_asrc_pair *ctx)
{
struct fsl_asrc *easrc = ctx->asrc;
@@ -1332,7 +1324,7 @@ int fsl_easrc_start_context(struct fsl_asrc_pair *ctx)
*
* Disable the DMA request and context
*/
-int fsl_easrc_stop_context(struct fsl_asrc_pair *ctx)
+static int fsl_easrc_stop_context(struct fsl_asrc_pair *ctx)
{
struct fsl_asrc *easrc = ctx->asrc;
int val, i;
@@ -1379,8 +1371,8 @@ int fsl_easrc_stop_context(struct fsl_asrc_pair *ctx)
return 0;
}
-struct dma_chan *fsl_easrc_get_dma_channel(struct fsl_asrc_pair *ctx,
- bool dir)
+static struct dma_chan *fsl_easrc_get_dma_channel(struct fsl_asrc_pair *ctx,
+ bool dir)
{
struct fsl_asrc *easrc = ctx->asrc;
enum asrc_pair_index index = ctx->index;
@@ -1391,7 +1383,6 @@ struct dma_chan *fsl_easrc_get_dma_channel(struct fsl_asrc_pair *ctx,
return dma_request_slave_channel(&easrc->pdev->dev, name);
};
-EXPORT_SYMBOL_GPL(fsl_easrc_get_dma_channel);
static const unsigned int easrc_rates[] = {
8000, 11025, 12000, 16000,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index cbcb70d6f8c8..4ae36099ae82 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -22,8 +22,7 @@
SNDRV_PCM_FMTBIT_S24_LE)
/**
- * fsl_esai_soc_data: soc specific data
- *
+ * struct fsl_esai_soc_data - soc specific data
* @imx: for imx platform
* @reset_at_xrun: flags for enable reset operaton
*/
@@ -33,8 +32,7 @@ struct fsl_esai_soc_data {
};
/**
- * fsl_esai: ESAI private data
- *
+ * struct fsl_esai - ESAI private data
* @dma_params_rx: DMA parameters for receive channel
* @dma_params_tx: DMA parameters for transmit channel
* @pdev: platform device pointer
@@ -49,6 +47,8 @@ struct fsl_esai_soc_data {
* @fifo_depth: depth of tx/rx FIFO
* @slot_width: width of each DAI slot
* @slots: number of slots
+ * @tx_mask: slot mask for TX
+ * @rx_mask: slot mask for RX
* @channels: channel num for tx or rx
* @hck_rate: clock rate of desired HCKx clock
* @sck_rate: clock rate of desired SCKx clock
@@ -157,13 +157,15 @@ static irqreturn_t esai_isr(int irq, void *devid)
}
/**
- * This function is used to calculate the divisors of psr, pm, fp and it is
- * supposed to be called in set_dai_sysclk() and set_bclk().
+ * fsl_esai_divisor_cal - This function is used to calculate the
+ * divisors of psr, pm, fp and it is supposed to be called in
+ * set_dai_sysclk() and set_bclk().
*
+ * @dai: pointer to DAI
+ * @tx: current setting is for playback or capture
* @ratio: desired overall ratio for the paticipating dividers
* @usefp: for HCK setting, there is no need to set fp divider
* @fp: bypass other dividers by setting fp directly if fp != 0
- * @tx: current setting is for playback or capture
*/
static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
bool usefp, u32 fp)
@@ -250,13 +252,12 @@ out_fp:
}
/**
- * This function mainly configures the clock frequency of MCLK (HCKT/HCKR)
- *
- * @Parameters:
- * clk_id: The clock source of HCKT/HCKR
+ * fsl_esai_set_dai_sysclk - configure the clock frequency of MCLK (HCKT/HCKR)
+ * @dai: pointer to DAI
+ * @clk_id: The clock source of HCKT/HCKR
* (Input from outside; output from inside, FSYS or EXTAL)
- * freq: The required clock rate of HCKT/HCKR
- * dir: The clock direction of HCKT/HCKR
+ * @freq: The required clock rate of HCKT/HCKR
+ * @dir: The clock direction of HCKT/HCKR
*
* Note: If the direction is input, we do not care about clk_id.
*/
@@ -358,7 +359,10 @@ out:
}
/**
- * This function configures the related dividers according to the bclk rate
+ * fsl_esai_set_bclk - configure the related dividers according to the bclk rate
+ * @dai: pointer to DAI
+ * @tx: direction boolean
+ * @freq: bclk freq
*/
static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
{
@@ -1008,7 +1012,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
+ ret = devm_request_irq(&pdev->dev, irq, esai_isr, IRQF_SHARED,
esai_priv->name, esai_priv);
if (ret) {
dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 7031869a023a..cdff739924e2 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1017,6 +1017,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sai);
pm_runtime_enable(&pdev->dev);
+ regcache_cache_only(sai->regmap, true);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
&fsl_sai_dai, 1);
@@ -1108,7 +1109,6 @@ static int fsl_sai_runtime_suspend(struct device *dev)
clk_disable_unprepare(sai->bus_clk);
regcache_cache_only(sai->regmap, true);
- regcache_mark_dirty(sai->regmap);
return 0;
}
@@ -1138,6 +1138,7 @@ static int fsl_sai_runtime_resume(struct device *dev)
}
regcache_cache_only(sai->regmap, false);
+ regcache_mark_dirty(sai->regmap);
regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
usleep_range(1000, 2000);
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 1b2e516f9162..455f96908377 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -16,6 +16,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/regmap.h>
+#include <linux/pm_runtime.h>
#include <sound/asoundef.h>
#include <sound/dmaengine_pcm.h>
@@ -42,6 +43,18 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
#define DEFAULT_RXCLK_SRC 1
+/**
+ * struct fsl_spdif_soc_data: soc specific data
+ *
+ * @imx: for imx platform
+ * @shared_root_clock: flag of sharing a clock source with others;
+ * so the driver shouldn't set root clock rate
+ */
+struct fsl_spdif_soc_data {
+ bool imx;
+ bool shared_root_clock;
+};
+
/*
* SPDIF control structure
* Defines channel status, subcode and Q sub
@@ -68,8 +81,8 @@ struct spdif_mixer_control {
};
/**
- * fsl_spdif_priv: Freescale SPDIF private data
- *
+ * struct fsl_spdif_priv - Freescale SPDIF private data
+ * @soc: SPDIF soc data
* @fsl_spdif_control: SPDIF control data
* @cpu_dai_drv: cpu dai driver
* @pdev: platform device pointer
@@ -87,8 +100,10 @@ struct spdif_mixer_control {
* @spbaclk: SPBA clock (optional, depending on SoC design)
* @dma_params_tx: DMA parameters for transmit channel
* @dma_params_rx: DMA parameters for receive channel
+ * @regcache_srpc: regcache for SRPC
*/
struct fsl_spdif_priv {
+ const struct fsl_spdif_soc_data *soc;
struct spdif_mixer_control fsl_spdif_control;
struct snd_soc_dai_driver cpu_dai_drv;
struct platform_device *pdev;
@@ -110,6 +125,27 @@ struct fsl_spdif_priv {
u32 regcache_srpc;
};
+static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
+ .imx = false,
+ .shared_root_clock = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
+ .imx = true,
+ .shared_root_clock = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
+ .imx = true,
+ .shared_root_clock = true,
+};
+
+/* Check if clk is a root clock that does not share clock source with others */
+static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, int clk)
+{
+ return (clk == STC_TXCLK_SPDIF_ROOT) && !spdif->soc->shared_root_clock;
+}
+
/* DPLL locked and lock loss interrupt handler */
static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
{
@@ -369,7 +405,7 @@ static int spdif_set_rx_clksrc(struct fsl_spdif_priv *spdif_priv,
static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
int sample_rate)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
struct regmap *regmap = spdif_priv->regmap;
@@ -420,8 +456,7 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
sysclk_df = spdif_priv->sysclk_df[rate];
- /* Don't mess up the clocks from other modules */
- if (clk != STC_TXCLK_SPDIF_ROOT)
+ if (!fsl_spdif_can_set_clk_rate(spdif_priv, clk))
goto clk_set_bypass;
/* The S/PDIF block needs a clock of 64 * fs * txclk_df */
@@ -457,34 +492,19 @@ clk_set_bypass:
static int fsl_spdif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct platform_device *pdev = spdif_priv->pdev;
struct regmap *regmap = spdif_priv->regmap;
u32 scr, mask;
- int i;
int ret;
/* Reset module and interrupts only for first initialization */
if (!snd_soc_dai_active(cpu_dai)) {
- ret = clk_prepare_enable(spdif_priv->coreclk);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable core clock\n");
- return ret;
- }
-
- if (!IS_ERR(spdif_priv->spbaclk)) {
- ret = clk_prepare_enable(spdif_priv->spbaclk);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable spba clock\n");
- goto err_spbaclk;
- }
- }
-
ret = spdif_softreset(spdif_priv);
if (ret) {
dev_err(&pdev->dev, "failed to soft reset\n");
- goto err;
+ return ret;
}
/* Disable all the interrupts */
@@ -498,18 +518,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
- for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
- ret = clk_prepare_enable(spdif_priv->txclk[i]);
- if (ret)
- goto disable_txclk;
- }
} else {
scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
- ret = clk_prepare_enable(spdif_priv->rxclk);
- if (ret)
- goto err;
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
@@ -517,39 +529,25 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0);
return 0;
-
-disable_txclk:
- for (i--; i >= 0; i--)
- clk_disable_unprepare(spdif_priv->txclk[i]);
-err:
- if (!IS_ERR(spdif_priv->spbaclk))
- clk_disable_unprepare(spdif_priv->spbaclk);
-err_spbaclk:
- clk_disable_unprepare(spdif_priv->coreclk);
-
- return ret;
}
static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct regmap *regmap = spdif_priv->regmap;
- u32 scr, mask, i;
+ u32 scr, mask;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
scr = 0;
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
- for (i = 0; i < SPDIF_TXRATE_MAX; i++)
- clk_disable_unprepare(spdif_priv->txclk[i]);
} else {
scr = SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
- clk_disable_unprepare(spdif_priv->rxclk);
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
@@ -558,9 +556,6 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
spdif_intr_status_clear(spdif_priv);
regmap_update_bits(regmap, REG_SPDIF_SCR,
SCR_LOW_POWER, SCR_LOW_POWER);
- if (!IS_ERR(spdif_priv->spbaclk))
- clk_disable_unprepare(spdif_priv->spbaclk);
- clk_disable_unprepare(spdif_priv->coreclk);
}
}
@@ -568,7 +563,7 @@ static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
struct platform_device *pdev = spdif_priv->pdev;
@@ -596,7 +591,7 @@ static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
static int fsl_spdif_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct regmap *regmap = spdif_priv->regmap;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
@@ -781,8 +776,8 @@ static int fsl_spdif_vbit_info(struct snd_kcontrol *kcontrol,
}
/* Get valid good bit from interrupt status register */
-static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int fsl_spdif_rx_vbit_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
@@ -796,6 +791,35 @@ static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
return 0;
}
+static int fsl_spdif_tx_vbit_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct regmap *regmap = spdif_priv->regmap;
+ u32 val;
+
+ regmap_read(regmap, REG_SPDIF_SCR, &val);
+ val = (val & SCR_VAL_MASK) >> SCR_VAL_OFFSET;
+ val = 1 - val;
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int fsl_spdif_tx_vbit_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+ struct regmap *regmap = spdif_priv->regmap;
+ u32 val = (1 - ucontrol->value.integer.value[0]) << SCR_VAL_OFFSET;
+
+ regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK, val);
+
+ return 0;
+}
+
/* DPLL lock information */
static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
@@ -953,11 +977,21 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
/* Valid bit error controller */
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 V-Bit Errors",
+ .name = "IEC958 RX V-Bit Errors",
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = fsl_spdif_vbit_info,
- .get = fsl_spdif_vbit_get,
+ .get = fsl_spdif_rx_vbit_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "IEC958 TX V-Bit",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = fsl_spdif_vbit_info,
+ .get = fsl_spdif_tx_vbit_get,
+ .put = fsl_spdif_tx_vbit_put,
},
/* DPLL lock info get controller */
{
@@ -990,6 +1024,10 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
+ /*Clear the val bit for Tx*/
+ regmap_update_bits(spdif_private->regmap, REG_SPDIF_SCR,
+ SCR_VAL_MASK, SCR_VAL_CLEAR);
+
return 0;
}
@@ -1186,7 +1224,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
continue;
ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
- i == STC_TXCLK_SPDIF_ROOT);
+ fsl_spdif_can_set_clk_rate(spdif_priv, i));
if (savesub == ret)
continue;
@@ -1230,6 +1268,12 @@ static int fsl_spdif_probe(struct platform_device *pdev)
spdif_priv->pdev = pdev;
+ spdif_priv->soc = of_device_get_match_data(&pdev->dev);
+ if (!spdif_priv->soc) {
+ dev_err(&pdev->dev, "failed to get soc data\n");
+ return -ENODEV;
+ }
+
/* Initialize this copy of the CPU DAI driver structure */
memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
spdif_priv->cpu_dai_drv.name = dev_name(&pdev->dev);
@@ -1311,6 +1355,8 @@ static int fsl_spdif_probe(struct platform_device *pdev)
/* Register with ASoC */
dev_set_drvdata(&pdev->dev, spdif_priv);
+ pm_runtime_enable(&pdev->dev);
+ regcache_cache_only(spdif_priv->regmap, true);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_spdif_component,
&spdif_priv->cpu_dai_drv, 1);
@@ -1326,41 +1372,96 @@ static int fsl_spdif_probe(struct platform_device *pdev)
return ret;
}
-#ifdef CONFIG_PM_SLEEP
-static int fsl_spdif_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int fsl_spdif_runtime_suspend(struct device *dev)
{
struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
+ int i;
regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
&spdif_priv->regcache_srpc);
-
regcache_cache_only(spdif_priv->regmap, true);
- regcache_mark_dirty(spdif_priv->regmap);
+
+ clk_disable_unprepare(spdif_priv->rxclk);
+
+ for (i = 0; i < SPDIF_TXRATE_MAX; i++)
+ clk_disable_unprepare(spdif_priv->txclk[i]);
+
+ if (!IS_ERR(spdif_priv->spbaclk))
+ clk_disable_unprepare(spdif_priv->spbaclk);
+ clk_disable_unprepare(spdif_priv->coreclk);
return 0;
}
-static int fsl_spdif_resume(struct device *dev)
+static int fsl_spdif_runtime_resume(struct device *dev)
{
struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
+ int ret;
+ int i;
+
+ ret = clk_prepare_enable(spdif_priv->coreclk);
+ if (ret) {
+ dev_err(dev, "failed to enable core clock\n");
+ return ret;
+ }
+
+ if (!IS_ERR(spdif_priv->spbaclk)) {
+ ret = clk_prepare_enable(spdif_priv->spbaclk);
+ if (ret) {
+ dev_err(dev, "failed to enable spba clock\n");
+ goto disable_core_clk;
+ }
+ }
+
+ for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
+ ret = clk_prepare_enable(spdif_priv->txclk[i]);
+ if (ret)
+ goto disable_tx_clk;
+ }
+
+ ret = clk_prepare_enable(spdif_priv->rxclk);
+ if (ret)
+ goto disable_tx_clk;
regcache_cache_only(spdif_priv->regmap, false);
+ regcache_mark_dirty(spdif_priv->regmap);
regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC,
SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK,
spdif_priv->regcache_srpc);
- return regcache_sync(spdif_priv->regmap);
+ ret = regcache_sync(spdif_priv->regmap);
+ if (ret)
+ goto disable_rx_clk;
+
+ return 0;
+
+disable_rx_clk:
+ clk_disable_unprepare(spdif_priv->rxclk);
+disable_tx_clk:
+ for (i--; i >= 0; i--)
+ clk_disable_unprepare(spdif_priv->txclk[i]);
+ if (!IS_ERR(spdif_priv->spbaclk))
+ clk_disable_unprepare(spdif_priv->spbaclk);
+disable_core_clk:
+ clk_disable_unprepare(spdif_priv->coreclk);
+
+ return ret;
}
-#endif /* CONFIG_PM_SLEEP */
+#endif /* CONFIG_PM */
static const struct dev_pm_ops fsl_spdif_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(fsl_spdif_runtime_suspend, fsl_spdif_runtime_resume,
+ NULL)
};
static const struct of_device_id fsl_spdif_dt_ids[] = {
- { .compatible = "fsl,imx35-spdif", },
- { .compatible = "fsl,vf610-spdif", },
+ { .compatible = "fsl,imx35-spdif", .data = &fsl_spdif_imx35, },
+ { .compatible = "fsl,vf610-spdif", .data = &fsl_spdif_vf610, },
+ { .compatible = "fsl,imx6sx-spdif", .data = &fsl_spdif_imx6sx, },
{}
};
MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 1a2fa7f18142..d8b9c6547142 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -203,12 +203,10 @@ struct fsl_ssi_soc_data {
};
/**
- * fsl_ssi: per-SSI private data
- *
+ * struct fsl_ssi - per-SSI private data
* @regs: Pointer to the regmap registers
* @irq: IRQ of this SSI
* @cpu_dai_drv: CPU DAI driver for this device
- *
* @dai_fmt: DAI configuration this device is currently used with
* @streams: Mask of current active streams: BIT(TX) and BIT(RX)
* @i2s_net: I2S and Network mode configurations of SCR register
@@ -221,38 +219,29 @@ struct fsl_ssi_soc_data {
* @slot_width: Width of each DAI slot
* @slots: Number of slots
* @regvals: Specific RX/TX register settings
- *
* @clk: Clock source to access register
* @baudclk: Clock source to generate bit and frame-sync clocks
* @baudclk_streams: Active streams that are using baudclk
- *
* @regcache_sfcsr: Cache sfcsr register value during suspend and resume
* @regcache_sacnt: Cache sacnt register value during suspend and resume
- *
* @dma_params_tx: DMA transmit parameters
* @dma_params_rx: DMA receive parameters
* @ssi_phys: physical address of the SSI registers
- *
* @fiq_params: FIQ stream filtering parameters
- *
* @card_pdev: Platform_device pointer to register a sound card for PowerPC or
* to register a CODEC platform device for AC97
* @card_name: Platform_device name to register a sound card for PowerPC or
* to register a CODEC platform device for AC97
* @card_idx: The index of SSI to register a sound card for PowerPC or
* to register a CODEC platform device for AC97
- *
* @dbg_stats: Debugging statistics
- *
* @soc: SoC specific data
* @dev: Pointer to &pdev->dev
- *
* @fifo_watermark: The FIFO watermark setting. Notifies DMA when there are
* @fifo_watermark or fewer words in TX fifo or
* @fifo_watermark or more empty words in RX fifo.
* @dma_maxburst: Max number of words to transfer in one go. So far,
* this is always the same as fifo_watermark.
- *
* @ac97_reg_lock: Mutex lock to serialize AC97 register access operations
*/
struct fsl_ssi {
@@ -374,7 +363,9 @@ static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi *ssi)
}
/**
- * Interrupt handler to gather states
+ * fsl_ssi_irq - Interrupt handler to gather states
+ * @irq: irq number
+ * @dev_id: context
*/
static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
{
@@ -395,7 +386,10 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
}
/**
- * Set SCR, SIER, STCR and SRCR registers with cached values in regvals
+ * fsl_ssi_config_enable - Set SCR, SIER, STCR and SRCR registers with
+ * cached values in regvals
+ * @ssi: SSI context
+ * @tx: direction
*
* Notes:
* 1) For offline_config SoCs, enable all necessary bits of both streams
@@ -474,7 +468,7 @@ enable_scr:
ssi->streams |= BIT(dir);
}
-/**
+/*
* Exclude bits that are used by the opposite stream
*
* When both streams are active, disabling some bits for the current stream
@@ -495,7 +489,10 @@ enable_scr:
((vals) & _ssi_xor_shared_bits(vals, avals, aactive))
/**
- * Unset SCR, SIER, STCR and SRCR registers with cached values in regvals
+ * fsl_ssi_config_disable - Unset SCR, SIER, STCR and SRCR registers
+ * with cached values in regvals
+ * @ssi: SSI context
+ * @tx: direction
*
* Notes:
* 1) For offline_config SoCs, to avoid online reconfigurations, disable all
@@ -577,7 +574,9 @@ static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
}
/**
- * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely
+ * fsl_ssi_setup_regvals - Cache critical bits of SIER, SRCR, STCR and
+ * SCR to later set them safely
+ * @ssi: SSI context
*/
static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
{
@@ -630,7 +629,7 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi)
static int fsl_ssi_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
int ret;
@@ -654,16 +653,19 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
clk_disable_unprepare(ssi->clk);
}
/**
- * Configure Digital Audio Interface bit clock
+ * fsl_ssi_set_bclk - Configure Digital Audio Interface bit clock
+ * @substream: ASoC substream
+ * @dai: pointer to DAI
+ * @hw_params: pointers to hw_params
*
- * Note: This function can be only called when using SSI as DAI master
+ * Notes: This function can be only called when using SSI as DAI master
*
* Quick instruction for parameters:
* freq: Output BCLK frequency = samplerate * slots * slot_width
@@ -782,7 +784,10 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
}
/**
- * Configure SSI based on PCM hardware parameters
+ * fsl_ssi_hw_params - Configure SSI based on PCM hardware parameters
+ * @substream: ASoC substream
+ * @hw_params: pointers to hw_params
+ * @dai: pointer to DAI
*
* Notes:
* 1) SxCCR.WL bits are critical bits that require SSI to be temporarily
@@ -858,7 +863,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
if (fsl_ssi_is_i2s_master(ssi) &&
@@ -997,7 +1002,9 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt)
}
/**
- * Configure Digital Audio Interface (DAI) Format
+ * fsl_ssi_set_dai_fmt - Configure Digital Audio Interface (DAI) Format
+ * @dai: pointer to DAI
+ * @fmt: format mask
*/
static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
@@ -1011,7 +1018,12 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
}
/**
- * Set TDM slot number and slot width
+ * fsl_ssi_set_dai_tdm_slot - Set TDM slot number and slot width
+ * @dai: pointer to DAI
+ * @tx_mask: mask for TX
+ * @rx_mask: mask for RX
+ * @slots: number of slots
+ * @slot_width: number of bits per slot
*/
static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
u32 rx_mask, int slots, int slot_width)
@@ -1055,7 +1067,10 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
}
/**
- * Start or stop SSI and corresponding DMA transaction.
+ * fsl_ssi_trigger - Start or stop SSI and corresponding DMA transaction.
+ * @substream: ASoC substream
+ * @cmd: trigger command
+ * @dai: pointer to DAI
*
* The DMA channel is in external master start and pause mode, which
* means the SSI completely controls the flow of data.
@@ -1063,7 +1078,7 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
@@ -1239,7 +1254,8 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
};
/**
- * Initialize SSI registers
+ * fsl_ssi_hw_init - Initialize SSI registers
+ * @ssi: SSI context
*/
static int fsl_ssi_hw_init(struct fsl_ssi *ssi)
{
@@ -1268,7 +1284,8 @@ static int fsl_ssi_hw_init(struct fsl_ssi *ssi)
}
/**
- * Clear SSI registers
+ * fsl_ssi_hw_clean - Clear SSI registers
+ * @ssi: SSI context
*/
static void fsl_ssi_hw_clean(struct fsl_ssi *ssi)
{
@@ -1285,7 +1302,8 @@ static void fsl_ssi_hw_clean(struct fsl_ssi *ssi)
regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0);
}
}
-/**
+
+/*
* Make every character in a string lower-case
*/
static void make_lowercase(char *s)
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c
index 2a20ee23dc52..2c46c55f0a88 100644
--- a/sound/soc/fsl/fsl_ssi_dbg.c
+++ b/sound/soc/fsl/fsl_ssi_dbg.c
@@ -78,7 +78,7 @@ void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr)
dbg->stats.tfe0++;
}
-/**
+/*
* Show the statistics of a flag only if its interrupt is enabled
*
* Compilers will optimize it to a no-op if the interrupt is disabled
@@ -90,7 +90,7 @@ void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr)
} while (0)
-/**
+/*
* Display the statistics for the current SSI device
*
* To avoid confusion, only show those counts that are enabled
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
index e09b45de0efd..202fb8950078 100644
--- a/sound/soc/fsl/imx-audmix.c
+++ b/sound/soc/fsl/imx-audmix.c
@@ -6,8 +6,8 @@
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * https://www.opensource.org/licenses/gpl-license.html
+ * https://www.gnu.org/copyleft/gpl.html
*/
#include <linux/module.h>
@@ -44,7 +44,7 @@ static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
struct snd_pcm_runtime *runtime = substream->runtime;
struct device *dev = rtd->card->dev;
@@ -73,7 +73,7 @@ static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct device *dev = rtd->card->dev;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
@@ -112,7 +112,7 @@ static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
static int imx_audmix_be_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct device *dev = rtd->card->dev;
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 3ce85a43e08f..25c18b9e348f 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -5,7 +5,7 @@
// Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
//
// Initial development of this code was funded by
-// Phytec Messtechnik GmbH, http://www.phytec.de
+// Phytec Messtechnik GmbH, https://www.phytec.de
#include <linux/clk.h>
#include <linux/debugfs.h>
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index fab2d6c56653..dd9c1ac81cf5 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -26,7 +26,7 @@
static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 3b8c796d7829..9e4f66b6b92b 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -114,7 +114,7 @@ static int psc_dma_hw_free(struct snd_soc_component *component,
static int psc_dma_trigger(struct snd_soc_component *component,
struct snd_pcm_substream *substream, int cmd)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct snd_pcm_runtime *runtime = substream->runtime;
struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
@@ -216,7 +216,7 @@ static int psc_dma_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct psc_dma_stream *s;
int rc;
@@ -244,7 +244,7 @@ static int psc_dma_open(struct snd_soc_component *component,
static int psc_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct psc_dma_stream *s;
@@ -270,7 +270,7 @@ static snd_pcm_uframes_t
psc_dma_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct psc_dma_stream *s;
dma_addr_t count;
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 1ab4fbda08cb..3149d59ae968 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -38,7 +38,7 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
u32 mode;
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index f7bd90051ce7..eccc833390d4 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -98,7 +98,7 @@ static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
*/
static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct mpc8610_hpcd_data *machine_data =
container_of(rtd->card, struct mpc8610_hpcd_data, card);
struct device *dev = rtd->card->dev;
@@ -426,9 +426,11 @@ static int __init mpc8610_hpcd_init(void)
guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts");
if (of_address_to_resource(guts_np, 0, &res)) {
pr_err("mpc8610-hpcd: missing/invalid global utilities node\n");
+ of_node_put(guts_np);
return -EINVAL;
}
guts_phys = res.start;
+ of_node_put(guts_np);
return platform_driver_register(&mpc8610_hpcd_driver);
}
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index a36d4e8cd55c..4ead537e090a 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -36,7 +36,7 @@ static int mx27vis_amp_muter_gpio;
static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
int ret;
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index fe3091590f20..ac68d2238045 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -121,7 +121,7 @@ static int p1022_ds_machine_probe(struct snd_soc_card *card)
*/
static int p1022_ds_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct machine_data *mdata =
container_of(rtd->card, struct machine_data, card);
struct device *dev = rtd->card->dev;
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
index f5374fe354ab..714515b8081f 100644
--- a/sound/soc/fsl/p1022_rdk.c
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -127,7 +127,7 @@ static int p1022_rdk_machine_probe(struct snd_soc_card *card)
*/
static int p1022_rdk_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct machine_data *mdata =
container_of(rtd->card, struct machine_data, card);
struct device *dev = rtd->card->dev;
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index 8b1551c55452..99611a037ada 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -75,7 +75,7 @@ static const struct _wm8350_audio wm8350_audio[] = {
static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
int i, found = 0;