Re: [PATCH v3 4/7] ASoC: codecs: wcd938x: add basic controls

2021-03-19 Thread Pierre-Louis Bossart




+static int wcd938x_ear_pa_put_gain(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   struct wcd938x_priv *wcd938x = wcd->wcd938x;
+
+   if (wcd938x->comp1_enable) {
+   dev_err(component->dev, "Can not set EAR PA Gain, compander1 is 
enabled\n");
+   return -EINVAL;
+   }
+
+   snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
+ WCD938X_EAR_GAIN_MASK,
+ ucontrol->value.integer.value[0]);
+
+   return 0;


that goes back to my other comments, the earpiece is connected to the RX 
interface, so what component would be used to set the gain here? the TX 
one? But what tells you this component is active and ready to support 
commands?




[PATCH v3 4/7] ASoC: codecs: wcd938x: add basic controls

2021-03-19 Thread Srinivas Kandagatla
This patch adds basic controls found in wcd938x codec.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/codecs/wcd938x.c | 415 +
 1 file changed, 415 insertions(+)

diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index 9e8d588e2235..9b5dda775a17 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -66,6 +66,15 @@
 #define WCD938X_MBHC_MOISTURE_RREF  R_24_KOHM
 #define WCD_MBHC_HS_V_MAX   1600
 
+#define WCD938X_EAR_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \
+{  .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+   .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+   .tlv.p = (tlv_array), \
+   .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
+   .put = wcd938x_ear_pa_put_gain, \
+   .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
+
 enum {
WCD9380 = 0,
WCD9385 = 5,
@@ -187,6 +196,9 @@ enum {
 };
 
 static struct wcd938x_priv *g_wcd938x;
+static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
+static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(line_gain, 600, -3000);
+static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000);
 
 static const struct reg_default wcd938x_defaults[] = {
{WCD938X_ANA_PAGE_REGISTER,0x00},
@@ -1275,6 +1287,380 @@ int wcd938x_io_init(struct wcd938x_sdw_priv *wcd)
 
 }
 
+static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
+   struct sdw_port_config *port_config,
+   u32 mstr_port_num,
+   u8 enable)
+{
+   u8 ch_mask, port_num;
+
+   port_num = ch_info->port_num;
+   ch_mask = ch_info->ch_mask;
+
+   port_config->num = port_num;
+
+   if (enable)
+   port_config->ch_mask |= ch_mask;
+   else
+   port_config->ch_mask &= ~ch_mask;
+
+   return 0;
+}
+
+static int wcd938x_connect_port(struct snd_soc_component *component, u8 ch_id, 
u8 enable)
+{
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   u8 port_num, mstr_port_num;
+
+   port_num = wcd->ch_info[ch_id].port_num;
+   mstr_port_num = wcd->port_map[port_num - 1];
+
+   return wcd938x_sdw_connect_port(>ch_info[ch_id],
+   >port_config[port_num],
+   mstr_port_num,
+   enable);
+}
+
+static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   struct wcd938x_priv *wcd938x = wcd->wcd938x;
+   struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+   int path = e->shift_l;
+
+   ucontrol->value.integer.value[0] = wcd938x->tx_mode[path];
+
+   return 0;
+}
+
+static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   struct wcd938x_priv *wcd938x = wcd->wcd938x;
+   struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+   int path = e->shift_l;
+
+   wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0];
+
+   return 0;
+}
+
+static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   struct wcd938x_priv *wcd938x = wcd->wcd938x;
+
+   ucontrol->value.integer.value[0] = wcd938x->hph_mode;
+
+   return 0;
+}
+
+static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   struct wcd938x_priv *wcd938x = wcd->wcd938x;
+
+   wcd938x->hph_mode = ucontrol->value.enumerated.item[0];
+
+   return 0;
+}
+
+static int wcd938x_ear_pa_put_gain(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
+   struct wcd938x_sdw_priv *wcd = snd_soc_component_get_drvdata(component);
+   struct wcd938x_priv *wcd938x = wcd->wcd938x;
+
+   if (wcd938x->comp1_enable)