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)