diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/simple-card.txt | 3 | ||||
| -rw-r--r-- | sound/soc/codecs/sgtl5000.c | 75 | ||||
| -rw-r--r-- | sound/soc/codecs/sirf-audio-codec.c | 8 | ||||
| -rw-r--r-- | sound/soc/generic/simple-card.c | 39 | ||||
| -rw-r--r-- | sound/soc/samsung/i2s.c | 14 | ||||
| -rw-r--r-- | sound/soc/samsung/pcm.c | 4 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c-i2s-v2.c | 8 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c2412-i2s.c | 6 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c24xx-i2s.c | 6 | ||||
| -rw-r--r-- | sound/soc/samsung/smdk_wm8580.c | 8 | ||||
| -rw-r--r-- | sound/soc/samsung/smdk_wm8994.c | 2 | ||||
| -rw-r--r-- | sound/soc/samsung/spdif.c | 4 | 
12 files changed, 83 insertions, 94 deletions
| diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 9b9df146fd1a..c2e9841dfce4 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -15,6 +15,9 @@ Optional properties:  					  Each entry is a pair of strings, the first being the  					  connection's sink, the second being the connection's  					  source. +- simple-audio-card,mclk-fs             : Multiplication factor between stream rate and codec +  					  mclk. +  Optional subnodes:  - simple-audio-card,dai-link		: Container for dai-link level diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 9626ee0417cd..3d39f0b5b4a8 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -36,18 +36,32 @@  /* default value of sgtl5000 registers */  static const struct reg_default sgtl5000_reg_defaults[] = { +	{ SGTL5000_CHIP_DIG_POWER,		0x0000 },  	{ SGTL5000_CHIP_CLK_CTRL,		0x0008 },  	{ SGTL5000_CHIP_I2S_CTRL,		0x0010 },  	{ SGTL5000_CHIP_SSS_CTRL,		0x0010 }, +	{ SGTL5000_CHIP_ADCDAC_CTRL,		0x020c },  	{ SGTL5000_CHIP_DAC_VOL,		0x3c3c },  	{ SGTL5000_CHIP_PAD_STRENGTH,		0x015f }, +	{ SGTL5000_CHIP_ANA_ADC_CTRL,		0x0000 },  	{ SGTL5000_CHIP_ANA_HP_CTRL,		0x1818 },  	{ SGTL5000_CHIP_ANA_CTRL,		0x0111 }, +	{ SGTL5000_CHIP_LINREG_CTRL,		0x0000 }, +	{ SGTL5000_CHIP_REF_CTRL,		0x0000 }, +	{ SGTL5000_CHIP_MIC_CTRL,		0x0000 }, +	{ SGTL5000_CHIP_LINE_OUT_CTRL,		0x0000 },  	{ SGTL5000_CHIP_LINE_OUT_VOL,		0x0404 },  	{ SGTL5000_CHIP_ANA_POWER,		0x7060 },  	{ SGTL5000_CHIP_PLL_CTRL,		0x5000 }, +	{ SGTL5000_CHIP_CLK_TOP_CTRL,		0x0000 }, +	{ SGTL5000_CHIP_ANA_STATUS,		0x0000 }, +	{ SGTL5000_CHIP_SHORT_CTRL,		0x0000 }, +	{ SGTL5000_CHIP_ANA_TEST2,		0x0000 }, +	{ SGTL5000_DAP_CTRL,			0x0000 }, +	{ SGTL5000_DAP_PEQ,			0x0000 },  	{ SGTL5000_DAP_BASS_ENHANCE,		0x0040 },  	{ SGTL5000_DAP_BASS_ENHANCE_CTRL,	0x051f }, +	{ SGTL5000_DAP_AUDIO_EQ,		0x0000 },  	{ SGTL5000_DAP_SURROUND,		0x0040 },  	{ SGTL5000_DAP_EQ_BASS_BAND0,		0x002f },  	{ SGTL5000_DAP_EQ_BASS_BAND1,		0x002f }, @@ -55,6 +69,7 @@ static const struct reg_default sgtl5000_reg_defaults[] = {  	{ SGTL5000_DAP_EQ_BASS_BAND3,		0x002f },  	{ SGTL5000_DAP_EQ_BASS_BAND4,		0x002f },  	{ SGTL5000_DAP_MAIN_CHAN,		0x8000 }, +	{ SGTL5000_DAP_MIX_CHAN,		0x0000 },  	{ SGTL5000_DAP_AVC_CTRL,		0x0510 },  	{ SGTL5000_DAP_AVC_THRESHOLD,		0x1473 },  	{ SGTL5000_DAP_AVC_ATTACK,		0x0028 }, @@ -1068,71 +1083,11 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec)  	return 0;  } -/* - * restore all sgtl5000 registers, - * since a big hole between dap and regular registers, - * we will restore them respectively. - */ -static int sgtl5000_restore_regs(struct snd_soc_codec *codec) -{ -	u16 *cache = codec->reg_cache; -	u16 reg; - -	/* restore regular registers */ -	for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { - -		/* These regs should restore in particular order */ -		if (reg == SGTL5000_CHIP_ANA_POWER || -			reg == SGTL5000_CHIP_CLK_CTRL || -			reg == SGTL5000_CHIP_LINREG_CTRL || -			reg == SGTL5000_CHIP_LINE_OUT_CTRL || -			reg == SGTL5000_CHIP_REF_CTRL) -			continue; - -		snd_soc_write(codec, reg, cache[reg]); -	} - -	/* restore dap registers */ -	for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2) -		snd_soc_write(codec, reg, cache[reg]); - -	/* -	 * restore these regs according to the power setting sequence in -	 * sgtl5000_set_power_regs() and clock setting sequence in -	 * sgtl5000_set_clock(). -	 * -	 * The order of restore is: -	 * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after -	 *    SGTL5000_CHIP_ANA_POWER PLL bits set -	 * 2. SGTL5000_CHIP_LINREG_CTRL should be set before -	 *    SGTL5000_CHIP_ANA_POWER LINREG_D restored -	 * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage, -	 *    prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored -	 */ -	snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, -			cache[SGTL5000_CHIP_LINREG_CTRL]); - -	snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, -			cache[SGTL5000_CHIP_ANA_POWER]); - -	snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, -			cache[SGTL5000_CHIP_CLK_CTRL]); - -	snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL, -			cache[SGTL5000_CHIP_REF_CTRL]); - -	snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL, -			cache[SGTL5000_CHIP_LINE_OUT_CTRL]); -	return 0; -} -  static int sgtl5000_resume(struct snd_soc_codec *codec)  {  	/* Bring the codec back up to standby to enable regulators */  	sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -	/* Restore registers by cached in memory */ -	sgtl5000_restore_regs(codec);  	return 0;  }  #else diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index c5177bc5df82..d90cb0fafcb2 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -109,7 +109,7 @@ static void enable_and_reset_codec(struct regmap *regmap,  {  	regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1,  			codec_enable_bits | codec_reset_bits, -			codec_enable_bits | ~codec_reset_bits); +			codec_enable_bits);  	msleep(20);  	regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1,  			codec_reset_bits, codec_reset_bits); @@ -128,8 +128,7 @@ static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,  		break;  	case SND_SOC_DAPM_POST_PMD:  		regmap_update_bits(sirf_audio_codec->regmap, -			AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, -			~ATLAS6_CODEC_ENABLE_BITS); +			AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 0);  		break;  	default:  		break; @@ -151,8 +150,7 @@ static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,  		break;  	case SND_SOC_DAPM_POST_PMD:  		regmap_update_bits(sirf_audio_codec->regmap, -			AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, -			~PRIMA2_CODEC_ENABLE_BITS); +			AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 0);  		break;  	default:  		break; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 98f97e543c29..03a7fdcdf114 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -24,9 +24,32 @@ struct simple_card_data {  		struct asoc_simple_dai cpu_dai;  		struct asoc_simple_dai codec_dai;  	} *dai_props; +	unsigned int mclk_fs;  	struct snd_soc_dai_link dai_link[];	/* dynamically allocated */  }; +static int asoc_simple_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_dai *codec_dai = rtd->codec_dai; +	struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); +	unsigned int mclk; +	int ret = 0; + +	if (priv->mclk_fs) { +		mclk = params_rate(params) * priv->mclk_fs; +		ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, +					     SND_SOC_CLOCK_IN); +	} + +	return ret; +} + +static struct snd_soc_ops asoc_simple_card_ops = { +	.hw_params = asoc_simple_card_hw_params, +}; +  static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,  				       struct asoc_simple_dai *set)  { @@ -144,7 +167,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np,  static int simple_card_dai_link_of(struct device_node *node,  				   struct device *dev,  				   struct snd_soc_dai_link *dai_link, -				   struct simple_dai_props *dai_props) +				   struct simple_dai_props *dai_props, +				   bool is_top_level_node)  {  	struct device_node *np = NULL;  	struct device_node *bitclkmaster = NULL; @@ -155,7 +179,8 @@ static int simple_card_dai_link_of(struct device_node *node,  	char *prefix = "";  	int ret; -	prefix = "simple-audio-card,"; +	if (is_top_level_node) +		prefix = "simple-audio-card,";  	daifmt = snd_soc_of_parse_daifmt(node, prefix,  					 &bitclkmaster, &framemaster); @@ -249,6 +274,7 @@ static int simple_card_dai_link_of(struct device_node *node,  	sprintf(name, "%s-%s", dai_link->cpu_dai_name,  				dai_link->codec_dai_name);  	dai_link->name = dai_link->stream_name = name; +	dai_link->ops = &asoc_simple_card_ops;  	dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);  	dev_dbg(dev, "\tcpu : %s / %04x / %d\n", @@ -298,6 +324,10 @@ static int asoc_simple_card_parse_of(struct device_node *node,  			return ret;  	} +	/* Factor to mclk, used in hw_params() */ +	of_property_read_u32(node, "simple-audio-card,mclk-fs", +			     &priv->mclk_fs); +  	dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?  		priv->snd_card.name : ""); @@ -307,14 +337,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,  		for (i = 0; (np = of_get_next_child(node, np)); i++) {  			dev_dbg(dev, "\tlink %d:\n", i);  			ret = simple_card_dai_link_of(np, dev, dai_link + i, -						      dai_props + i); +						      dai_props + i, false);  			if (ret < 0) {  				of_node_put(np);  				return ret;  			}  		}  	} else { -		ret = simple_card_dai_link_of(node, dev, dai_link, dai_props); +		ret = simple_card_dai_link_of(node, dev, dai_link, dai_props, +					      true);  		if (ret < 0)  			return ret;  	} diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 07ff3e7cb890..2ac76fa3e742 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -488,7 +488,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,  			clk_id = 1;  		if (!any_active(i2s)) { -			if (i2s->op_clk) { +			if (i2s->op_clk && !IS_ERR(i2s->op_clk)) {  				if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||  					(!clk_id && (mod & MOD_IMS_SYSMUX))) {  					clk_disable_unprepare(i2s->op_clk); @@ -506,6 +506,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,  			else  				i2s->op_clk = clk_get(&i2s->pdev->dev,  						"i2s_opclk0"); + +			if (WARN_ON(IS_ERR(i2s->op_clk))) +				return PTR_ERR(i2s->op_clk); +  			clk_prepare_enable(i2s->op_clk);  			i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); @@ -672,8 +676,8 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,  	if (is_manager(i2s))  		mod &= ~MOD_BLC_MASK; -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_S8: +	switch (params_width(params)) { +	case 8:  		if (is_secondary(i2s))  			mod |= MOD_BLCS_8BIT;  		else @@ -681,7 +685,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,  		if (is_manager(i2s))  			mod |= MOD_BLC_8BIT;  		break; -	case SNDRV_PCM_FORMAT_S16_LE: +	case 16:  		if (is_secondary(i2s))  			mod |= MOD_BLCS_16BIT;  		else @@ -689,7 +693,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,  		if (is_manager(i2s))  			mod |= MOD_BLC_16BIT;  		break; -	case SNDRV_PCM_FORMAT_S24_LE: +	case 24:  		if (is_secondary(i2s))  			mod |= MOD_BLCS_24BIT;  		else diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index a3c9c9cba3b0..4c5f97fe45c8 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -283,8 +283,8 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,  	dev_dbg(pcm->dev, "Entered %s\n", __func__);  	/* Strictly check for sample size */ -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_S16_LE: +	switch (params_width(params)) { +	case 16:  		break;  	default:  		return -EINVAL; diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 77a2ae50dc94..0ff4bbe23af3 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -322,13 +322,13 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,  	iismod &= ~S3C64XX_IISMOD_BLC_MASK;  	/* Sample size */ -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_S8: +	switch (params_width(params)) { +	case 8:  		iismod |= S3C64XX_IISMOD_BLC_8BIT;  		break; -	case SNDRV_PCM_FORMAT_S16_LE: +	case 16:  		break; -	case SNDRV_PCM_FORMAT_S24_LE: +	case 24:  		iismod |= S3C64XX_IISMOD_BLC_24BIT;  		break;  	} diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 843f315dcb3a..08c059be9104 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -120,11 +120,11 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,  	iismod = readl(i2s->regs + S3C2412_IISMOD);  	pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_S8: +	switch (params_width(params)) { +	case 8:  		iismod |= S3C2412_IISMOD_8BIT;  		break; -	case SNDRV_PCM_FORMAT_S16_LE: +	case 16:  		iismod &= ~S3C2412_IISMOD_8BIT;  		break;  	} diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 4a6d206db222..9aba9fb7df0e 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -248,12 +248,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,  	iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);  	pr_debug("hw_params r: IISMOD: %x\n", iismod); -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_S8: +	switch (params_width(params)) { +	case 8:  		iismod &= ~S3C2410_IISMOD_16BIT;  		dma_data->dma_size = 1;  		break; -	case SNDRV_PCM_FORMAT_S16_LE: +	case 16:  		iismod |= S3C2410_IISMOD_16BIT;  		dma_data->dma_size = 2;  		break; diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 7a16b32ed673..b1a519f83b29 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -37,13 +37,11 @@ static int smdk_hw_params(struct snd_pcm_substream *substream,  	unsigned int pll_out;  	int bfs, rfs, ret; -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_U8: -	case SNDRV_PCM_FORMAT_S8: +	switch (params_width(params)) { +	case 8:  		bfs = 16;  		break; -	case SNDRV_PCM_FORMAT_U16_LE: -	case SNDRV_PCM_FORMAT_S16_LE: +	case 16:  		bfs = 32;  		break;  	default: diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index fc25cc00f0f2..3d6272a8cad2 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -57,7 +57,7 @@ static int smdk_hw_params(struct snd_pcm_substream *substream,  	int ret;  	/* AIF1CLK should be >=3MHz for optimal performance */ -	if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) +	if (params_width(params) == 24)  		pll_out = params_rate(params) * 384;  	else if (params_rate(params) == 8000 || params_rate(params) == 11025)  		pll_out = params_rate(params) * 512; diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index e93a93e296f4..d9ffc48fce5e 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -211,8 +211,8 @@ static int spdif_hw_params(struct snd_pcm_substream *substream,  	con |= CON_PCM_DATA;  	con &= ~CON_PCM_MASK; -	switch (params_format(params)) { -	case SNDRV_PCM_FORMAT_S16_LE: +	switch (params_width(params)) { +	case 16:  		con |= CON_PCM_16BIT;  		break;  	default: | 
