diff mbox series

[12/14] Add the postscaler's switch in DAPM manage.

Message ID 20230106091543.2440-13-kiseok.jo@irondevice.com
State New
Headers show
Series ASoC: Add a driver the Iron Device SMA1303 AMP | expand

Commit Message

Kiseok Jo Jan. 6, 2023, 9:15 a.m. UTC
Signed-off-by: Kiseok Jo <kiseok.jo@irondevice.com>
---
 sound/soc/codecs/sma1303.c | 196 +++++++++++++------------------------
 1 file changed, 66 insertions(+), 130 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/codecs/sma1303.c b/sound/soc/codecs/sma1303.c
index ea4356233c2f..08f5054fde1d 100644
--- a/sound/soc/codecs/sma1303.c
+++ b/sound/soc/codecs/sma1303.c
@@ -301,132 +301,6 @@  static int sma1303_regmap_read(struct sma1303_priv *sma1303,
 	return ret;
 }
 
-static int bytes_ext_get(struct snd_kcontrol *kcontrol,
-			struct snd_ctl_elem_value *ucontrol, int reg)
-{
-	struct snd_soc_component *component =
-		snd_soc_kcontrol_component(kcontrol);
-	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
-	struct soc_bytes_ext *params = (void *)kcontrol->private_value;
-	unsigned int i, reg_val;
-	u8 *val;
-	int ret;
-
-	val = (u8 *)ucontrol->value.bytes.data;
-	for (i = 0; i < params->max; i++) {
-		ret = sma1303_regmap_read(sma1303, reg + i, &reg_val);
-		if (sizeof(reg_val) > 2)
-			reg_val = cpu_to_le32(reg_val);
-		else
-			reg_val = cpu_to_le16(reg_val);
-		memcpy(val + i, &reg_val, sizeof(u8));
-	}
-
-	return ret;
-}
-
-static int bytes_ext_put(struct snd_kcontrol *kcontrol,
-			struct snd_ctl_elem_value *ucontrol, int reg)
-{
-	struct snd_soc_component *component =
-		snd_soc_kcontrol_component(kcontrol);
-	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
-	struct soc_bytes_ext *params = (void *)kcontrol->private_value;
-	void *data;
-	u8 *val;
-	int i, ret;
-
-	data = kmemdup(ucontrol->value.bytes.data,
-			params->max, GFP_KERNEL | GFP_DMA);
-	if (!data)
-		return -ENOMEM;
-
-	val = (u8 *)data;
-	for (i = 0; i < params->max; i++) {
-		ret = sma1303_regmap_write(sma1303, reg + i, *(val + i));
-		if (ret < 0) {
-			kfree(data);
-			return ret;
-		}
-	}
-	kfree(data);
-
-	return 0;
-}
-
-static int postscaler_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	return bytes_ext_get(kcontrol, ucontrol, SMA1303_90_POSTSCALER);
-}
-
-static int postscaler_put(struct snd_kcontrol *kcontrol,
-	struct snd_ctl_elem_value *ucontrol)
-{
-	return bytes_ext_put(kcontrol, ucontrol, SMA1303_90_POSTSCALER);
-}
-
-static const char * const sma1303_postscaler_config_text[] = {
-	"Enable", "Disable"};
-
-static const struct soc_enum sma1303_postscaler_config_enum =
-	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_postscaler_config_text),
-			sma1303_postscaler_config_text);
-
-static int sma1303_postscaler_config_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_component *component =
-		snd_soc_kcontrol_component(kcontrol);
-	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
-	int ret, data, val;
-
-	ret = sma1303_regmap_read(sma1303, SMA1303_90_POSTSCALER, &data);
-	val = data & SMA1303_BYP_POST_MASK;
-	switch (val) {
-	case SMA1303_BYP_POST_SCALER:
-		ucontrol->value.integer.value[0] = 1;
-		break;
-	case SMA1303_EN_POST_SCALER:
-		ucontrol->value.integer.value[0] = 0;
-		break;
-	default:
-		dev_err(component->dev,
-				"Invalid value, register: %x value: %d\n",
-					SMA1303_90_POSTSCALER, val);
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-static int sma1303_postscaler_config_put(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_component *component =
-		snd_soc_kcontrol_component(kcontrol);
-	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
-	int sel = (int)ucontrol->value.integer.value[0];
-	int val;
-
-	switch (sel) {
-	case 0:
-		val = SMA1303_EN_POST_SCALER;
-		break;
-	case 1:
-		val = SMA1303_BYP_POST_SCALER;
-		break;
-	default:
-		dev_err(component->dev,
-				"Invalid value, register: %x\n",
-					SMA1303_90_POSTSCALER);
-		return -EINVAL;
-	}
-
-	return sma1303_regmap_update_bits(sma1303,
-			SMA1303_90_POSTSCALER, SMA1303_BYP_POST_MASK, val);
-}
-
 static const char * const sma1303_aif_in_source_text[] = {
 	"Mono", "Left", "Right"};
 static const char * const sma1303_aif_out_source_text[] = {
@@ -468,6 +342,34 @@  static int sma1303_force_mute_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int sma1303_postscaler_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+		snd_soc_kcontrol_component(kcontrol);
+	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
+	int val, ret;
+
+	ret = sma1303_regmap_read(sma1303, SMA1303_90_POSTSCALER, &val);
+	ucontrol->value.integer.value[0] = (val & 0x7E) >> 1;
+
+	return ret;
+}
+
+static int sma1303_postscaler_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+		snd_soc_kcontrol_component(kcontrol);
+	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
+	int ret, sel = (int)ucontrol->value.integer.value[0];
+
+	ret = sma1303_regmap_update_bits(sma1303,
+			SMA1303_90_POSTSCALER, 0x70, (sel << 1));
+
+	return ret;
+}
+
 static int sma1303_startup(struct snd_soc_component *component)
 {
 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
@@ -727,6 +629,34 @@  static int sma1303_sdo_event(struct snd_soc_dapm_widget *w,
 	return ret;
 }
 
+static int sma1303_post_scaler_event(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+		snd_soc_dapm_to_component(w->dapm);
+	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		dev_info(sma1303->dev,
+				"%s : SND_SOC_DAPM_PRE_PMU\n", __func__);
+		sma1303_regmap_update_bits(sma1303,
+				SMA1303_90_POSTSCALER,
+				SMA1303_BYP_POST_MASK,
+				SMA1303_EN_POST_SCALER);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		dev_info(sma1303->dev,
+				"%s : SND_SOC_DAPM_POST_PMD\n", __func__);
+		sma1303_regmap_update_bits(sma1303,
+				SMA1303_90_POSTSCALER,
+				SMA1303_BYP_POST_MASK,
+				SMA1303_BYP_POST_SCALER);
+		break;
+	}
+	return 0;
+}
+
 static int sma1303_power_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
@@ -756,18 +686,18 @@  static const struct snd_kcontrol_new sma1303_aif_out_source_control =
 	SOC_DAPM_ENUM("AIF OUT Source", sma1303_aif_out_source_enum);
 static const struct snd_kcontrol_new sma1303_sdo_control =
 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
+static const struct snd_kcontrol_new sma1303_post_scaler_control =
+	SOC_DAPM_SINGLE_VIRT("Switch", 1);
 static const struct snd_kcontrol_new sma1303_enable_control =
 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
 
 static const struct snd_kcontrol_new sma1303_snd_controls[] = {
 	SOC_SINGLE_TLV("Speaker Volume", SMA1303_0A_SPK_VOL,
 		0, 167, 1, sma1303_spk_tlv),
-	SND_SOC_BYTES_EXT("Postscaler Set", 1,
-		postscaler_get, postscaler_put),
-	SOC_ENUM_EXT("Postscaler Config", sma1303_postscaler_config_enum,
-		sma1303_postscaler_config_get, sma1303_postscaler_config_put),
 	SOC_SINGLE_BOOL_EXT("Force Mute", 0,
 		sma1303_force_mute_get, sma1303_force_mute_put),
+	SOC_SINGLE_EXT("Postscaler Gain", SMA1303_90_POSTSCALER, 1, 0x30, 0,
+		sma1303_postscaler_get, sma1303_postscaler_put),
 };
 
 static const struct snd_soc_dapm_widget sma1303_dapm_widgets[] = {
@@ -789,6 +719,10 @@  static const struct snd_soc_dapm_widget sma1303_dapm_widgets[] = {
 			sma1303_sdo_event,
 			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_MIXER("Entry", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SWITCH_E("Post Scaler", SND_SOC_NOPM, 0, 1,
+			&sma1303_post_scaler_control,
+			sma1303_post_scaler_event,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_OUT_DRV_E("AMP Power", SND_SOC_NOPM, 0, 0, NULL, 0,
 			sma1303_power_event,
 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -818,6 +752,8 @@  static const struct snd_soc_dapm_route sma1303_audio_map[] = {
 	{"Entry", NULL, "AIF OUT Source"},
 	{"Entry", NULL, "AIF IN Source"},
 
+	{"Post Scaler", "Switch", "Entry"},
+	{"AMP Power", NULL, "Entry"},
 	{"AMP Power", NULL, "Entry"},
 
 	{"AMP Enable", "Switch", "AMP Power"},