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

Commit cabad441 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/topic/ssm4567', 'asoc/topic/sta32x',...

Merge remote-tracking branches 'asoc/topic/ssm4567', 'asoc/topic/sta32x', 'asoc/topic/sta350', 'asoc/topic/sta529' and 'asoc/topic/stac9766' into asoc-next
Loading
Loading
Loading
Loading
+128 −0
Original line number Original line Diff line number Diff line
@@ -69,6 +69,22 @@
#define SSM4567_DAC_FS_64000_96000	0x3
#define SSM4567_DAC_FS_64000_96000	0x3
#define SSM4567_DAC_FS_128000_192000	0x4
#define SSM4567_DAC_FS_128000_192000	0x4


/* SAI_CTRL_1 */
#define SSM4567_SAI_CTRL_1_BCLK			BIT(6)
#define SSM4567_SAI_CTRL_1_TDM_BLCKS_MASK	(0x3 << 4)
#define SSM4567_SAI_CTRL_1_TDM_BLCKS_32		(0x0 << 4)
#define SSM4567_SAI_CTRL_1_TDM_BLCKS_48		(0x1 << 4)
#define SSM4567_SAI_CTRL_1_TDM_BLCKS_64		(0x2 << 4)
#define SSM4567_SAI_CTRL_1_FSYNC		BIT(3)
#define SSM4567_SAI_CTRL_1_LJ			BIT(2)
#define SSM4567_SAI_CTRL_1_TDM			BIT(1)
#define SSM4567_SAI_CTRL_1_PDM			BIT(0)

/* SAI_CTRL_2 */
#define SSM4567_SAI_CTRL_2_AUTO_SLOT		BIT(3)
#define SSM4567_SAI_CTRL_2_TDM_SLOT_MASK	0x7
#define SSM4567_SAI_CTRL_2_TDM_SLOT(x)		(x)

struct ssm4567 {
struct ssm4567 {
	struct regmap *regmap;
	struct regmap *regmap;
};
};
@@ -145,15 +161,24 @@ static const struct snd_kcontrol_new ssm4567_snd_controls[] = {
	SOC_SINGLE_TLV("Master Playback Volume", SSM4567_REG_DAC_VOLUME, 0,
	SOC_SINGLE_TLV("Master Playback Volume", SSM4567_REG_DAC_VOLUME, 0,
		0xff, 1, ssm4567_vol_tlv),
		0xff, 1, ssm4567_vol_tlv),
	SOC_SINGLE("DAC Low Power Mode Switch", SSM4567_REG_DAC_CTRL, 4, 1, 0),
	SOC_SINGLE("DAC Low Power Mode Switch", SSM4567_REG_DAC_CTRL, 4, 1, 0),
	SOC_SINGLE("DAC High Pass Filter Switch", SSM4567_REG_DAC_CTRL,
		5, 1, 0),
};
};


static const struct snd_kcontrol_new ssm4567_amplifier_boost_control =
	SOC_DAPM_SINGLE("Switch", SSM4567_REG_POWER_CTRL, 1, 1, 1);

static const struct snd_soc_dapm_widget ssm4567_dapm_widgets[] = {
static const struct snd_soc_dapm_widget ssm4567_dapm_widgets[] = {
	SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM4567_REG_POWER_CTRL, 2, 1),
	SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM4567_REG_POWER_CTRL, 2, 1),
	SND_SOC_DAPM_SWITCH("Amplifier Boost", SSM4567_REG_POWER_CTRL, 3, 1,
		&ssm4567_amplifier_boost_control),


	SND_SOC_DAPM_OUTPUT("OUT"),
	SND_SOC_DAPM_OUTPUT("OUT"),
};
};


static const struct snd_soc_dapm_route ssm4567_routes[] = {
static const struct snd_soc_dapm_route ssm4567_routes[] = {
	{ "OUT", NULL, "Amplifier Boost" },
	{ "Amplifier Boost", "Switch", "DAC" },
	{ "OUT", NULL, "DAC" },
	{ "OUT", NULL, "DAC" },
};
};


@@ -192,6 +217,107 @@ static int ssm4567_mute(struct snd_soc_dai *dai, int mute)
			SSM4567_DAC_MUTE, val);
			SSM4567_DAC_MUTE, val);
}
}


static int ssm4567_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
	unsigned int rx_mask, int slots, int width)
{
	struct ssm4567 *ssm4567 = snd_soc_dai_get_drvdata(dai);
	unsigned int blcks;
	int slot;
	int ret;

	if (tx_mask == 0)
		return -EINVAL;

	if (rx_mask && rx_mask != tx_mask)
		return -EINVAL;

	slot = __ffs(tx_mask);
	if (tx_mask != BIT(slot))
		return -EINVAL;

	switch (width) {
	case 32:
		blcks = SSM4567_SAI_CTRL_1_TDM_BLCKS_32;
		break;
	case 48:
		blcks = SSM4567_SAI_CTRL_1_TDM_BLCKS_48;
		break;
	case 64:
		blcks = SSM4567_SAI_CTRL_1_TDM_BLCKS_64;
		break;
	default:
		return -EINVAL;
	}

	ret = regmap_update_bits(ssm4567->regmap, SSM4567_REG_SAI_CTRL_2,
		SSM4567_SAI_CTRL_2_AUTO_SLOT | SSM4567_SAI_CTRL_2_TDM_SLOT_MASK,
		SSM4567_SAI_CTRL_2_TDM_SLOT(slot));
	if (ret)
		return ret;

	return regmap_update_bits(ssm4567->regmap, SSM4567_REG_SAI_CTRL_1,
		SSM4567_SAI_CTRL_1_TDM_BLCKS_MASK, blcks);
}

static int ssm4567_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct ssm4567 *ssm4567 = snd_soc_dai_get_drvdata(dai);
	unsigned int ctrl1 = 0;
	bool invert_fclk;

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		invert_fclk = false;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		ctrl1 |= SSM4567_SAI_CTRL_1_BCLK;
		invert_fclk = false;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		ctrl1 |= SSM4567_SAI_CTRL_1_FSYNC;
		invert_fclk = true;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		ctrl1 |= SSM4567_SAI_CTRL_1_BCLK;
		invert_fclk = true;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		ctrl1 |= SSM4567_SAI_CTRL_1_LJ;
		invert_fclk = !invert_fclk;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		ctrl1 |= SSM4567_SAI_CTRL_1_TDM;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		ctrl1 |= SSM4567_SAI_CTRL_1_TDM | SSM4567_SAI_CTRL_1_LJ;
		break;
	case SND_SOC_DAIFMT_PDM:
		ctrl1 |= SSM4567_SAI_CTRL_1_PDM;
		break;
	default:
		return -EINVAL;
	}

	if (invert_fclk)
		ctrl1 |= SSM4567_SAI_CTRL_1_FSYNC;

	return regmap_write(ssm4567->regmap, SSM4567_REG_SAI_CTRL_1, ctrl1);
}

static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable)
static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable)
{
{
	int ret = 0;
	int ret = 0;
@@ -246,6 +372,8 @@ static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
static const struct snd_soc_dai_ops ssm4567_dai_ops = {
static const struct snd_soc_dai_ops ssm4567_dai_ops = {
	.hw_params	= ssm4567_hw_params,
	.hw_params	= ssm4567_hw_params,
	.digital_mute	= ssm4567_mute,
	.digital_mute	= ssm4567_mute,
	.set_fmt	= ssm4567_set_dai_fmt,
	.set_tdm_slot	= ssm4567_set_tdm_slot,
};
};


static struct snd_soc_dai_driver ssm4567_dai = {
static struct snd_soc_dai_driver ssm4567_dai = {
+1 −20
Original line number Original line Diff line number Diff line
@@ -833,23 +833,6 @@ static struct snd_soc_dai_driver sta32x_dai = {
	.ops = &sta32x_dai_ops,
	.ops = &sta32x_dai_ops,
};
};


#ifdef CONFIG_PM
static int sta32x_suspend(struct snd_soc_codec *codec)
{
	sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
	return 0;
}

static int sta32x_resume(struct snd_soc_codec *codec)
{
	sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	return 0;
}
#else
#define sta32x_suspend NULL
#define sta32x_resume NULL
#endif

static int sta32x_probe(struct snd_soc_codec *codec)
static int sta32x_probe(struct snd_soc_codec *codec)
{
{
	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
@@ -936,7 +919,6 @@ static int sta32x_remove(struct snd_soc_codec *codec)
	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
	struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);


	sta32x_watchdog_stop(sta32x);
	sta32x_watchdog_stop(sta32x);
	sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);


	return 0;
	return 0;
@@ -955,9 +937,8 @@ static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg)
static const struct snd_soc_codec_driver sta32x_codec = {
static const struct snd_soc_codec_driver sta32x_codec = {
	.probe =		sta32x_probe,
	.probe =		sta32x_probe,
	.remove =		sta32x_remove,
	.remove =		sta32x_remove,
	.suspend =		sta32x_suspend,
	.resume =		sta32x_resume,
	.set_bias_level =	sta32x_set_bias_level,
	.set_bias_level =	sta32x_set_bias_level,
	.suspend_bias_off =	true,
	.controls =		sta32x_snd_controls,
	.controls =		sta32x_snd_controls,
	.num_controls =		ARRAY_SIZE(sta32x_snd_controls),
	.num_controls =		ARRAY_SIZE(sta32x_snd_controls),
	.dapm_widgets =		sta32x_dapm_widgets,
	.dapm_widgets =		sta32x_dapm_widgets,
+1 −20
Original line number Original line Diff line number Diff line
@@ -912,23 +912,6 @@ static struct snd_soc_dai_driver sta350_dai = {
	.ops = &sta350_dai_ops,
	.ops = &sta350_dai_ops,
};
};


#ifdef CONFIG_PM
static int sta350_suspend(struct snd_soc_codec *codec)
{
	sta350_set_bias_level(codec, SND_SOC_BIAS_OFF);
	return 0;
}

static int sta350_resume(struct snd_soc_codec *codec)
{
	sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	return 0;
}
#else
#define sta350_suspend NULL
#define sta350_resume NULL
#endif

static int sta350_probe(struct snd_soc_codec *codec)
static int sta350_probe(struct snd_soc_codec *codec)
{
{
	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
@@ -1065,7 +1048,6 @@ static int sta350_remove(struct snd_soc_codec *codec)
{
{
	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
	struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);


	sta350_set_bias_level(codec, SND_SOC_BIAS_OFF);
	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);


	return 0;
	return 0;
@@ -1074,9 +1056,8 @@ static int sta350_remove(struct snd_soc_codec *codec)
static const struct snd_soc_codec_driver sta350_codec = {
static const struct snd_soc_codec_driver sta350_codec = {
	.probe =		sta350_probe,
	.probe =		sta350_probe,
	.remove =		sta350_remove,
	.remove =		sta350_remove,
	.suspend =		sta350_suspend,
	.resume =		sta350_resume,
	.set_bias_level =	sta350_set_bias_level,
	.set_bias_level =	sta350_set_bias_level,
	.suspend_bias_off =	true,
	.controls =		sta350_snd_controls,
	.controls =		sta350_snd_controls,
	.num_controls =		ARRAY_SIZE(sta350_snd_controls),
	.num_controls =		ARRAY_SIZE(sta350_snd_controls),
	.dapm_widgets =		sta350_dapm_widgets,
	.dapm_widgets =		sta350_dapm_widgets,
+2 −33
Original line number Original line Diff line number Diff line
@@ -319,41 +319,10 @@ static struct snd_soc_dai_driver sta529_dai = {
	.ops	= &sta529_dai_ops,
	.ops	= &sta529_dai_ops,
};
};


static int sta529_probe(struct snd_soc_codec *codec)
{
	sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	return 0;
}

/* power down chip */
static int sta529_remove(struct snd_soc_codec *codec)
{
	sta529_set_bias_level(codec, SND_SOC_BIAS_OFF);

	return 0;
}

static int sta529_suspend(struct snd_soc_codec *codec)
{
	sta529_set_bias_level(codec, SND_SOC_BIAS_OFF);

	return 0;
}

static int sta529_resume(struct snd_soc_codec *codec)
{
	sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	return 0;
}

static const struct snd_soc_codec_driver sta529_codec_driver = {
static const struct snd_soc_codec_driver sta529_codec_driver = {
	.probe = sta529_probe,
	.remove = sta529_remove,
	.set_bias_level = sta529_set_bias_level,
	.set_bias_level = sta529_set_bias_level,
	.suspend = sta529_suspend,
	.suspend_bias_off = true,
	.resume = sta529_resume,

	.controls = sta529_snd_controls,
	.controls = sta529_snd_controls,
	.num_controls = ARRAY_SIZE(sta529_snd_controls),
	.num_controls = ARRAY_SIZE(sta529_snd_controls),
};
};
+5 −15
Original line number Original line Diff line number Diff line
@@ -258,12 +258,6 @@ static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
	return 0;
	return 0;
}
}


static int stac9766_codec_suspend(struct snd_soc_codec *codec)
{
	stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
	return 0;
}

static int stac9766_codec_resume(struct snd_soc_codec *codec)
static int stac9766_codec_resume(struct snd_soc_codec *codec)
{
{
	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
@@ -273,7 +267,7 @@ static int stac9766_codec_resume(struct snd_soc_codec *codec)
	/* give the codec an AC97 warm reset to start the link */
	/* give the codec an AC97 warm reset to start the link */
reset:
reset:
	if (reset > 5) {
	if (reset > 5) {
		printk(KERN_ERR "stac9766 failed to resume");
		dev_err(codec->dev, "Failed to resume\n");
		return -EIO;
		return -EIO;
	}
	}
	ac97->bus->ops->warm_reset(ac97);
	ac97->bus->ops->warm_reset(ac97);
@@ -283,7 +277,6 @@ static int stac9766_codec_resume(struct snd_soc_codec *codec)
		reset++;
		reset++;
		goto reset;
		goto reset;
	}
	}
	stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);


	return 0;
	return 0;
}
}
@@ -351,15 +344,10 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
	stac9766_reset(codec, 0);
	stac9766_reset(codec, 0);
	ret = stac9766_reset(codec, 1);
	ret = stac9766_reset(codec, 1);
	if (ret < 0) {
	if (ret < 0) {
		printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
		dev_err(codec->dev, "Failed to reset: AC97 link error\n");
		goto codec_err;
		goto codec_err;
	}
	}


	stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
			     ARRAY_SIZE(stac9766_snd_ac97_controls));

	return 0;
	return 0;


codec_err:
codec_err:
@@ -376,12 +364,14 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec)
}
}


static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
	.controls = stac9766_snd_ac97_controls,
	.num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls),
	.write = stac9766_ac97_write,
	.write = stac9766_ac97_write,
	.read = stac9766_ac97_read,
	.read = stac9766_ac97_read,
	.set_bias_level = stac9766_set_bias_level,
	.set_bias_level = stac9766_set_bias_level,
	.suspend_bias_off = true,
	.probe = stac9766_codec_probe,
	.probe = stac9766_codec_probe,
	.remove = stac9766_codec_remove,
	.remove = stac9766_codec_remove,
	.suspend = stac9766_codec_suspend,
	.resume = stac9766_codec_resume,
	.resume = stac9766_codec_resume,
	.reg_cache_size = ARRAY_SIZE(stac9766_reg),
	.reg_cache_size = ARRAY_SIZE(stac9766_reg),
	.reg_word_size = sizeof(u16),
	.reg_word_size = sizeof(u16),