diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/fsl/eukrea-tlv320.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl-asoc-card.c | 216 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc.c | 103 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc_dma.c | 4 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_audmix.c | 10 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_dma.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_easrc.c | 49 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 34 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 3 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 233 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 78 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi_dbg.c | 4 | ||||
-rw-r--r-- | sound/soc/fsl/imx-audmix.c | 10 | ||||
-rw-r--r-- | sound/soc/fsl/imx-audmux.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/imx-mc13783.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.c | 8 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_psc_i2s.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/mpc8610_hpcd.c | 4 | ||||
-rw-r--r-- | sound/soc/fsl/mx27vis-aic32x4.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/p1022_ds.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/p1022_rdk.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/wm1133-ev1.c | 2 |
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, ®_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, ®_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, ®val); - 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; |