Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39b47b59 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000',...

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000', 'asoc/topic/simple' and 'asoc/topic/sirf' into asoc-next
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+15 −60
Original line number Diff line number Diff line
@@ -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
+3 −5
Original line number Diff line number Diff line
@@ -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;
+35 −4
Original line number Diff line number Diff line
@@ -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,6 +179,7 @@ static int simple_card_dai_link_of(struct device_node *node,
	char *prefix = "";
	int ret;

	if (is_top_level_node)
		prefix = "simple-audio-card,";

	daifmt = snd_soc_of_parse_daifmt(node, prefix,
@@ -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;
	}
+9 −5
Original line number Diff line number Diff line
@@ -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
Loading