diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/adi,axi-i2s.txt | 7 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/sound/renesas,rsnd.txt | 7 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/sound/rt5651.txt | 5 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/sound/simple-amplifier.txt | 2 | ||||
-rw-r--r-- | sound/soc/adi/axi-i2s.c | 68 | ||||
-rw-r--r-- | sound/soc/codecs/nau8810.c | 24 | ||||
-rw-r--r-- | sound/soc/codecs/rt5651.c | 47 | ||||
-rw-r--r-- | sound/soc/codecs/rt5651.h | 1 | ||||
-rw-r--r-- | sound/soc/codecs/simple-amplifier.c | 3 | ||||
-rw-r--r-- | sound/soc/generic/audio-graph-card.c | 64 | ||||
-rw-r--r-- | sound/soc/generic/simple-card.c | 43 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5651.c | 22 | ||||
-rw-r--r-- | sound/soc/qcom/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/soc-topology.c | 14 | ||||
-rw-r--r-- | sound/soc/stm/stm32_i2s.c | 25 | ||||
-rw-r--r-- | sound/soc/stm/stm32_spdifrx.c | 42 | ||||
-rw-r--r-- | sound/soc/ti/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/ti/ams-delta.c | 2 | ||||
-rw-r--r-- | sound/soc/ti/davinci-mcasp.c | 2 | ||||
-rw-r--r-- | sound/soc/ti/edma-pcm.c | 5 | ||||
-rw-r--r-- | sound/soc/ti/sdma-pcm.c | 9 |
21 files changed, 274 insertions, 124 deletions
diff --git a/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt b/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt index 4248b662deff..229ad1392cdc 100644 --- a/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt +++ b/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt @@ -1,5 +1,8 @@ ADI AXI-I2S controller +The core can be generated with transmit (playback), only receive +(capture) or both directions enabled. + Required properties: - compatible : Must be "adi,axi-i2s-1.00.a" - reg : Must contain I2S core's registers location and length @@ -9,8 +12,8 @@ Required properties: - clock-names : "axi" for the clock to the AXI interface, "ref" for the sample rate reference clock. - dmas: Pairs of phandle and specifier for the DMA channels that are used by - the core. The core expects two dma channels, one for transmit and one for - receive. + the core. The core expects two dma channels if both transmit and receive are + enabled, one channel otherwise. - dma-names : "tx" for the transmit channel, "rx" for the receive channel. For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 648d43e1b1e9..b34afa66fb00 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -282,7 +282,12 @@ Required properties: - reg : Should contain the register physical address. required register is SRU/ADG/SSI if generation1 - SRU/ADG/SSIU/SSI if generation2 + SRU/ADG/SSIU/SSI/AUDIO-DMAC-periperi if generation2/generation3 + Select extended AUDIO-DMAC-periperi address if SoC has it, + otherwise select normal AUDIO-DMAC-periperi address. +- reg-names : Should contain the register names. + scu/adg/ssi if generation1 + scu/adg/ssiu/ssi/audmapp if generation2/generation3 - rcar_sound,ssi : Should contain SSI feature. The number of SSI subnode should be same as HW. see below for detail. diff --git a/Documentation/devicetree/bindings/sound/rt5651.txt b/Documentation/devicetree/bindings/sound/rt5651.txt index a41199a5cd79..56e736a1cba9 100644 --- a/Documentation/devicetree/bindings/sound/rt5651.txt +++ b/Documentation/devicetree/bindings/sound/rt5651.txt @@ -22,6 +22,11 @@ Optional properties: 2: Use JD1_2 pin for jack-detect 3: Use JD2 pin for jack-detect +- realtek,jack-detect-not-inverted + bool. Normal jack-detect switches give an inverted (active-low) signal, + set this bool in the rare case you've a jack-detect switch which is not + inverted. + - realtek,over-current-threshold-microamp u32, micbias over-current detection threshold in µA, valid values are 600, 1500 and 2000µA. diff --git a/Documentation/devicetree/bindings/sound/simple-amplifier.txt b/Documentation/devicetree/bindings/sound/simple-amplifier.txt index 7182ac4f1e65..b1b097cc9b68 100644 --- a/Documentation/devicetree/bindings/sound/simple-amplifier.txt +++ b/Documentation/devicetree/bindings/sound/simple-amplifier.txt @@ -2,9 +2,9 @@ Simple Amplifier Audio Driver Required properties: - compatible : "dioo,dio2125" or "simple-audio-amplifier" -- enable-gpios : the gpio connected to the enable pin of the simple amplifier Optional properties: +- enable-gpios : the gpio connected to the enable pin of the simple amplifier - VCC-supply : power supply for the device, as covered in Documentation/devicetree/bindings/regulator/regulator.txt diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c index 4c23381727a1..273c543e8ff3 100644 --- a/sound/soc/adi/axi-i2s.c +++ b/sound/soc/adi/axi-i2s.c @@ -43,6 +43,9 @@ struct axi_i2s { struct clk *clk; struct clk *clk_ref; + bool has_capture; + bool has_playback; + struct snd_soc_dai_driver dai_driver; struct snd_dmaengine_dai_dma_data capture_dma_data; @@ -136,8 +139,10 @@ static int axi_i2s_dai_probe(struct snd_soc_dai *dai) { struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); - snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, - &i2s->capture_dma_data); + snd_soc_dai_init_dma_data( + dai, + i2s->has_playback ? &i2s->playback_dma_data : NULL, + i2s->has_capture ? &i2s->capture_dma_data : NULL); return 0; } @@ -151,18 +156,6 @@ static const struct snd_soc_dai_ops axi_i2s_dai_ops = { static struct snd_soc_dai_driver axi_i2s_dai = { .probe = axi_i2s_dai_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE, - }, .ops = &axi_i2s_dai_ops, .symmetric_rates = 1, }; @@ -178,6 +171,19 @@ static const struct regmap_config axi_i2s_regmap_config = { .max_register = AXI_I2S_REG_STATUS, }; +static void axi_i2s_parse_of(struct axi_i2s *i2s, const struct device_node *np) +{ + struct property *dma_names; + const char *dma_name; + + of_property_for_each_string(np, "dma-names", dma_names, dma_name) { + if (strcmp(dma_name, "rx") == 0) + i2s->has_capture = true; + if (strcmp(dma_name, "tx") == 0) + i2s->has_playback = true; + } +} + static int axi_i2s_probe(struct platform_device *pdev) { struct resource *res; @@ -191,6 +197,8 @@ static int axi_i2s_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2s); + axi_i2s_parse_of(i2s, pdev->dev.of_node); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) @@ -213,13 +221,29 @@ static int axi_i2s_probe(struct platform_device *pdev) if (ret) return ret; - i2s->playback_dma_data.addr = res->start + AXI_I2S_REG_TX_FIFO; - i2s->playback_dma_data.addr_width = 4; - i2s->playback_dma_data.maxburst = 1; + if (i2s->has_playback) { + axi_i2s_dai.playback.channels_min = 2; + axi_i2s_dai.playback.channels_max = 2; + axi_i2s_dai.playback.rates = SNDRV_PCM_RATE_KNOT; + axi_i2s_dai.playback.formats = + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE; + + i2s->playback_dma_data.addr = res->start + AXI_I2S_REG_TX_FIFO; + i2s->playback_dma_data.addr_width = 4; + i2s->playback_dma_data.maxburst = 1; + } + + if (i2s->has_capture) { + axi_i2s_dai.capture.channels_min = 2; + axi_i2s_dai.capture.channels_max = 2; + axi_i2s_dai.capture.rates = SNDRV_PCM_RATE_KNOT; + axi_i2s_dai.capture.formats = + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE; - i2s->capture_dma_data.addr = res->start + AXI_I2S_REG_RX_FIFO; - i2s->capture_dma_data.addr_width = 4; - i2s->capture_dma_data.maxburst = 1; + i2s->capture_dma_data.addr = res->start + AXI_I2S_REG_RX_FIFO; + i2s->capture_dma_data.addr_width = 4; + i2s->capture_dma_data.maxburst = 1; + } i2s->ratnum.num = clk_get_rate(i2s->clk_ref) / 2 / AXI_I2S_BITS_PER_FRAME; i2s->ratnum.den_step = 1; @@ -240,6 +264,10 @@ static int axi_i2s_probe(struct platform_device *pdev) if (ret) goto err_clk_disable; + dev_info(&pdev->dev, "probed, capture %s, playback %s\n", + i2s->has_capture ? "enabled" : "disabled", + i2s->has_playback ? "enabled" : "disabled"); + return 0; err_clk_disable: diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index 645aa0794123..125e205e6687 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -493,7 +493,7 @@ static int nau8810_set_sysclk(struct snd_soc_dai *dai, return 0; } -static int nau88l0_calc_pll(unsigned int pll_in, +static int nau8810_calc_pll(unsigned int pll_in, unsigned int fs, struct nau8810_pll *pll_param) { u64 f2, f2_max, pll_ratio; @@ -505,7 +505,7 @@ static int nau88l0_calc_pll(unsigned int pll_in, f2_max = 0; scal_sel = ARRAY_SIZE(nau8810_mclk_scaler); for (i = 0; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) { - f2 = 256 * fs * 4 * nau8810_mclk_scaler[i] / 10; + f2 = 256ULL * fs * 4 * nau8810_mclk_scaler[i] / 10; if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX && f2_max < f2) { f2_max = f2; @@ -542,7 +542,7 @@ static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id, int ret, fs; fs = freq_out / 256; - ret = nau88l0_calc_pll(freq_in, fs, pll_param); + ret = nau8810_calc_pll(freq_in, fs, pll_param); if (ret < 0) { dev_err(nau8810->dev, "Unsupported input clock %d\n", freq_in); return ret; @@ -667,6 +667,24 @@ static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component); int val_len = 0, val_rate = 0, ret = 0; + unsigned int ctrl_val, bclk_fs, bclk_div; + + /* Select BCLK configuration if the codec as master. */ + regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &ctrl_val); + if (ctrl_val & NAU8810_CLKIO_MASTER) { + /* get the bclk and fs ratio */ + bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params); + if (bclk_fs <= 32) + bclk_div = NAU8810_BCLKDIV_8; + else if (bclk_fs <= 64) + bclk_div = NAU8810_BCLKDIV_4; + else if (bclk_fs <= 128) + bclk_div = NAU8810_BCLKDIV_2; + else + return -EINVAL; + regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, + NAU8810_BCLKSEL_MASK, bclk_div); + } switch (params_width(params)) { case 16: diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 29b2d60076b0..cb8252ff31cb 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1645,7 +1645,10 @@ static bool rt5651_jack_inserted(struct snd_soc_component *component) break; } - return val == 0; + if (rt5651->jd_active_high) + return val != 0; + else + return val == 0; } /* Jack detect and button-press timings */ @@ -1868,20 +1871,47 @@ static void rt5651_enable_jack_detect(struct snd_soc_component *component, case RT5651_JD1_1: snd_soc_component_update_bits(component, RT5651_JD_CTRL2, RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_1); - snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1, - RT5651_JD1_1_IRQ_EN, RT5651_JD1_1_IRQ_EN); + /* active-low is normal, set inv flag for active-high */ + if (rt5651->jd_active_high) + snd_soc_component_update_bits(component, + RT5651_IRQ_CTRL1, + RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV, + RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV); + else + snd_soc_component_update_bits(component, + RT5651_IRQ_CTRL1, + RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV, + RT5651_JD1_1_IRQ_EN); break; case RT5651_JD1_2: snd_soc_component_update_bits(component, RT5651_JD_CTRL2, RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_2); - snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1, - RT5651_JD1_2_IRQ_EN, RT5651_JD1_2_IRQ_EN); + /* active-low is normal, set inv flag for active-high */ + if (rt5651->jd_active_high) + snd_soc_component_update_bits(component, + RT5651_IRQ_CTRL1, + RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV, + RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV); + else + snd_soc_component_update_bits(component, + RT5651_IRQ_CTRL1, + RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV, + RT5651_JD1_2_IRQ_EN); break; case RT5651_JD2: snd_soc_component_update_bits(component, RT5651_JD_CTRL2, RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD2); - snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1, - RT5651_JD2_IRQ_EN, RT5651_JD2_IRQ_EN); + /* active-low is normal, set inv flag for active-high */ + if (rt5651->jd_active_high) + snd_soc_component_update_bits(component, + RT5651_IRQ_CTRL1, + RT5651_JD2_IRQ_EN | RT5651_JD2_INV, + RT5651_JD2_IRQ_EN | RT5651_JD2_INV); + else + snd_soc_component_update_bits(component, + RT5651_IRQ_CTRL1, + RT5651_JD2_IRQ_EN | RT5651_JD2_INV, + RT5651_JD2_IRQ_EN); break; default: dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n"); @@ -1986,6 +2016,9 @@ static void rt5651_apply_properties(struct snd_soc_component *component) "realtek,jack-detect-source", &val) == 0) rt5651->jd_src = val; + if (device_property_read_bool(component->dev, "realtek,jack-detect-not-inverted")) + rt5651->jd_active_high = true; + /* * Testing on various boards has shown that good defaults for the OVCD * threshold and scale-factor are 2000µA and 0.75. For an effective diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h index 41fcb8b5eb40..05b0f6f8b95d 100644 --- a/sound/soc/codecs/rt5651.h +++ b/sound/soc/codecs/rt5651.h @@ -2083,6 +2083,7 @@ struct rt5651_priv { int release_count; int poll_count; unsigned int jd_src; + bool jd_active_high; unsigned int ovcd_th; unsigned int ovcd_sf; diff --git a/sound/soc/codecs/simple-amplifier.c b/sound/soc/codecs/simple-amplifier.c index c07e8a80b4b7..351aa55c384e 100644 --- a/sound/soc/codecs/simple-amplifier.c +++ b/sound/soc/codecs/simple-amplifier.c @@ -89,7 +89,8 @@ static int simple_amp_probe(struct platform_device *pdev) return -ENOMEM; platform_set_drvdata(pdev, priv); - priv->gpiod_enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); + priv->gpiod_enable = devm_gpiod_get_optional(dev, "enable", + GPIOD_OUT_LOW); if (IS_ERR(priv->gpiod_enable)) { err = PTR_ERR(priv->gpiod_enable); if (err != -EPROBE_DEFER) diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index bb12351330e8..7dd772a895e2 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -176,9 +176,9 @@ static int graph_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static void graph_get_conversion(struct device *dev, - struct device_node *ep, - struct asoc_simple_card_data *adata) +static void graph_parse_convert(struct device *dev, + struct device_node *ep, + struct asoc_simple_card_data *adata) { struct device_node *top = dev->of_node; struct device_node *port = of_get_parent(ep); @@ -190,6 +190,28 @@ static void graph_get_conversion(struct device *dev, asoc_simple_card_parse_convert(dev, ports, NULL, adata); asoc_simple_card_parse_convert(dev, port, NULL, adata); asoc_simple_card_parse_convert(dev, ep, NULL, adata); + + of_node_put(port); + of_node_put(ports); + of_node_put(node); +} + +static void graph_parse_mclk_fs(struct device_node *top, + struct device_node *ep, + struct graph_dai_props *props) +{ + struct device_node *port = of_get_parent(ep); + struct device_node *ports = of_get_parent(port); + struct device_node *node = of_graph_get_port_parent(ep); + + of_property_read_u32(top, "mclk-fs", &props->mclk_fs); + of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); + of_property_read_u32(port, "mclk-fs", &props->mclk_fs); + of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); + + of_node_put(port); + of_node_put(ports); + of_node_put(node); } static int graph_dai_link_of_dpcm(struct graph_priv *priv, @@ -222,13 +244,6 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv, dev_dbg(dev, "link_of DPCM (%pOF)\n", ep); - of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(ports, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(port, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs); - - graph_get_conversion(dev, ep, &dai_props->adata); - of_node_put(ports); of_node_put(port); of_node_put(node); @@ -307,6 +322,9 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv, "prefix"); } + graph_parse_convert(dev, ep, &dai_props->adata); + graph_parse_mclk_fs(top, ep, dai_props); + asoc_simple_card_canonicalize_platform(dai_link); ret = asoc_simple_card_of_parse_tdm(ep, dai); @@ -335,10 +353,6 @@ static int graph_dai_link_of(struct graph_priv *priv, struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, li->link); struct graph_dai_props *dai_props = graph_priv_to_props(priv, li->link); struct device_node *top = dev->of_node; - struct device_node *cpu_port; - struct device_node *cpu_ports; - struct device_node *codec_port; - struct device_node *codec_ports; struct asoc_simple_dai *cpu_dai; struct asoc_simple_dai *codec_dai; int ret; @@ -347,11 +361,6 @@ static int graph_dai_link_of(struct graph_priv *priv, if (!li->cpu) return 0; - cpu_port = of_get_parent(cpu_ep); - cpu_ports = of_get_parent(cpu_port); - codec_port = of_get_parent(codec_ep); - codec_ports = of_get_parent(codec_port); - dev_dbg(dev, "link_of (%pOF)\n", cpu_ep); li->link++; @@ -362,17 +371,8 @@ static int graph_dai_link_of(struct graph_priv *priv, dai_props->codec_dai = &priv->dais[li->dais++]; /* Factor to mclk, used in hw_params() */ - of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(cpu_ports, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(codec_ports, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(cpu_port, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(codec_port, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs); - of_node_put(cpu_port); - of_node_put(cpu_ports); - of_node_put(codec_port); - of_node_put(codec_ports); + graph_parse_mclk_fs(top, cpu_ep, dai_props); + graph_parse_mclk_fs(top, codec_ep, dai_props); ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &dai_link->dai_fmt); @@ -462,8 +462,8 @@ static int graph_for_each_link(struct graph_priv *priv, /* get convert-xxx property */ memset(&adata, 0, sizeof(adata)); - graph_get_conversion(dev, codec_ep, &adata); - graph_get_conversion(dev, cpu_ep, &adata); + graph_parse_convert(dev, codec_ep, &adata); + graph_parse_convert(dev, cpu_ep, &adata); /* * It is DPCM diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 7147bba45a2a..b792638a11c8 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -172,9 +172,9 @@ static int simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static void simple_get_conversion(struct device *dev, - struct device_node *np, - struct asoc_simple_card_data *adata) +static void simple_parse_convert(struct device *dev, + struct device_node *np, + struct asoc_simple_card_data *adata) { struct device_node *top = dev->of_node; struct device_node *node = of_get_parent(np); @@ -187,6 +187,26 @@ static void simple_get_conversion(struct device *dev, of_node_put(node); } +static void simple_parse_mclk_fs(struct device_node *top, + struct device_node *cpu, + struct device_node *codec, + struct simple_dai_props *props, + char *prefix) +{ + struct device_node *node = of_get_parent(cpu); + char prop[128]; + + snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX); + of_property_read_u32(top, prop, &props->mclk_fs); + + snprintf(prop, sizeof(prop), "%smclk-fs", prefix); + of_property_read_u32(node, prop, &props->mclk_fs); + of_property_read_u32(cpu, prop, &props->mclk_fs); + of_property_read_u32(codec, prop, &props->mclk_fs); + + of_node_put(node); +} + static int simple_dai_link_of_dpcm(struct simple_priv *priv, struct device_node *np, struct device_node *codec, @@ -200,7 +220,6 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv, struct snd_soc_dai_link_component *codecs = dai_link->codecs; struct device_node *top = dev->of_node; struct device_node *node = of_get_parent(np); - char prop[128]; char *prefix = ""; int ret; @@ -295,7 +314,8 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv, "prefix"); } - simple_get_conversion(dev, np, &dai_props->adata); + simple_parse_convert(dev, np, &dai_props->adata); + simple_parse_mclk_fs(top, np, codec, dai_props, prefix); asoc_simple_card_canonicalize_platform(dai_link); @@ -303,11 +323,6 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv, if (ret) return ret; - snprintf(prop, sizeof(prop), "%smclk-fs", prefix); - of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(node, prop, &dai_props->mclk_fs); - of_property_read_u32(np, prop, &dai_props->mclk_fs); - ret = asoc_simple_card_parse_daifmt(dev, node, codec, prefix, &dai_link->dai_fmt); if (ret < 0) @@ -372,11 +387,7 @@ static int simple_dai_link_of(struct simple_priv *priv, if (ret < 0) goto dai_link_of_err; - snprintf(prop, sizeof(prop), "%smclk-fs", prefix); - of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); - of_property_read_u32(node, prop, &dai_props->mclk_fs); - of_property_read_u32(cpu, prop, &dai_props->mclk_fs); - of_property_read_u32(codec, prop, &dai_props->mclk_fs); + simple_parse_mclk_fs(top, cpu, codec, dai_props, prefix); ret = asoc_simple_card_parse_cpu(cpu, dai_link, DAI, CELL, &single_cpu); @@ -471,7 +482,7 @@ static int simple_for_each_link(struct simple_priv *priv, /* get convert-xxx property */ memset(&adata, 0, sizeof(adata)); for_each_child_of_node(node, np) - simple_get_conversion(dev, np, &adata); + simple_parse_convert(dev, np, &adata); /* loop for all CPU/Codec node */ for_each_child_of_node(node, np) { diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index b0a4d297176e..4ed59f41ee83 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -79,14 +79,15 @@ enum { #define BYT_RT5651_SSP0_AIF2 BIT(21) #define BYT_RT5651_HP_LR_SWAPPED BIT(22) #define BYT_RT5651_MONO_SPEAKER BIT(23) +#define BYT_RT5651_JD_NOT_INV BIT(24) #define BYT_RT5651_DEFAULT_QUIRKS (BYT_RT5651_MCLK_EN | \ BYT_RT5651_JD1_1 | \ BYT_RT5651_OVCD_TH_2000UA | \ BYT_RT5651_OVCD_SF_0P75) -/* jack-detect-source + dmic-en + ovcd-th + -sf + terminating empty entry */ -#define MAX_NO_PROPS 5 +/* jack-detect-source + inv + dmic-en + ovcd-th + -sf + terminating entry */ +#define MAX_NO_PROPS 6 struct byt_rt5651_private { struct clk *mclk; @@ -137,6 +138,8 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk SSP0_AIF2 enabled\n"); if (byt_rt5651_quirk & BYT_RT5651_MONO_SPEAKER) dev_info(dev, "quirk MONO_SPEAKER enabled\n"); + if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV) + dev_info(dev, "quirk JD_NOT_INV enabled\n"); } #define BYT_CODEC_DAI1 "rt5651-aif1" @@ -415,6 +418,18 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { BYT_RT5651_MONO_SPEAKER), }, { + /* Complet Electro Serv MY8307 */ + .callback = byt_rt5651_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Complet Electro Serv"), + DMI_MATCH(DMI_PRODUCT_NAME, "MY8307"), + }, + .driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS | + BYT_RT5651_IN2_MAP | + BYT_RT5651_MONO_SPEAKER | + BYT_RT5651_JD_NOT_INV), + }, + { /* I.T.Works TW701, Ployer Momo7w and Trekstor ST70416-6 * (these all use the same mainboard) */ .callback = byt_rt5651_quirk_cb, @@ -525,6 +540,9 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev) if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN) props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en"); + if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV) + props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted"); + return device_add_properties(i2c_dev, props); } diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 75ceb04d8bf0..b1764af858ba 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -98,7 +98,7 @@ config SND_SOC_MSM8996 config SND_SOC_SDM845 tristate "SoC Machine driver for SDM845 boards" - depends on QCOM_APR && MFD_CROS_EC + depends on QCOM_APR && MFD_CROS_EC && I2C select SND_SOC_QDSP6 select SND_SOC_QCOM_COMMON select SND_SOC_RT5663 diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 25fca7055464..fbee4720b834 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -894,19 +894,20 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, continue; } + /* create any TLV data */ + soc_tplg_create_tlv(tplg, &kc, &mc->hdr); + /* pass control to driver for optional further init */ err = soc_tplg_init_kcontrol(tplg, &kc, (struct snd_soc_tplg_ctl_hdr *) mc); if (err < 0) { dev_err(tplg->dev, "ASoC: failed to init %s\n", mc->hdr.name); + soc_tplg_free_tlv(tplg, &kc); kfree(sm); continue; } - /* create any TLV data */ - soc_tplg_create_tlv(tplg, &kc, &mc->hdr); - /* register control here */ err = soc_tplg_add_kcontrol(tplg, &kc, &sm->dobj.control.kcontrol); @@ -1324,18 +1325,19 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( continue; } + /* create any TLV data */ + soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr); + /* pass control to driver for optional further init */ err = soc_tplg_init_kcontrol(tplg, &kc[i], (struct snd_soc_tplg_ctl_hdr *)mc); if (err < 0) { dev_err(tplg->dev, "ASoC: failed to init %s\n", mc->hdr.name); + soc_tplg_free_tlv(tplg, &kc[i]); kfree(sm); continue; } - - /* create any TLV data */ - soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr); } return kc; diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 8968458eec62..952634258b02 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -179,7 +179,6 @@ enum i2s_datlen { I2S_I2SMOD_DATLEN_32, }; -#define STM32_I2S_DAI_NAME_SIZE 20 #define STM32_I2S_FIFO_SIZE 16 #define STM32_I2S_IS_MASTER(x) ((x)->ms_flg == I2S_MS_MASTER) @@ -202,7 +201,6 @@ enum i2s_datlen { * @phys_addr: I2S registers physical base address * @lock_fd: lock to manage race conditions in full duplex mode * @irq_lock: prevent race condition with IRQ - * @dais_name: DAI name * @mclk_rate: master clock frequency (Hz) * @fmt: DAI protocol * @refcount: keep count of opened streams on I2S @@ -224,7 +222,6 @@ struct stm32_i2s_data { dma_addr_t phys_addr; spinlock_t lock_fd; /* Manage race conditions for full duplex */ spinlock_t irq_lock; /* used to prevent race condition with IRQ */ - char dais_name[STM32_I2S_DAI_NAME_SIZE]; unsigned int mclk_rate; unsigned int fmt; int refcount; @@ -495,12 +492,6 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai, unsigned int fthlv; int ret; - if ((params_channels(params) == 1) && - ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A)) { - dev_err(cpu_dai->dev, "Mono mode supported only by DSP_A\n"); - return -EINVAL; - } - switch (format) { case 16: cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_16); @@ -550,6 +541,10 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream, i2s->substream = substream; spin_unlock_irqrestore(&i2s->irq_lock, flags); + if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A) + snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, 2); + ret = clk_prepare_enable(i2s->i2sclk); if (ret < 0) { dev_err(cpu_dai->dev, "Failed to enable clock: %d\n", ret); @@ -592,7 +587,8 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* Enable i2s */ - dev_dbg(cpu_dai->dev, "start I2S\n"); + dev_dbg(cpu_dai->dev, "start I2S %s\n", + playback_flg ? "playback" : "capture"); cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, @@ -637,6 +633,9 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + dev_dbg(cpu_dai->dev, "stop I2S %s\n", + playback_flg ? "playback" : "capture"); + if (playback_flg) regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, I2S_IER_UDRIE, @@ -653,8 +652,6 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd, break; } - dev_dbg(cpu_dai->dev, "stop I2S\n"); - ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, I2S_CR1_SPE, 0); if (ret < 0) { @@ -770,12 +767,8 @@ static int stm32_i2s_dais_init(struct platform_device *pdev, if (!dai_ptr) return -ENOMEM; - snprintf(i2s->dais_name, STM32_I2S_DAI_NAME_SIZE, - "%s", dev_name(&pdev->dev)); - dai_ptr->probe = stm32_i2s_dai_probe; dai_ptr->ops = &stm32_i2s_pcm_dai_ops; - dai_ptr->name = i2s->dais_name; dai_ptr->id = 1; stm32_i2s_dai_init(&dai_ptr->playback, "playback"); stm32_i2s_dai_init(&dai_ptr->capture, "capture"); diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 373df4f24be1..b4c3d983e195 100644 --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -21,6 +21,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/of_platform.h> +#include <linux/pinctrl/consumer.h> #include <linux/regmap.h> #include <linux/reset.h> @@ -471,6 +472,8 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx) memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB); memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB); + pinctrl_pm_select_default_state(&spdifrx->pdev->dev); + ret = stm32_spdifrx_dma_ctrl_start(spdifrx); if (ret < 0) return ret; @@ -502,6 +505,7 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx) end: clk_disable_unprepare(spdifrx->kclk); + pinctrl_pm_select_sleep_state(&spdifrx->pdev->dev); return ret; } @@ -611,10 +615,15 @@ static bool stm32_spdifrx_readable_reg(struct device *dev, unsigned int reg) static bool stm32_spdifrx_volatile_reg(struct device *dev, unsigned int reg) { - if (reg == STM32_SPDIFRX_DR) + switch (reg) { + case STM32_SPDIFRX_DR: + case STM32_SPDIFRX_CSR: + case STM32_SPDIFRX_SR: + case STM32_SPDIFRX_DIR: return true; - - return false; + default: + return false; + } } static bool stm32_spdifrx_writeable_reg(struct device *dev, unsigned int reg) @@ -638,6 +647,7 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = { .volatile_reg = stm32_spdifrx_volatile_reg, .writeable_reg = stm32_spdifrx_writeable_reg, .fast_io = true, + .cache_type = REGCACHE_FLAT, }; static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) @@ -983,10 +993,36 @@ static int stm32_spdifrx_remove(struct platform_device *pdev) MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids); +#ifdef CONFIG_PM_SLEEP +static int stm32_spdifrx_suspend(struct device *dev) +{ + struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev); + + regcache_cache_only(spdifrx->regmap, true); + regcache_mark_dirty(spdifrx->regmap); + + return 0; +} + +static int stm32_spdifrx_resume(struct device *dev) +{ + struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev); + + regcache_cache_only(spdifrx->regmap, false); + + return regcache_sync(spdifrx->regmap); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops stm32_spdifrx_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(stm32_spdifrx_suspend, stm32_spdifrx_resume) +}; + static struct platform_driver stm32_spdifrx_driver = { .driver = { .name = "st,stm32-spdifrx", .of_match_table = stm32_spdifrx_ids, + .pm = &stm32_spdifrx_pm_ops, }, .probe = stm32_spdifrx_probe, .remove = stm32_spdifrx_remove, diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig index 4bf3c15d4e51..ee7c202c69b7 100644 --- a/sound/soc/ti/Kconfig +++ b/sound/soc/ti/Kconfig @@ -21,8 +21,8 @@ config SND_SOC_DAVINCI_ASP config SND_SOC_DAVINCI_MCASP tristate "Multichannel Audio Serial Port (McASP) support" - select SND_SOC_TI_EDMA_PCM if TI_EDMA - select SND_SOC_TI_SDMA_PCM if DMA_OMAP + select SND_SOC_TI_EDMA_PCM + select SND_SOC_TI_SDMA_PCM help Say Y or M here if you want to have support for McASP IP found in various Texas Instruments SoCs like: diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index 4dce494dfbd3..b9611db14c86 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -200,7 +200,7 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, return 0; } -static const SOC_ENUM_SINGLE_EXT_DECL(ams_delta_audio_enum, +static SOC_ENUM_SINGLE_EXT_DECL(ams_delta_audio_enum, ams_delta_audio_mode); static const struct snd_kcontrol_new ams_delta_audio_controls[] = { diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index a3a67a8f0f54..9fbc759fdefe 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -45,6 +45,7 @@ #define MCASP_MAX_AFIFO_DEPTH 64 +#ifdef CONFIG_PM static u32 context_regs[] = { DAVINCI_MCASP_TXFMCTL_REG, DAVINCI_MCASP_RXFMCTL_REG, @@ -68,6 +69,7 @@ struct davinci_mcasp_context { u32 *xrsr_regs; /* for serializer configuration */ bool pm_state; }; +#endif struct davinci_mcasp_ruledata { struct davinci_mcasp *mcasp; diff --git a/sound/soc/ti/edma-pcm.c b/sound/soc/ti/edma-pcm.c index 59e588abe54b..fdffb801b185 100644 --- a/sound/soc/ti/edma-pcm.c +++ b/sound/soc/ti/edma-pcm.c @@ -23,7 +23,6 @@ #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> -#include <linux/edma.h> #include "edma-pcm.h" @@ -43,14 +42,12 @@ static const struct snd_pcm_hardware edma_pcm_hardware = { static const struct snd_dmaengine_pcm_config edma_dmaengine_pcm_config = { .pcm_hardware = &edma_pcm_hardware, .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, - .compat_filter_fn = edma_filter_fn, .prealloc_buffer_size = 128 * 1024, }; int edma_pcm_platform_register(struct device *dev) { - return devm_snd_dmaengine_pcm_register(dev, &edma_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_COMPAT); + return devm_snd_dmaengine_pcm_register(dev, &edma_dmaengine_pcm_config, 0); } EXPORT_SYMBOL_GPL(edma_pcm_platform_register); diff --git a/sound/soc/ti/sdma-pcm.c b/sound/soc/ti/sdma-pcm.c index 21a9c2499d48..a236350beb10 100644 --- a/sound/soc/ti/sdma-pcm.c +++ b/sound/soc/ti/sdma-pcm.c @@ -11,7 +11,6 @@ #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> -#include <linux/omap-dmaengine.h> #include "sdma-pcm.h" @@ -31,7 +30,6 @@ static const struct snd_pcm_hardware sdma_pcm_hardware = { static const struct snd_dmaengine_pcm_config sdma_dmaengine_pcm_config = { .pcm_hardware = &sdma_pcm_hardware, .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, - .compat_filter_fn = omap_dma_filter_fn, .prealloc_buffer_size = 128 * 1024, }; @@ -39,13 +37,12 @@ int sdma_pcm_platform_register(struct device *dev, char *txdmachan, char *rxdmachan) { struct snd_dmaengine_pcm_config *config; - unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; + unsigned int flags = 0; /* Standard names for the directions: 'tx' and 'rx' */ if (!txdmachan && !rxdmachan) return devm_snd_dmaengine_pcm_register(dev, - &sdma_dmaengine_pcm_config, - flags); + &sdma_dmaengine_pcm_config, 0); config = devm_kzalloc(dev, sizeof(*config), GFP_KERNEL); if (!config) @@ -65,7 +62,7 @@ int sdma_pcm_platform_register(struct device *dev, config->chan_names[0] = txdmachan; config->chan_names[1] = rxdmachan; - return devm_snd_dmaengine_pcm_register(dev, config, flags); + return devm_snd_dmaengine_pcm_register(dev, config, 0); } EXPORT_SYMBOL_GPL(sdma_pcm_platform_register); |