diff options
25 files changed, 202 insertions, 149 deletions
| diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 1358a0ceb4d0..0bc29c4516e7 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -81,7 +81,7 @@ struct snd_compr_stream;  #define SND_SOC_DAIFMT_CBP_CFP		(1 << 12) /* codec clk provider & frame provider */  #define SND_SOC_DAIFMT_CBC_CFP		(2 << 12) /* codec clk consumer & frame provider */  #define SND_SOC_DAIFMT_CBP_CFC		(3 << 12) /* codec clk provider & frame consumer */ -#define SND_SOC_DAIFMT_CBC_CFC		(4 << 12) /* codec clk consumer & frame follower */ +#define SND_SOC_DAIFMT_CBC_CFC		(4 << 12) /* codec clk consumer & frame consumer */  /* previous definitions kept for backwards-compatibility, do not use in new contributions */  #define SND_SOC_DAIFMT_CBM_CFM		SND_SOC_DAIFMT_CBP_CFP diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index f22bb2bdf527..8148b0d22e88 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -235,10 +235,6 @@ static int acp3x_dma_open(struct snd_soc_component *component,  		return ret;  	} -	if (!adata->play_stream && !adata->capture_stream && -	    !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) -		rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); -  	i2s_data->acp3x_base = adata->acp3x_base;  	runtime->private_data = i2s_data;  	return ret; @@ -365,12 +361,6 @@ static int acp3x_dma_close(struct snd_soc_component *component,  		}  	} -	/* Disable ACP irq, when the current stream is being closed and -	 * another stream is also not active. -	 */ -	if (!adata->play_stream && !adata->capture_stream && -		!adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) -		rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);  	return 0;  } diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h index 03fe93913e12..c3f0c8b7545d 100644 --- a/sound/soc/amd/raven/acp3x.h +++ b/sound/soc/amd/raven/acp3x.h @@ -77,6 +77,7 @@  #define ACP_POWER_OFF_IN_PROGRESS	0x03  #define ACP3x_ITER_IRER_SAMP_LEN_MASK	0x38 +#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF  struct acp3x_platform_info {  	u16 play_i2s_instance; diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c index d3536fd6a124..a013a607b3d4 100644 --- a/sound/soc/amd/raven/pci-acp3x.c +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -76,6 +76,19 @@ static int acp3x_reset(void __iomem *acp3x_base)  	return -ETIMEDOUT;  } +static void acp3x_enable_interrupts(void __iomem *acp_base) +{ +	rv_writel(0x01, acp_base + mmACP_EXTERNAL_INTR_ENB); +} + +static void acp3x_disable_interrupts(void __iomem *acp_base) +{ +	rv_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + +		  mmACP_EXTERNAL_INTR_STAT); +	rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_CNTL); +	rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_ENB); +} +  static int acp3x_init(struct acp3x_dev_data *adata)  {  	void __iomem *acp3x_base = adata->acp3x_base; @@ -93,6 +106,7 @@ static int acp3x_init(struct acp3x_dev_data *adata)  		pr_err("ACP3x reset failed\n");  		return ret;  	} +	acp3x_enable_interrupts(acp3x_base);  	return 0;  } @@ -100,6 +114,7 @@ static int acp3x_deinit(void __iomem *acp3x_base)  {  	int ret; +	acp3x_disable_interrupts(acp3x_base);  	/* Reset */  	ret = acp3x_reset(acp3x_base);  	if (ret) { diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c index 34aed80db0eb..37d4600b6f2c 100644 --- a/sound/soc/codecs/ak5558.c +++ b/sound/soc/codecs/ak5558.c @@ -307,7 +307,7 @@ static struct snd_soc_dai_driver ak5558_dai = {  };  static struct snd_soc_dai_driver ak5552_dai = { -	.name = "ak5558-aif", +	.name = "ak5552-aif",  	.capture = {  		.stream_name = "Capture",  		.channels_min = 1, diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index f4067230ac42..88e79b9f52ed 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -261,6 +261,9 @@ static const struct regmap_config cs35l32_regmap = {  	.readable_reg = cs35l32_readable_register,  	.precious_reg = cs35l32_precious_register,  	.cache_type = REGCACHE_RBTREE, + +	.use_single_read = true, +	.use_single_write = true,  };  static int cs35l32_handle_of_data(struct i2c_client *i2c_client, diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 7ad7b733af9b..e8f3dcfd144d 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -1201,6 +1201,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client,  		dev_err(&i2c_client->dev,  			"CS35L33 Device ID (%X). Expected ID %X\n",  			devid, CS35L33_CHIP_ID); +		ret = -EINVAL;  		goto err_enable;  	} diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 110ee2d06358..3d3c3c34dfe2 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -800,6 +800,9 @@ static struct regmap_config cs35l34_regmap = {  	.readable_reg = cs35l34_readable_register,  	.precious_reg = cs35l34_precious_register,  	.cache_type = REGCACHE_RBTREE, + +	.use_single_read = true, +	.use_single_write = true,  };  static int cs35l34_handle_of_data(struct i2c_client *i2c_client, diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index bf982e145e94..77473c226f9e 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -399,6 +399,9 @@ static const struct regmap_config cs42l42_regmap = {  	.reg_defaults = cs42l42_reg_defaults,  	.num_reg_defaults = ARRAY_SIZE(cs42l42_reg_defaults),  	.cache_type = REGCACHE_RBTREE, + +	.use_single_read = true, +	.use_single_write = true,  };  static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, false); diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index c44a5cdb796e..7cdffdf6b8cf 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1175,7 +1175,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client,  	struct cs42l56_platform_data *pdata =  		dev_get_platdata(&i2c_client->dev);  	int ret, i; -	unsigned int devid = 0; +	unsigned int devid;  	unsigned int alpha_rev, metal_rev;  	unsigned int reg; @@ -1245,6 +1245,11 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client,  	}  	ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, ®); +	if (ret) { +		dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret); +		return ret; +	} +  	devid = reg & CS42L56_CHIP_ID_MASK;  	if (devid != CS42L56_DEVID) {  		dev_err(&i2c_client->dev, diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index c3f974ec78e5..e92bacaab53f 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1268,6 +1268,9 @@ static const struct regmap_config cs42l73_regmap = {  	.volatile_reg = cs42l73_volatile_register,  	.readable_reg = cs42l73_readable_register,  	.cache_type = REGCACHE_RBTREE, + +	.use_single_read = true, +	.use_single_write = true,  };  static int cs42l73_i2c_probe(struct i2c_client *i2c_client, diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 3d67cbf9eaaa..abe0cc0bc03a 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -912,6 +912,9 @@ static struct regmap_config cs53l30_regmap = {  	.writeable_reg = cs53l30_writeable_register,  	.readable_reg = cs53l30_readable_register,  	.cache_type = REGCACHE_RBTREE, + +	.use_single_read = true, +	.use_single_write = true,  };  static int cs53l30_i2c_probe(struct i2c_client *client, diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index bd3c523a8617..13009d08b09a 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2181,10 +2181,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)  				 ret);  			goto err;  		} - -		da7219->dai_clks[i] = devm_clk_hw_get_clk(dev, dai_clk_hw, NULL); -		if (IS_ERR(da7219->dai_clks[i])) -			return PTR_ERR(da7219->dai_clks[i]); +		da7219->dai_clks[i] = dai_clk_hw->clk;  		/* For DT setup onecell data, otherwise create lookup */  		if (np) { diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index b0ebfc8d180c..171ab7f519c0 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -3579,6 +3579,7 @@ static const struct of_device_id rx_macro_dt_match[] = {  	{ .compatible = "qcom,sm8250-lpass-rx-macro" },  	{ }  }; +MODULE_DEVICE_TABLE(of, rx_macro_dt_match);  static struct platform_driver rx_macro_driver = {  	.driver = { diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index acd2fbc0ca7c..27a0d5defd27 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -1846,6 +1846,7 @@ static const struct of_device_id tx_macro_dt_match[] = {  	{ .compatible = "qcom,sm8250-lpass-tx-macro" },  	{ }  }; +MODULE_DEVICE_TABLE(of, tx_macro_dt_match);  static struct platform_driver tx_macro_driver = {  	.driver = {  		.name = "tx_macro", diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 4be24e7f51c8..f8e49e45ce33 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -41,6 +41,7 @@ struct max98088_priv {  	enum max98088_type devtype;  	struct max98088_pdata *pdata;  	struct clk *mclk; +	unsigned char mclk_prescaler;  	unsigned int sysclk;  	struct max98088_cdata dai[2];  	int eq_textcnt; @@ -998,13 +999,16 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,         /* Configure NI when operating as master */         if (snd_soc_component_read(component, M98088_REG_14_DAI1_FORMAT)                 & M98088_DAI_MAS) { +               unsigned long pclk; +                 if (max98088->sysclk == 0) {                         dev_err(component->dev, "Invalid system clock frequency\n");                         return -EINVAL;                 }                 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)                                 * (unsigned long long int)rate; -               do_div(ni, (unsigned long long int)max98088->sysclk); +               pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler); +               ni = DIV_ROUND_CLOSEST_ULL(ni, pclk);                 snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,                         (ni >> 8) & 0x7F);                 snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO, @@ -1065,13 +1069,16 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,         /* Configure NI when operating as master */         if (snd_soc_component_read(component, M98088_REG_1C_DAI2_FORMAT)                 & M98088_DAI_MAS) { +               unsigned long pclk; +                 if (max98088->sysclk == 0) {                         dev_err(component->dev, "Invalid system clock frequency\n");                         return -EINVAL;                 }                 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)                                 * (unsigned long long int)rate; -               do_div(ni, (unsigned long long int)max98088->sysclk); +               pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler); +               ni = DIV_ROUND_CLOSEST_ULL(ni, pclk);                 snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,                         (ni >> 8) & 0x7F);                 snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO, @@ -1113,8 +1120,10 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,          */         if ((freq >= 10000000) && (freq < 20000000)) {                 snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x10); +               max98088->mclk_prescaler = 1;         } else if ((freq >= 20000000) && (freq < 30000000)) {                 snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x20); +               max98088->mclk_prescaler = 2;         } else {                 dev_err(component->dev, "Invalid master clock frequency\n");                 return -EINVAL; diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index cc36739f7fcf..24a084e0b48a 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -683,13 +683,13 @@ static int rt711_sdca_set_fu1e_capture_ctl(struct rt711_sdca_priv *rt711)  	ch_r = (rt711->fu1e_dapm_mute || rt711->fu1e_mixer_r_mute) ? 0x01 : 0x00;  	err = regmap_write(rt711->regmap, -			SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, +			SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E,  			RT711_SDCA_CTL_FU_MUTE, CH_L), ch_l);  	if (err < 0)  		return err;  	err = regmap_write(rt711->regmap, -			SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, +			SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E,  			RT711_SDCA_CTL_FU_MUTE, CH_R), ch_r);  	if (err < 0)  		return err; diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index ffdf7e559515..82a24e330065 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -408,6 +408,7 @@ static const struct of_device_id sti_sas_dev_match[] = {  	},  	{},  }; +MODULE_DEVICE_TABLE(of, sti_sas_dev_match);  static int sti_sas_driver_probe(struct platform_device *pdev)  { diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 0917d65d6921..556c284f49dd 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -119,6 +119,7 @@ config SND_SOC_FSL_RPMSG  	tristate "NXP Audio Base On RPMSG support"  	depends on COMMON_CLK  	depends on RPMSG +	depends on SND_IMX_SOC || SND_IMX_SOC = n  	select SND_SOC_IMX_RPMSG if SND_IMX_SOC != n  	help  	  Say Y if you want to add rpmsg audio support for the Freescale CPUs. diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 2c8a2fcb7922..5e71382467e8 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -209,7 +209,7 @@ static void graph_parse_mclk_fs(struct device_node *top,  static int graph_parse_node(struct asoc_simple_priv *priv,  			    struct device_node *ep,  			    struct link_info *li, -			    int is_cpu) +			    int *cpu)  {  	struct device *dev = simple_priv_to_dev(priv);  	struct device_node *top = dev->of_node; @@ -217,9 +217,9 @@ static int graph_parse_node(struct asoc_simple_priv *priv,  	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);  	struct snd_soc_dai_link_component *dlc;  	struct asoc_simple_dai *dai; -	int ret, single = 0; +	int ret; -	if (is_cpu) { +	if (cpu) {  		dlc = asoc_link_to_cpu(dai_link, 0);  		dai = simple_props_to_dai_cpu(dai_props, 0);  	} else { @@ -229,7 +229,7 @@ static int graph_parse_node(struct asoc_simple_priv *priv,  	graph_parse_mclk_fs(top, ep, dai_props); -	ret = asoc_simple_parse_dai(ep, dlc, &single); +	ret = asoc_simple_parse_dai(ep, dlc, cpu);  	if (ret < 0)  		return ret; @@ -241,9 +241,6 @@ static int graph_parse_node(struct asoc_simple_priv *priv,  	if (ret < 0)  		return ret; -	if (is_cpu) -		asoc_simple_canonicalize_cpu(dlc, single); -  	return 0;  } @@ -276,33 +273,29 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,  				  struct link_info *li)  {  	struct device *dev = simple_priv_to_dev(priv); -	struct snd_soc_card *card = simple_priv_to_card(priv);  	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);  	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);  	struct device_node *top = dev->of_node;  	struct device_node *ep = li->cpu ? cpu_ep : codec_ep; -	struct device_node *port; -	struct device_node *ports; -	struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); -	struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);  	char dai_name[64];  	int ret; -	port	= of_get_parent(ep); -	ports	= of_get_parent(port); -  	dev_dbg(dev, "link_of DPCM (%pOF)\n", ep);  	if (li->cpu) { +		struct snd_soc_card *card = simple_priv_to_card(priv); +		struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); +		int is_single_links = 0; +  		/* Codec is dummy */  		/* FE settings */  		dai_link->dynamic		= 1;  		dai_link->dpcm_merged_format	= 1; -		ret = graph_parse_node(priv, cpu_ep, li, 1); +		ret = graph_parse_node(priv, cpu_ep, li, &is_single_links);  		if (ret) -			goto out_put_node; +			return ret;  		snprintf(dai_name, sizeof(dai_name),  			 "fe.%pOFP.%s", cpus->of_node, cpus->dai_name); @@ -318,8 +311,13 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,  		 */  		if (card->component_chaining && !soc_component_is_pcm(cpus))  			dai_link->no_pcm = 1; + +		asoc_simple_canonicalize_cpu(cpus, is_single_links);  	} else { -		struct snd_soc_codec_conf *cconf; +		struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, 0); +		struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0); +		struct device_node *port; +		struct device_node *ports;  		/* CPU is dummy */ @@ -327,22 +325,25 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,  		dai_link->no_pcm		= 1;  		dai_link->be_hw_params_fixup	= asoc_simple_be_hw_params_fixup; -		cconf	= simple_props_to_codec_conf(dai_props, 0); - -		ret = graph_parse_node(priv, codec_ep, li, 0); +		ret = graph_parse_node(priv, codec_ep, li, NULL);  		if (ret < 0) -			goto out_put_node; +			return ret;  		snprintf(dai_name, sizeof(dai_name),  			 "be.%pOFP.%s", codecs->of_node, codecs->dai_name);  		/* check "prefix" from top node */ +		port = of_get_parent(ep); +		ports = of_get_parent(port);  		snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,  					      "prefix");  		if (of_node_name_eq(ports, "ports"))  			snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, "prefix");  		snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node,  					     "prefix"); + +		of_node_put(ports); +		of_node_put(port);  	}  	graph_parse_convert(dev, ep, &dai_props->adata); @@ -351,11 +352,8 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,  	ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name); -out_put_node:  	li->link++; -	of_node_put(ports); -	of_node_put(port);  	return ret;  } @@ -369,20 +367,23 @@ static int graph_dai_link_of(struct asoc_simple_priv *priv,  	struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0);  	struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);  	char dai_name[64]; -	int ret; +	int ret, is_single_links = 0;  	dev_dbg(dev, "link_of (%pOF)\n", cpu_ep); -	ret = graph_parse_node(priv, cpu_ep, li, 1); +	ret = graph_parse_node(priv, cpu_ep, li, &is_single_links);  	if (ret < 0)  		return ret; -	ret = graph_parse_node(priv, codec_ep, li, 0); +	ret = graph_parse_node(priv, codec_ep, li, NULL);  	if (ret < 0)  		return ret;  	snprintf(dai_name, sizeof(dai_name),  		 "%s-%s", cpus->dai_name, codecs->dai_name); + +	asoc_simple_canonicalize_cpu(cpus, is_single_links); +  	ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name);  	if (ret < 0)  		return ret; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index a1373be4558f..0015f534d42d 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -93,12 +93,11 @@ static void simple_parse_convert(struct device *dev,  }  static void simple_parse_mclk_fs(struct device_node *top, -				 struct device_node *cpu, -				 struct device_node *codec, +				 struct device_node *np,  				 struct simple_dai_props *props,  				 char *prefix)  { -	struct device_node *node = of_get_parent(cpu); +	struct device_node *node = of_get_parent(np);  	char prop[128];  	snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX); @@ -106,12 +105,71 @@ static void simple_parse_mclk_fs(struct device_node *top,  	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_property_read_u32(np,	prop, &props->mclk_fs);  	of_node_put(node);  } +static int simple_parse_node(struct asoc_simple_priv *priv, +			     struct device_node *np, +			     struct link_info *li, +			     char *prefix, +			     int *cpu) +{ +	struct device *dev = simple_priv_to_dev(priv); +	struct device_node *top = dev->of_node; +	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); +	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); +	struct snd_soc_dai_link_component *dlc; +	struct asoc_simple_dai *dai; +	int ret; + +	if (cpu) { +		dlc = asoc_link_to_cpu(dai_link, 0); +		dai = simple_props_to_dai_cpu(dai_props, 0); +	} else { +		dlc = asoc_link_to_codec(dai_link, 0); +		dai = simple_props_to_dai_codec(dai_props, 0); +	} + +	simple_parse_mclk_fs(top, np, dai_props, prefix); + +	ret = asoc_simple_parse_dai(np, dlc, cpu); +	if (ret) +		return ret; + +	ret = asoc_simple_parse_clk(dev, np, dai, dlc); +	if (ret) +		return ret; + +	ret = asoc_simple_parse_tdm(np, dai); +	if (ret) +		return ret; + +	return 0; +} + +static int simple_link_init(struct asoc_simple_priv *priv, +			    struct device_node *node, +			    struct device_node *codec, +			    struct link_info *li, +			    char *prefix, char *name) +{ +	struct device *dev = simple_priv_to_dev(priv); +	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); +	int ret; + +	ret = asoc_simple_parse_daifmt(dev, node, codec, +				       prefix, &dai_link->dai_fmt); +	if (ret < 0) +		return 0; + +	dai_link->init			= asoc_simple_dai_init; +	dai_link->ops			= &simple_ops; + +	return asoc_simple_set_dailink_name(dev, dai_link, name); +} +  static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,  				   struct device_node *np,  				   struct device_node *codec, @@ -121,24 +179,21 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,  	struct device *dev = simple_priv_to_dev(priv);  	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);  	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); -	struct asoc_simple_dai *dai; -	struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); -	struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0); -	struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0);  	struct device_node *top = dev->of_node;  	struct device_node *node = of_get_parent(np);  	char *prefix = ""; +	char dai_name[64];  	int ret;  	dev_dbg(dev, "link_of DPCM (%pOF)\n", np); -	li->link++; -  	/* For single DAI link & old style of DT node */  	if (is_top)  		prefix = PREFIX;  	if (li->cpu) { +		struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0); +		struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0);  		int is_single_links = 0;  		/* Codec is dummy */ @@ -147,25 +202,16 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,  		dai_link->dynamic		= 1;  		dai_link->dpcm_merged_format	= 1; -		dai = simple_props_to_dai_cpu(dai_props, 0); - -		ret = asoc_simple_parse_dai(np, cpus, &is_single_links); -		if (ret) -			goto out_put_node; - -		ret = asoc_simple_parse_clk(dev, np, dai, cpus); +		ret = simple_parse_node(priv, np, li, prefix, &is_single_links);  		if (ret < 0)  			goto out_put_node; -		ret = asoc_simple_set_dailink_name(dev, dai_link, -						   "fe.%s", -						   cpus->dai_name); -		if (ret < 0) -			goto out_put_node; +		snprintf(dai_name, sizeof(dai_name), "fe.%s", cpus->dai_name);  		asoc_simple_canonicalize_cpu(cpus, is_single_links);  		asoc_simple_canonicalize_platform(platforms, cpus);  	} else { +		struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);  		struct snd_soc_codec_conf *cconf;  		/* CPU is dummy */ @@ -174,22 +220,13 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,  		dai_link->no_pcm		= 1;  		dai_link->be_hw_params_fixup	= asoc_simple_be_hw_params_fixup; -		dai	= simple_props_to_dai_codec(dai_props, 0);  		cconf	= simple_props_to_codec_conf(dai_props, 0); -		ret = asoc_simple_parse_dai(np, codecs, NULL); +		ret = simple_parse_node(priv, np, li, prefix, NULL);  		if (ret < 0)  			goto out_put_node; -		ret = asoc_simple_parse_clk(dev, np, dai, codecs); -		if (ret < 0) -			goto out_put_node; - -		ret = asoc_simple_set_dailink_name(dev, dai_link, -						   "be.%s", -						   codecs->dai_name); -		if (ret < 0) -			goto out_put_node; +		snprintf(dai_name, sizeof(dai_name), "be.%s", codecs->dai_name);  		/* check "prefix" from top node */  		snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, @@ -201,23 +238,14 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,  	}  	simple_parse_convert(dev, np, &dai_props->adata); -	simple_parse_mclk_fs(top, np, codec, dai_props, prefix); - -	ret = asoc_simple_parse_tdm(np, dai); -	if (ret) -		goto out_put_node; - -	ret = asoc_simple_parse_daifmt(dev, node, codec, -				       prefix, &dai_link->dai_fmt); -	if (ret < 0) -		goto out_put_node;  	snd_soc_dai_link_set_capabilities(dai_link); -	dai_link->ops			= &simple_ops; -	dai_link->init			= asoc_simple_dai_init; +	ret = simple_link_init(priv, node, codec, li, prefix, dai_name);  out_put_node: +	li->link++; +  	of_node_put(node);  	return ret;  } @@ -230,23 +258,19 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,  {  	struct device *dev = simple_priv_to_dev(priv);  	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); -	struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); -	struct asoc_simple_dai *cpu_dai	= simple_props_to_dai_cpu(dai_props, 0); -	struct asoc_simple_dai *codec_dai = simple_props_to_dai_codec(dai_props, 0);  	struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0);  	struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);  	struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0); -	struct device_node *top = dev->of_node;  	struct device_node *cpu = NULL;  	struct device_node *node = NULL;  	struct device_node *plat = NULL; +	char dai_name[64];  	char prop[128];  	char *prefix = "";  	int ret, single_cpu = 0;  	cpu  = np;  	node = of_get_parent(np); -	li->link++;  	dev_dbg(dev, "link_of (%pOF)\n", node); @@ -257,18 +281,11 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,  	snprintf(prop, sizeof(prop), "%splat", prefix);  	plat = of_get_child_by_name(node, prop); -	ret = asoc_simple_parse_daifmt(dev, node, codec, -				       prefix, &dai_link->dai_fmt); -	if (ret < 0) -		goto dai_link_of_err; - -	simple_parse_mclk_fs(top, cpu, codec, dai_props, prefix); - -	ret = asoc_simple_parse_dai(cpu, cpus, &single_cpu); +	ret = simple_parse_node(priv, cpu, li, prefix, &single_cpu);  	if (ret < 0)  		goto dai_link_of_err; -	ret = asoc_simple_parse_dai(codec, codecs, NULL); +	ret = simple_parse_node(priv, codec, li, prefix, NULL);  	if (ret < 0)  		goto dai_link_of_err; @@ -276,39 +293,20 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,  	if (ret < 0)  		goto dai_link_of_err; -	ret = asoc_simple_parse_tdm(cpu, cpu_dai); -	if (ret < 0) -		goto dai_link_of_err; - -	ret = asoc_simple_parse_tdm(codec, codec_dai); -	if (ret < 0) -		goto dai_link_of_err; - -	ret = asoc_simple_parse_clk(dev, cpu, cpu_dai, cpus); -	if (ret < 0) -		goto dai_link_of_err; - -	ret = asoc_simple_parse_clk(dev, codec, codec_dai, codecs); -	if (ret < 0) -		goto dai_link_of_err; - -	ret = asoc_simple_set_dailink_name(dev, dai_link, -					   "%s-%s", -					   cpus->dai_name, -					   codecs->dai_name); -	if (ret < 0) -		goto dai_link_of_err; - -	dai_link->ops = &simple_ops; -	dai_link->init = asoc_simple_dai_init; +	snprintf(dai_name, sizeof(dai_name), +		 "%s-%s", cpus->dai_name, codecs->dai_name);  	asoc_simple_canonicalize_cpu(cpus, single_cpu);  	asoc_simple_canonicalize_platform(platforms, cpus); +	ret = simple_link_init(priv, node, codec, li, prefix, dai_name); +  dai_link_of_err:  	of_node_put(plat);  	of_node_put(node); +	li->link++; +  	return ret;  } diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index df2f5d55e8ff..22dbd9d93c1e 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -574,6 +574,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {  					BYT_RT5640_SSP0_AIF1 |  					BYT_RT5640_MCLK_EN),  	}, +	{	/* Glavey TM800A550L */ +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), +			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), +			/* Above strings are too generic, also match on BIOS version */ +			DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), +		}, +		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS | +					BYT_RT5640_SSP0_AIF1 | +					BYT_RT5640_MCLK_EN), +	},  	{  		.matches = {  			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), @@ -652,6 +663,20 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {  					BYT_RT5640_MONO_SPEAKER |  					BYT_RT5640_MCLK_EN),  	}, +	{	/* Lenovo Miix 3-830 */ +		.matches = { +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), +			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 3-830"), +		}, +		.driver_data = (void *)(BYT_RT5640_IN1_MAP | +					BYT_RT5640_JD_SRC_JD2_IN4N | +					BYT_RT5640_OVCD_TH_2000UA | +					BYT_RT5640_OVCD_SF_0P75 | +					BYT_RT5640_MONO_SPEAKER | +					BYT_RT5640_DIFF_MIC | +					BYT_RT5640_SSP0_AIF1 | +					BYT_RT5640_MCLK_EN), +	},  	{	/* Linx Linx7 tablet */  		.matches = {  			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"), diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index c62d2612e8f5..28c7497344e3 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -835,18 +835,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)  		if (dai_id == LPASS_DP_RX)  			continue; -		drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(dev, +		drvdata->mi2s_osr_clk[dai_id] = devm_clk_get_optional(dev,  					     variant->dai_osr_clk_names[i]); -		if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) { -			dev_warn(dev, -				"%s() error getting optional %s: %ld\n", -				__func__, -				variant->dai_osr_clk_names[i], -				PTR_ERR(drvdata->mi2s_osr_clk[dai_id])); - -			drvdata->mi2s_osr_clk[dai_id] = NULL; -		} -  		drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(dev,  						variant->dai_bit_clk_names[i]);  		if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 8d7bab433fb3..c1f9f0f58464 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -421,11 +421,16 @@ static int ssp_dai_hw_params(struct snd_pcm_substream *substream,  	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);  	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);  	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); +	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;  	struct sof_ipc_dai_config *config;  	struct snd_sof_dai *sof_dai;  	struct sof_ipc_reply reply;  	int ret; +	/* DAI_CONFIG IPC during hw_params is not supported in older firmware */ +	if (v->abi_version < SOF_ABI_VER(3, 18, 0)) +		return 0; +  	list_for_each_entry(sof_dai, &sdev->dai_list, list) {  		if (!sof_dai->cpu_dai_name || !sof_dai->dai_config)  			continue; diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index c1561237ee24..3aa1cf262402 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -484,10 +484,7 @@ static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai)  		dev_err(dev, "mclk register returned %d\n", ret);  		return ret;  	} - -	sai->sai_mclk = devm_clk_hw_get_clk(dev, hw, NULL); -	if (IS_ERR(sai->sai_mclk)) -		return PTR_ERR(sai->sai_mclk); +	sai->sai_mclk = hw->clk;  	/* register mclk provider */  	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); | 
