@@ -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, ®_val);
- if (sizeof(reg_val) > 2)
- reg_val = cpu_to_le32(reg_val);
- else
- reg_val = cpu_to_le16(reg_val);
- memcpy(val + i, ®_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"},
Signed-off-by: Kiseok Jo <kiseok.jo@irondevice.com> --- sound/soc/codecs/sma1303.c | 196 +++++++++++++------------------------ 1 file changed, 66 insertions(+), 130 deletions(-)