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

Commit 6e6d57d0 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/topic/rcar', 'asoc/topic/rockchip',...

Merge remote-tracking branches 'asoc/topic/rcar', 'asoc/topic/rockchip', 'asoc/topic/rt286' and 'asoc/topic/rt5631' into asoc-next
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
Renesas R-Car sound

Required properties:
- compatible			: "renesas,rcar_sound-gen1" if generation1
- compatible			: "renesas,rcar_sound-<soctype>", fallbacks
				  "renesas,rcar_sound-gen1" if generation1, and
				  "renesas,rcar_sound-gen2" if generation2
				  Examples with soctypes are:
				    - "renesas,rcar_sound-r8a7790" (R-Car H2)
				    - "renesas,rcar_sound-r8a7791" (R-Car M2-W)
- reg				: Should contain the register physical address.
				  required register is
				   SRU/ADG/SSI      if generation1
@@ -35,9 +39,9 @@ DAI subnode properties:

Example:

rcar_sound: rcar_sound@0xffd90000 {
rcar_sound: rcar_sound@ec500000 {
	#sound-dai-cells = <1>;
	compatible = "renesas,rcar_sound-gen2";
	compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
	reg =	<0 0xec500000 0 0x1000>, /* SCU */
		<0 0xec5a0000 0 0x100>,  /* ADG */
		<0 0xec540000 0 0x1000>, /* SSIU */
+48 −0
Original line number Diff line number Diff line
ALC5631/RT5631 audio CODEC

This device supports I2C only.

Required properties:

  - compatible : "realtek,alc5631" or "realtek,rt5631"

  - reg : the I2C address of the device.

Pins on the device (for linking into audio routes):

  * SPK_OUT_R_P
  * SPK_OUT_R_N
  * SPK_OUT_L_P
  * SPK_OUT_L_N
  * HP_OUT_L
  * HP_OUT_R
  * AUX_OUT2_LP
  * AUX_OUT2_RN
  * AUX_OUT1_LP
  * AUX_OUT1_RN
  * AUX_IN_L_JD
  * AUX_IN_R_JD
  * MONO_IN_P
  * MONO_IN_N
  * MIC1_P
  * MIC1_N
  * MIC2_P
  * MIC2_N
  * MONO_OUT_P
  * MONO_OUT_N
  * MICBIAS1
  * MICBIAS2

Example:

alc5631: alc5631@1a {
	compatible = "realtek,alc5631";
	reg = <0x1a>;
};

or

rt5631: rt5631@1a {
	compatible = "realtek,rt5631";
	reg = <0x1a>;
};
+4 −4
Original line number Diff line number Diff line
@@ -36,14 +36,14 @@
#define RSND_SSI_CLK_PIN_SHARE		(1 << 31)
#define RSND_SSI_NO_BUSIF		(1 << 30) /* SSI+DMA without BUSIF */

#define RSND_SSI(_dma_id, _pio_irq, _flags)		\
{ .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags }
#define RSND_SSI(_dma_id, _irq, _flags)		\
{ .dma_id = _dma_id, .irq = _irq, .flags = _flags }
#define RSND_SSI_UNUSED \
{ .dma_id = -1, .pio_irq = -1, .flags = 0 }
{ .dma_id = -1, .irq = -1, .flags = 0 }

struct rsnd_ssi_platform_info {
	int dma_id;
	int pio_irq;
	int irq;
	u32 flags;
};

+2 −1
Original line number Diff line number Diff line
@@ -501,7 +501,8 @@ config SND_SOC_RT286
	depends on I2C

config SND_SOC_RT5631
	tristate
	tristate "Realtek ALC5631/RT5631 CODEC"
	depends on I2C

config SND_SOC_RT5640
	tristate
+172 −59
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -36,11 +37,13 @@

struct rt286_priv {
	struct regmap *regmap;
	struct snd_soc_codec *codec;
	struct rt286_platform_data pdata;
	struct i2c_client *i2c;
	struct snd_soc_jack *jack;
	struct delayed_work jack_detect_work;
	int sys_clk;
	int clk_id;
	struct reg_default *index_cache;
};

@@ -298,7 +301,6 @@ static int rt286_support_power_controls[] = {
static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
{
	unsigned int val, buf;
	int i;

	*hp = false;
	*mic = false;
@@ -309,67 +311,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
		if (*hp) {
			/* power on HV,VERF */
			regmap_update_bits(rt286->regmap,
				RT286_POWER_CTRL1, 0x1001, 0x0);
				RT286_DC_GAIN, 0x200, 0x200);

			snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
							"HV");
			snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
							"VREF");
			/* power LDO1 */
			regmap_update_bits(rt286->regmap,
				RT286_POWER_CTRL2, 0x4, 0x4);
			snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
							"LDO1");
			snd_soc_dapm_sync(&rt286->codec->dapm);

			regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
			msleep(50);

			regmap_update_bits(rt286->regmap,
				RT286_CBJ_CTRL1, 0xfcc0, 0xd400);
			msleep(300);
			regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val);

			msleep(200);
			i = 40;
			while (((val & 0x0800) == 0) && (i > 0)) {
			if (0x0070 == (val & 0x0070)) {
				*mic = true;
			} else {
				regmap_update_bits(rt286->regmap,
					RT286_CBJ_CTRL1, 0xfcc0, 0xe400);
				msleep(300);
				regmap_read(rt286->regmap,
					RT286_CBJ_CTRL2, &val);
				i--;
				msleep(20);
			}

			if (0x0400 == (val & 0x0700)) {
				*mic = false;

				regmap_write(rt286->regmap,
					RT286_SET_MIC1, 0x20);
				/* power off HV,VERF */
				regmap_update_bits(rt286->regmap,
					RT286_POWER_CTRL1, 0x1001, 0x1001);
				regmap_update_bits(rt286->regmap,
					RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
				regmap_update_bits(rt286->regmap,
					RT286_CBJ_CTRL1, 0x0030, 0x0000);
				regmap_update_bits(rt286->regmap,
					RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
			} else if ((0x0200 == (val & 0x0700)) ||
				(0x0100 == (val & 0x0700))) {
				if (0x0070 == (val & 0x0070))
					*mic = true;
				regmap_update_bits(rt286->regmap,
					RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
				regmap_update_bits(rt286->regmap,
					RT286_CBJ_CTRL1, 0x0030, 0x0020);
				regmap_update_bits(rt286->regmap,
					RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
			} else {
				else
					*mic = false;
			}

			regmap_update_bits(rt286->regmap,
						RT286_MISC_CTRL1,
						0x0060, 0x0000);
		} else {
			regmap_update_bits(rt286->regmap,
						RT286_MISC_CTRL1,
						0x0060, 0x0020);
			regmap_update_bits(rt286->regmap,
						RT286_A_BIAS_CTRL3,
						0xc000, 0x8000);
			regmap_update_bits(rt286->regmap,
						RT286_CBJ_CTRL1,
						0x0030, 0x0020);
			regmap_update_bits(rt286->regmap,
						RT286_A_BIAS_CTRL2,
						0xc000, 0x8000);
				RT286_DC_GAIN, 0x200, 0x0);

		} else {
			*mic = false;
			regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20);
		}
	} else {
		regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
@@ -378,6 +357,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
		*mic = buf & 0x80000000;
	}

	snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV");
	snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF");
	if (!*hp)
		snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1");
	snd_soc_dapm_sync(&rt286->codec->dapm);

	return 0;
}

@@ -415,6 +400,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
}
EXPORT_SYMBOL_GPL(rt286_mic_detect);

static int is_mclk_mode(struct snd_soc_dapm_widget *source,
			 struct snd_soc_dapm_widget *sink)
{
	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec);

	if (rt286->clk_id == RT286_SCLK_S_MCLK)
		return 1;
	else
		return 0;
}

static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0);
static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);

@@ -568,7 +564,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w,
	return 0;
}

static int rt286_vref_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		snd_soc_update_bits(codec,
			RT286_CBJ_CTRL1, 0x0400, 0x0000);
		mdelay(50);
		break;
	default:
		return 0;
	}

	return 0;
}

static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30);
		break;
	default:
		return 0;
	}

	return 0;
}

static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		snd_soc_update_bits(codec,
			RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
		snd_soc_update_bits(codec,
			RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
		break;
	case SND_SOC_DAPM_POST_PMD:
		snd_soc_update_bits(codec,
			RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
		snd_soc_update_bits(codec,
			RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
		break;
	default:
		return 0;
	}

	return 0;
}

static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
	SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1,
		12, 1, NULL, 0),
	SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1,
		0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU),
	SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2,
		2, 0, NULL, 0),
	SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1,
		13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD |
		SND_SOC_DAPM_POST_PMU),
	SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1,
		5, 0, NULL, 0),
	SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM,
		0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU |
		SND_SOC_DAPM_POST_PMD),

	/* Input Lines */
	SND_SOC_DAPM_INPUT("DMIC1 Pin"),
	SND_SOC_DAPM_INPUT("DMIC2 Pin"),
@@ -642,6 +715,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
};

static const struct snd_soc_dapm_route rt286_dapm_routes[] = {
	{"ADC 0", NULL, "MCLK MODE", is_mclk_mode},
	{"ADC 1", NULL, "MCLK MODE", is_mclk_mode},
	{"Front", NULL, "MCLK MODE", is_mclk_mode},
	{"Surround", NULL, "MCLK MODE", is_mclk_mode},

	{"HP Power", NULL, "LDO1"},
	{"HP Power", NULL, "LDO2"},

	{"MIC1", NULL, "LDO1"},
	{"MIC1", NULL, "LDO2"},
	{"MIC1", NULL, "HV"},
	{"MIC1", NULL, "VREF"},
	{"MIC1", NULL, "MIC1 Input Buffer"},

	{"SPO", NULL, "LDO1"},
	{"SPO", NULL, "LDO2"},
	{"SPO", NULL, "HV"},
	{"SPO", NULL, "VREF"},

	{"DMIC1", NULL, "DMIC1 Pin"},
	{"DMIC2", NULL, "DMIC2 Pin"},
	{"DMIC1", NULL, "DMIC Receiver"},
@@ -880,6 +972,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
	}

	rt286->sys_clk = freq;
	rt286->clk_id = clk_id;

	return 0;
}
@@ -915,13 +1008,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,

	case SND_SOC_BIAS_ON:
		mdelay(10);
		snd_soc_update_bits(codec,
			RT286_CBJ_CTRL1, 0x0400, 0x0400);
		snd_soc_update_bits(codec,
			RT286_DC_GAIN, 0x200, 0x0);

		break;

	case SND_SOC_BIAS_STANDBY:
		snd_soc_write(codec,
			RT286_SET_AUDIO_POWER, AC_PWRST_D3);
		snd_soc_update_bits(codec,
			RT286_DC_GAIN, 0x200, 0x0);
			RT286_CBJ_CTRL1, 0x0400, 0x0000);
		break;

	default:
@@ -962,6 +1060,7 @@ static int rt286_probe(struct snd_soc_codec *codec)
{
	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);

	rt286->codec = codec;
	codec->dapm.bias_level = SND_SOC_BIAS_OFF;

	if (rt286->i2c->irq) {
@@ -1107,6 +1206,16 @@ static const struct acpi_device_id rt286_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, rt286_acpi_match);

static struct dmi_system_id force_combo_jack_table[] = {
	{
		.ident = "Intel Wilson Beach",
		.matches = {
			DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS")
		}
	},
	{ }
};

static int rt286_i2c_probe(struct i2c_client *i2c,
			   const struct i2c_device_id *id)
{
@@ -1142,6 +1251,9 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
	if (pdata)
		rt286->pdata = *pdata;

	if (dmi_check_system(force_combo_jack_table))
		rt286->pdata.cbj_en = true;

	regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3);

	for (i = 0; i < RT286_POWER_REG_LEN; i++)
@@ -1152,7 +1264,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
	if (!rt286->pdata.cbj_en) {
		regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000);
		regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816);
		regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000);
		regmap_update_bits(rt286->regmap,
					RT286_CBJ_CTRL1, 0xf000, 0xb000);
	} else {
@@ -1169,8 +1280,10 @@ static int rt286_i2c_probe(struct i2c_client *i2c,

	mdelay(10);

	/*Power down LDO2*/
	regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0);
	regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000);
	/* Power down LDO, VREF */
	regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0);
	regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001);

	/* Set depop parameter */
	regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a);
Loading