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

Commit 4cb803b8 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/rt5645' into asoc-next

parents b27aafed bc86e53a
Loading
Loading
Loading
Loading
+137 −2
Original line number Original line Diff line number Diff line
@@ -42,6 +42,8 @@


#define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING))
#define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING))


#define RT5645_HWEQ_NUM 57

static const struct regmap_range_cfg rt5645_ranges[] = {
static const struct regmap_range_cfg rt5645_ranges[] = {
	{
	{
		.name = "PR",
		.name = "PR",
@@ -224,6 +226,11 @@ static const struct reg_default rt5645_reg[] = {
	{ 0xff, 0x6308 },
	{ 0xff, 0x6308 },
};
};


struct rt5645_eq_param_s {
	unsigned short reg;
	unsigned short val;
};

static const char *const rt5645_supply_names[] = {
static const char *const rt5645_supply_names[] = {
	"avdd",
	"avdd",
	"cpvdd",
	"cpvdd",
@@ -240,6 +247,7 @@ struct rt5645_priv {
	struct snd_soc_jack *btn_jack;
	struct snd_soc_jack *btn_jack;
	struct delayed_work jack_detect_work;
	struct delayed_work jack_detect_work;
	struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
	struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
	struct rt5645_eq_param_s *eq_param;


	int codec_type;
	int codec_type;
	int sysclk;
	int sysclk;
@@ -469,6 +477,94 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv,
	8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
	8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
);
);


/* {-6, -4.5, -3, -1.5, 0, 0.82, 1.58, 2.28} dB */
static const DECLARE_TLV_DB_RANGE(spk_clsd_tlv,
	0, 4, TLV_DB_SCALE_ITEM(-600, 150, 0),
	5, 5, TLV_DB_SCALE_ITEM(82, 0, 0),
	6, 6, TLV_DB_SCALE_ITEM(158, 0, 0),
	7, 7, TLV_DB_SCALE_ITEM(228, 0, 0)
);

static int rt5645_hweq_info(struct snd_kcontrol *kcontrol,
			 struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	uinfo->count = RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s);

	return 0;
}

static int rt5645_hweq_get(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
	struct rt5645_eq_param_s *eq_param =
		(struct rt5645_eq_param_s *)ucontrol->value.bytes.data;
	int i;

	for (i = 0; i < RT5645_HWEQ_NUM; i++) {
		eq_param[i].reg = cpu_to_be16(rt5645->eq_param[i].reg);
		eq_param[i].val = cpu_to_be16(rt5645->eq_param[i].val);
	}

	return 0;
}

static bool rt5645_validate_hweq(unsigned short reg)
{
	if ((reg >= 0x1a4 && reg <= 0x1cd) | (reg >= 0x1e5 && reg <= 0x1f8) |
		(reg == RT5645_EQ_CTRL2))
		return true;

	return false;
}

static int rt5645_hweq_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
	struct rt5645_eq_param_s *eq_param =
		(struct rt5645_eq_param_s *)ucontrol->value.bytes.data;
	int i;

	for (i = 0; i < RT5645_HWEQ_NUM; i++) {
		eq_param[i].reg = be16_to_cpu(eq_param[i].reg);
		eq_param[i].val = be16_to_cpu(eq_param[i].val);
	}

	/* The final setting of the table should be RT5645_EQ_CTRL2 */
	for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) {
		if (eq_param[i].reg == 0)
			continue;
		else if (eq_param[i].reg != RT5645_EQ_CTRL2)
			return 0;
		else
			break;
	}

	for (i = 0; i < RT5645_HWEQ_NUM; i++) {
		if (!rt5645_validate_hweq(eq_param[i].reg) &&
			eq_param[i].reg != 0)
			return 0;
		else if (eq_param[i].reg == 0)
			break;
	}

	memcpy(rt5645->eq_param, eq_param,
		RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s));

	return 0;
}

#define RT5645_HWEQ(xname) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.info = rt5645_hweq_info, \
	.get = rt5645_hweq_get, \
	.put = rt5645_hweq_put \
}

static const struct snd_kcontrol_new rt5645_snd_controls[] = {
static const struct snd_kcontrol_new rt5645_snd_controls[] = {
	/* Speaker Output Volume */
	/* Speaker Output Volume */
	SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
	SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
@@ -476,6 +572,10 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
	SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
	SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
		RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
		RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),


	/* ClassD modulator Speaker Gain Ratio */
	SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO,
		RT5645_SPK_G_CLSD_SFT, 7, 0, spk_clsd_tlv),

	/* Headphone Output Volume */
	/* Headphone Output Volume */
	SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL,
	SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL,
		RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
		RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
@@ -529,6 +629,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
	/* I2S2 function select */
	/* I2S2 function select */
	SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT,
	SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT,
		1, 1),
		1, 1),
	RT5645_HWEQ("Speaker HWEQ"),
};
};


/**
/**
@@ -619,6 +720,22 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,


}
}


static int rt5645_enable_hweq(struct snd_soc_codec *codec)
{
	struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
	int i;

	for (i = 0; i < RT5645_HWEQ_NUM; i++) {
		if (rt5645_validate_hweq(rt5645->eq_param[i].reg))
			regmap_write(rt5645->regmap, rt5645->eq_param[i].reg,
					rt5645->eq_param[i].val);
		else
			break;
	}

	return 0;
}

/**
/**
 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
 * @codec: SoC audio codec device.
 * @codec: SoC audio codec device.
@@ -1523,6 +1640,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,


	switch (event) {
	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
	case SND_SOC_DAPM_POST_PMU:
		rt5645_enable_hweq(codec);
		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
			RT5645_PWR_CLS_D_L,
			RT5645_PWR_CLS_D_L,
@@ -1531,6 +1649,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
		break;
		break;


	case SND_SOC_DAPM_PRE_PMD:
	case SND_SOC_DAPM_PRE_PMD:
		snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
			RT5645_PWR_CLS_D_L, 0);
			RT5645_PWR_CLS_D_L, 0);
@@ -2733,6 +2852,10 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
		snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
			RT5645_PWR_FV1 | RT5645_PWR_FV2,
			RT5645_PWR_FV1 | RT5645_PWR_FV2,
			RT5645_PWR_FV1 | RT5645_PWR_FV2);
			RT5645_PWR_FV1 | RT5645_PWR_FV2);
		if (rt5645->en_button_func &&
			snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
			queue_delayed_work(system_power_efficient_wq,
				&rt5645->jack_detect_work, msecs_to_jiffies(0));
		break;
		break;


	case SND_SOC_BIAS_OFF:
	case SND_SOC_BIAS_OFF:
@@ -3044,6 +3167,9 @@ static int rt5645_probe(struct snd_soc_codec *codec)
		snd_soc_dapm_sync(dapm);
		snd_soc_dapm_sync(dapm);
	}
	}


	rt5645->eq_param = devm_kzalloc(codec->dev,
		RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL);

	return 0;
	return 0;
}
}


@@ -3104,7 +3230,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = {
		.capture = {
		.capture = {
			.stream_name = "AIF1 Capture",
			.stream_name = "AIF1 Capture",
			.channels_min = 1,
			.channels_min = 1,
			.channels_max = 2,
			.channels_max = 4,
			.rates = RT5645_STEREO_RATES,
			.rates = RT5645_STEREO_RATES,
			.formats = RT5645_FORMATS,
			.formats = RT5645_FORMATS,
		},
		},
@@ -3215,6 +3341,13 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
			DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
		},
		},
	},
	},
	{
		.ident = "Google Reks",
		.callback = strago_quirk_cb,
		.matches = {
			DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
		},
	},
	{ }
	{ }
};
};


@@ -3232,7 +3365,7 @@ static int buddy_quirk_cb(const struct dmi_system_id *id)
	return 1;
	return 1;
}
}


static struct dmi_system_id dmi_platform_intel_broadwell[] __initdata = {
static struct dmi_system_id dmi_platform_intel_broadwell[] = {
	{
	{
		.ident = "Chrome Buddy",
		.ident = "Chrome Buddy",
		.callback = buddy_quirk_cb,
		.callback = buddy_quirk_cb,
@@ -3505,6 +3638,8 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
		RT5645_CBJ_MN_JD);
		RT5645_CBJ_MN_JD);
	regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN,
	regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN,
		0);
		0);
	msleep(20);
	regmap_write(rt5645->regmap, RT5645_RESET, 0);
}
}


static struct i2c_driver rt5645_i2c_driver = {
static struct i2c_driver rt5645_i2c_driver = {
+14 −10
Original line number Original line Diff line number Diff line
@@ -621,14 +621,14 @@
#define RT5645_G_OM_L_SM_L_SFT			6
#define RT5645_G_OM_L_SM_L_SFT			6
#define RT5645_M_BST1_L_SM_L			(0x1 << 5)
#define RT5645_M_BST1_L_SM_L			(0x1 << 5)
#define RT5645_M_BST1_L_SM_L_SFT		5
#define RT5645_M_BST1_L_SM_L_SFT		5
#define RT5645_M_BST3_L_SM_L			(0x1 << 4)
#define RT5645_M_BST3_L_SM_L_SFT		4
#define RT5645_M_IN_L_SM_L			(0x1 << 3)
#define RT5645_M_IN_L_SM_L			(0x1 << 3)
#define RT5645_M_IN_L_SM_L_SFT			3
#define RT5645_M_IN_L_SM_L_SFT			3
#define RT5645_M_DAC_L1_SM_L			(0x1 << 1)
#define RT5645_M_DAC_L1_SM_L_SFT		1
#define RT5645_M_DAC_L2_SM_L			(0x1 << 2)
#define RT5645_M_DAC_L2_SM_L			(0x1 << 2)
#define RT5645_M_DAC_L2_SM_L_SFT		2
#define RT5645_M_DAC_L2_SM_L_SFT		2
#define RT5645_M_BST3_L_SM_L			(0x1 << 4)
#define RT5645_M_DAC_L1_SM_L			(0x1 << 1)
#define RT5645_M_BST3_L_SM_L_SFT		4
#define RT5645_M_DAC_L1_SM_L_SFT		1


/* SPK Right Mixer Control (0x47) */
/* SPK Right Mixer Control (0x47) */
#define RT5645_G_RM_R_SM_R_MASK			(0x3 << 14)
#define RT5645_G_RM_R_SM_R_MASK			(0x3 << 14)
@@ -643,14 +643,14 @@
#define RT5645_G_OM_R_SM_R_SFT			6
#define RT5645_G_OM_R_SM_R_SFT			6
#define RT5645_M_BST2_R_SM_R			(0x1 << 5)
#define RT5645_M_BST2_R_SM_R			(0x1 << 5)
#define RT5645_M_BST2_R_SM_R_SFT		5
#define RT5645_M_BST2_R_SM_R_SFT		5
#define RT5645_M_BST3_R_SM_R			(0x1 << 4)
#define RT5645_M_BST3_R_SM_R_SFT		4
#define RT5645_M_IN_R_SM_R			(0x1 << 3)
#define RT5645_M_IN_R_SM_R			(0x1 << 3)
#define RT5645_M_IN_R_SM_R_SFT			3
#define RT5645_M_IN_R_SM_R_SFT			3
#define RT5645_M_DAC_R1_SM_R			(0x1 << 1)
#define RT5645_M_DAC_R1_SM_R_SFT		1
#define RT5645_M_DAC_R2_SM_R			(0x1 << 2)
#define RT5645_M_DAC_R2_SM_R			(0x1 << 2)
#define RT5645_M_DAC_R2_SM_R_SFT		2
#define RT5645_M_DAC_R2_SM_R_SFT		2
#define RT5645_M_BST3_R_SM_R			(0x1 << 4)
#define RT5645_M_DAC_R1_SM_R			(0x1 << 1)
#define RT5645_M_BST3_R_SM_R_SFT		4
#define RT5645_M_DAC_R1_SM_R_SFT		1


/* SPOLMIX Control (0x48) */
/* SPOLMIX Control (0x48) */
#define RT5645_M_DAC_L1_SPM_L			(0x1 << 15)
#define RT5645_M_DAC_L1_SPM_L			(0x1 << 15)
@@ -670,13 +670,17 @@
#define RT5645_M_SV_R_SPM_R			(0x1 << 0)
#define RT5645_M_SV_R_SPM_R			(0x1 << 0)
#define RT5645_M_SV_R_SPM_R_SFT			0
#define RT5645_M_SV_R_SPM_R_SFT			0


/* SPOMIX Ratio Control (0x4a) */
#define RT5645_SPK_G_CLSD_MASK			(0x7 << 0)
#define RT5645_SPK_G_CLSD_SFT			0

/* Mono Output Mixer Control (0x4c) */
/* Mono Output Mixer Control (0x4c) */
#define RT5645_G_MONOMIX_MASK			(0x1 << 10)
#define RT5645_G_MONOMIX_SFT			10
#define RT5645_M_OV_L_MM			(0x1 << 9)
#define RT5645_M_OV_L_MM			(0x1 << 9)
#define RT5645_M_OV_L_MM_SFT			9
#define RT5645_M_OV_L_MM_SFT			9
#define RT5645_M_DAC_L2_MA			(0x1 << 8)
#define RT5645_M_DAC_L2_MA			(0x1 << 8)
#define RT5645_M_DAC_L2_MA_SFT			8
#define RT5645_M_DAC_L2_MA_SFT			8
#define RT5645_G_MONOMIX_MASK			(0x1 << 10)
#define RT5645_G_MONOMIX_SFT			10
#define RT5645_M_BST2_MM			(0x1 << 4)
#define RT5645_M_BST2_MM			(0x1 << 4)
#define RT5645_M_BST2_MM_SFT			4
#define RT5645_M_BST2_MM_SFT			4
#define RT5645_M_DAC_R1_MM			(0x1 << 3)
#define RT5645_M_DAC_R1_MM			(0x1 << 3)