diff options
Diffstat (limited to 'sound/soc/codecs/wcd938x.c')
| -rw-r--r-- | sound/soc/codecs/wcd938x.c | 322 |
1 files changed, 113 insertions, 209 deletions
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 6021aa5a5689..f5b7de2bc896 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -11,7 +11,6 @@ #include <linux/pm_runtime.h> #include <linux/component.h> #include <sound/tlv.h> -#include <linux/of_gpio.h> #include <linux/of.h> #include <sound/jack.h> #include <sound/pcm.h> @@ -19,17 +18,20 @@ #include <linux/regmap.h> #include <sound/soc.h> #include <sound/soc-dapm.h> +#include <linux/mux/consumer.h> #include <linux/regulator/consumer.h> #include "wcd-clsh-v2.h" +#include "wcd-common.h" #include "wcd-mbhc-v2.h" #include "wcd938x.h" +#define CHIPID_WCD9380 0x0 +#define CHIPID_WCD9385 0x5 + #define WCD938X_MAX_MICBIAS (4) -#define WCD938X_MAX_SUPPLY (4) #define WCD938X_MBHC_MAX_BUTTONS (8) #define TX_ADC_MAX (4) -#define WCD938X_TX_MAX_SWR_PORTS (5) #define WCD938X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ @@ -39,8 +41,6 @@ SNDRV_PCM_RATE_176400) #define WCD938X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE) -/* Convert from vout ctl to micbias voltage in mV */ -#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) #define SWR_CLK_RATE_0P6MHZ (600000) #define SWR_CLK_RATE_1P2MHZ (1200000) #define SWR_CLK_RATE_2P4MHZ (2400000) @@ -48,8 +48,6 @@ #define SWR_CLK_RATE_9P6MHZ (9600000) #define SWR_CLK_RATE_11P2896MHZ (1128960) -#define WCD938X_DRV_NAME "wcd938x_codec" -#define WCD938X_VERSION_1_0 (1) #define EAR_RX_PATH_AUX (1) #define ADC_MODE_VAL_HIFI 0x01 @@ -72,34 +70,11 @@ /* Z value compared in milliOhm */ #define WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) #define WCD938X_MBHC_ZDET_CONST (86 * 16384) -#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, -}; - -enum { - TX_HDR12 = 0, - TX_HDR34, - TX_HDR_MAX, -}; - -enum { - WCD_RX1, - WCD_RX2, - WCD_RX3 -}; + SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, snd_soc_get_volsw, \ + wcd938x_ear_pa_put_gain, tlv_array) enum { /* INTR_CTRL_INT_MASK_0 */ @@ -181,10 +156,9 @@ struct wcd938x_priv { struct wcd_mbhc_config mbhc_cfg; struct wcd_mbhc_intr intr_ids; struct wcd_clsh_ctrl *clsh_info; + struct wcd_common common; struct irq_domain *virq; - struct regmap_irq_chip *wcd_regmap_irq_chip; struct regmap_irq_chip_data *irq_chip; - struct regulator_bulk_data supplies[WCD938X_MAX_SUPPLY]; struct snd_soc_jack *jack; unsigned long status_mask; s32 micb_ref[WCD938X_MAX_MICBIAS]; @@ -193,20 +167,21 @@ struct wcd938x_priv { u32 tx_mode[TX_ADC_MAX]; int flyback_cur_det_disable; int ear_rx_path; - int variant; - int reset_gpio; + struct gpio_desc *reset_gpio; struct gpio_desc *us_euro_gpio; - u32 micb1_mv; - u32 micb2_mv; - u32 micb3_mv; - u32 micb4_mv; + struct mux_control *us_euro_mux; + unsigned int mux_state; int hphr_pdm_wd_int; int hphl_pdm_wd_int; int aux_pdm_wd_int; bool comp1_enable; bool comp2_enable; bool ldoh; - bool bcs_dis; + bool mux_setup_done; +}; + +static const char * const wcd938x_supplies[] = { + "vdd-rxtx", "vdd-io", "vdd-buck", "vdd-mic-bias", }; static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); @@ -222,7 +197,7 @@ struct wcd938x_mbhc_zdet_param { u16 btn7; }; -static struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = { +static const struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = { WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD938X_ANA_MBHC_MECH, 0x80), WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD938X_ANA_MBHC_MECH, 0x40), WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD938X_ANA_MBHC_MECH, 0x20), @@ -296,7 +271,7 @@ static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = { REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08), }; -static struct regmap_irq_chip wcd938x_regmap_irq_chip = { +static const struct regmap_irq_chip wcd938x_regmap_irq_chip = { .name = "wcd938x", .irqs = wcd938x_irqs, .num_irqs = ARRAY_SIZE(wcd938x_irqs), @@ -419,7 +394,7 @@ static int wcd938x_io_init(struct wcd938x_priv *wcd938x) } -static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info, +static int wcd938x_sdw_connect_port(const struct wcd_sdw_ch_info *ch_info, struct sdw_port_config *port_config, u8 enable) { @@ -1117,8 +1092,7 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, int bank; int rate; - bank = (wcd938x_swr_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev)) ? 0 : 1; - bank = bank ? 0 : 1; + bank = sdw_slave_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -1505,7 +1479,7 @@ static int wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, 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 snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int path = e->shift_l; @@ -1518,7 +1492,7 @@ static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, 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 snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int path = e->shift_l; @@ -1534,7 +1508,7 @@ static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, 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 snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = wcd938x->hph_mode; @@ -1545,7 +1519,7 @@ static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, 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 snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0]) @@ -1559,7 +1533,7 @@ static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, 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 snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); if (wcd938x->comp1_enable) { @@ -1578,7 +1552,7 @@ static int wcd938x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); struct soc_mixer_control *mc; bool hphr; @@ -1597,7 +1571,7 @@ static int wcd938x_get_compander(struct snd_kcontrol *kcontrol, static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); struct wcd938x_sdw_priv *wcd; int value = ucontrol->value.integer.value[0]; @@ -1628,7 +1602,7 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wcd938x->ldoh; @@ -1639,7 +1613,7 @@ static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol, static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); if (wcd938x->ldoh == ucontrol->value.integer.value[0]) @@ -1650,31 +1624,6 @@ static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol, return 1; } -static int wcd938x_bcs_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - - ucontrol->value.integer.value[0] = wcd938x->bcs_dis; - - return 0; -} - -static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - - if (wcd938x->bcs_dis == ucontrol->value.integer.value[0]) - return 0; - - wcd938x->bcs_dis = ucontrol->value.integer.value[0]; - - return 1; -} - static const char * const tx_mode_mux_text_wcd9380[] = { "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", }; @@ -1894,7 +1843,7 @@ static const struct snd_kcontrol_new wcd9385_snd_controls[] = { static int wcd938x_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp); struct wcd938x_sdw_priv *wcd; struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; @@ -1913,7 +1862,7 @@ static int wcd938x_get_swr_port(struct snd_kcontrol *kcontrol, static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp); struct wcd938x_sdw_priv *wcd; struct soc_mixer_control *mixer = @@ -1982,7 +1931,7 @@ static bool wcd938x_mbhc_micb_en_status(struct snd_soc_component *component, int if (micb_num == MIC_BIAS_2) { val = snd_soc_component_read_field(component, WCD938X_ANA_MICB2, - WCD938X_ANA_MICB2_ENABLE_MASK); + WCD938X_MICB_EN_MASK); if (val == WCD938X_MICB_ENABLE) return true; } @@ -2023,15 +1972,6 @@ static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component, } } -static int wcd938x_get_micb_vout_ctl_val(u32 micb_mv) -{ - /* min micbias voltage is 1V and maximum is 2.85V */ - if (micb_mv < 1000 || micb_mv > 2850) - return -EINVAL; - - return (micb_mv - 1000) / 50; -} - static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num) { @@ -2068,7 +2008,7 @@ static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, cur_vout_ctl = snd_soc_component_read_field(component, micb_reg, WCD938X_MICB_VOUT_MASK); - req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt); + req_vout_ctl = wcd_get_micb_vout_ctl_val(component->dev, req_volt); if (req_vout_ctl < 0) { ret = -EINVAL; goto exit; @@ -2116,10 +2056,10 @@ static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *compon * voltage needed to detect threshold microphone, then do * not change the micbias, just return. */ - if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + if (wcd938x->common.micb_mv[2] >= WCD_MBHC_THR_HS_MICB_MV) return 0; - micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv; + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->common.micb_mv[2]; return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); } @@ -2566,7 +2506,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd938x->wcd_mbhc); @@ -2580,8 +2520,7 @@ static int wcd938x_hph_impedance_get(struct snd_kcontrol *kcontrol, uint32_t zl, zr; bool hphr; struct soc_mixer_control *mc; - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); mc = (struct soc_mixer_control *)(kcontrol->private_value); @@ -2695,8 +2634,6 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { wcd938x_get_swr_port, wcd938x_set_swr_port), SOC_SINGLE_EXT("LDOH Enable Switch", SND_SOC_NOPM, 0, 1, 0, wcd938x_ldoh_get, wcd938x_ldoh_put), - SOC_SINGLE_EXT("ADC2_BCS Disable Switch", SND_SOC_NOPM, 0, 1, 0, - wcd938x_bcs_get, wcd938x_bcs_put), SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, analog_gain), SOC_SINGLE_TLV("ADC2 Volume", WCD938X_ANA_TX_CH2, 0, 20, 0, analog_gain), @@ -3026,28 +2963,16 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"EAR", NULL, "EAR PGA"}, }; -static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x) +static void wcd938x_set_micbias_data(struct device *dev, struct wcd938x_priv *wcd938x) { - int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; - - /* set micbias voltage */ - vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv); - vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv); - vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv); - vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv); - if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0) - return -EINVAL; - regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1, - WCD938X_MICB_VOUT_MASK, vout_ctl_1); + WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[0]); regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2, - WCD938X_MICB_VOUT_MASK, vout_ctl_2); + WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[1]); regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3, - WCD938X_MICB_VOUT_MASK, vout_ctl_3); + WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[2]); regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4, - WCD938X_MICB_VOUT_MASK, vout_ctl_4); - - return 0; + WCD938X_MICB_VOUT_MASK, wcd938x->common.micb_vout[3]); } static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data) @@ -3055,7 +2980,7 @@ static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data) return IRQ_HANDLED; } -static struct irq_chip wcd_irq_chip = { +static const struct irq_chip wcd_irq_chip = { .name = "WCD938x", }; @@ -3076,7 +3001,7 @@ static const struct irq_domain_ops wcd_domain_ops = { static int wcd938x_irq_init(struct wcd938x_priv *wcd, struct device *dev) { - wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL); + wcd->virq = irq_domain_create_linear(NULL, 1, &wcd_domain_ops, NULL); if (!(wcd->virq)) { dev_err(dev, "%s: Failed to add IRQ domain\n", __func__); return -EINVAL; @@ -3094,6 +3019,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev; struct device *dev = component->dev; unsigned long time_left; + unsigned int variant; int ret, i; time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete, @@ -3109,9 +3035,9 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) if (ret < 0) return ret; - wcd938x->variant = snd_soc_component_read_field(component, - WCD938X_DIGITAL_EFUSE_REG_0, - WCD938X_ID_MASK); + variant = snd_soc_component_read_field(component, + WCD938X_DIGITAL_EFUSE_REG_0, + WCD938X_ID_MASK); wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X); if (IS_ERR(wcd938x->clsh_info)) { @@ -3165,24 +3091,24 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) disable_irq_nosync(wcd938x->hphl_pdm_wd_int); disable_irq_nosync(wcd938x->aux_pdm_wd_int); - switch (wcd938x->variant) { - case WCD9380: + switch (variant) { + case CHIPID_WCD9380: ret = snd_soc_add_component_controls(component, wcd9380_snd_controls, ARRAY_SIZE(wcd9380_snd_controls)); if (ret < 0) { dev_err(component->dev, "%s: Failed to add snd ctrls for variant: %d\n", - __func__, wcd938x->variant); + __func__, variant); goto err_free_aux_pdm_wd_int; } break; - case WCD9385: + case CHIPID_WCD9385: ret = snd_soc_add_component_controls(component, wcd9385_snd_controls, ARRAY_SIZE(wcd9385_snd_controls)); if (ret < 0) { dev_err(component->dev, "%s: Failed to add snd ctrls for variant: %d\n", - __func__, wcd938x->variant); + __func__, variant); goto err_free_aux_pdm_wd_int; } break; @@ -3250,48 +3176,28 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd938x = { .endianness = 1, }; -static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd) -{ - struct device_node *np = dev->of_node; - u32 prop_val = 0; - int rc = 0; - - rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val); - if (!rc) - wcd->micb1_mv = prop_val/1000; - else - dev_info(dev, "%s: Micbias1 DT property not found\n", __func__); - - rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val); - if (!rc) - wcd->micb2_mv = prop_val/1000; - else - dev_info(dev, "%s: Micbias2 DT property not found\n", __func__); - - rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val); - if (!rc) - wcd->micb3_mv = prop_val/1000; - else - dev_info(dev, "%s: Micbias3 DT property not found\n", __func__); - - rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val); - if (!rc) - wcd->micb4_mv = prop_val/1000; - else - dev_info(dev, "%s: Micbias4 DT property not found\n", __func__); -} - -static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component, bool active) +static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component) { - int value; - - struct wcd938x_priv *wcd938x; + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + struct device *dev = component->dev; + int ret; - wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->us_euro_mux) { + if (wcd938x->mux_setup_done) + mux_control_deselect(wcd938x->us_euro_mux); - value = gpiod_get_value(wcd938x->us_euro_gpio); + ret = mux_control_try_select(wcd938x->us_euro_mux, !wcd938x->mux_state); + if (ret) { + dev_err(dev, "Error (%d) Unable to select us/euro mux state\n", ret); + wcd938x->mux_setup_done = false; + return false; + } + wcd938x->mux_setup_done = true; + } else { + gpiod_set_value(wcd938x->us_euro_gpio, !wcd938x->mux_state); + } - gpiod_set_value(wcd938x->us_euro_gpio, !value); + wcd938x->mux_state = !wcd938x->mux_state; return true; } @@ -3302,41 +3208,47 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg; int ret; - wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0); - if (wcd938x->reset_gpio < 0) - return dev_err_probe(dev, wcd938x->reset_gpio, + wcd938x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(wcd938x->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(wcd938x->reset_gpio), "Failed to get reset gpio\n"); - wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", - GPIOD_OUT_LOW); - if (IS_ERR(wcd938x->us_euro_gpio)) - return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio), - "us-euro swap Control GPIO not found\n"); + if (of_property_present(dev->of_node, "mux-controls")) { + wcd938x->us_euro_mux = devm_mux_control_get(dev, NULL); + if (IS_ERR(wcd938x->us_euro_mux)) { + ret = PTR_ERR(wcd938x->us_euro_mux); + return dev_err_probe(dev, ret, "failed to get mux control\n"); + } - cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; + ret = mux_control_try_select(wcd938x->us_euro_mux, wcd938x->mux_state); + if (ret) { + dev_err(dev, "Error (%d) Unable to select us/euro mux state\n", ret); + return ret; + } + wcd938x->mux_setup_done = true; + } else { + wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", GPIOD_OUT_LOW); + if (IS_ERR(wcd938x->us_euro_gpio)) + return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio), + "us-euro swap Control GPIO not found\n"); + } - wcd938x->supplies[0].supply = "vdd-rxtx"; - wcd938x->supplies[1].supply = "vdd-io"; - wcd938x->supplies[2].supply = "vdd-buck"; - wcd938x->supplies[3].supply = "vdd-mic-bias"; + cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; - ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd938x_supplies), + wcd938x_supplies); if (ret) - return dev_err_probe(dev, ret, "Failed to get supplies\n"); - - ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - if (ret) { - regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); - return dev_err_probe(dev, ret, "Failed to enable supplies\n"); - } + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); - wcd938x_dt_parse_micbias_info(dev, wcd938x); + ret = wcd_dt_parse_micbias_info(&wcd938x->common); + if (ret) + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); cfg->mbhc_micbias = MIC_BIAS_2; cfg->anc_micbias = MIC_BIAS_2; cfg->v_hs_max = WCD_MBHC_HS_V_MAX; cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS; - cfg->micb_mv = wcd938x->micb2_mv; + cfg->micb_mv = wcd938x->common.micb_mv[2]; cfg->linein_th = 5000; cfg->hs_thr = 1700; cfg->hph_thr = 50; @@ -3348,10 +3260,10 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device static int wcd938x_reset(struct wcd938x_priv *wcd938x) { - gpio_direction_output(wcd938x->reset_gpio, 0); + gpiod_set_value(wcd938x->reset_gpio, 1); /* 20us sleep required after pulling the reset gpio to LOW */ usleep_range(20, 30); - gpio_set_value(wcd938x->reset_gpio, 1); + gpiod_set_value(wcd938x->reset_gpio, 0); /* 20us sleep required after pulling the reset gpio to HIGH */ usleep_range(20, 30); @@ -3434,7 +3346,7 @@ static int wcd938x_bind(struct device *dev) return ret; } - wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode); + wcd938x->rxdev = of_sdw_find_device_by_node(wcd938x->rxnode); if (!wcd938x->rxdev) { dev_err(dev, "could not find slave with matching of node\n"); ret = -EINVAL; @@ -3443,7 +3355,7 @@ static int wcd938x_bind(struct device *dev) wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev); wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x; - wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode); + wcd938x->txdev = of_sdw_find_device_by_node(wcd938x->txnode); if (!wcd938x->txdev) { dev_err(dev, "could not find txslave with matching of node\n"); ret = -EINVAL; @@ -3476,7 +3388,7 @@ static int wcd938x_bind(struct device *dev) goto err_remove_tx_link; } - wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL); + wcd938x->regmap = wcd938x->sdw_priv[AIF1_CAP]->regmap; if (!wcd938x->regmap) { dev_err(dev, "could not get TX device regmap\n"); ret = -EINVAL; @@ -3492,11 +3404,7 @@ static int wcd938x_bind(struct device *dev) wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq; wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq; - ret = wcd938x_set_micbias_data(wcd938x); - if (ret < 0) { - dev_err(dev, "%s: bad micbias pdata\n", __func__); - goto err_remove_rx_link; - } + wcd938x_set_micbias_data(dev, wcd938x); ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, wcd938x_dais, ARRAY_SIZE(wcd938x_dais)); @@ -3585,6 +3493,8 @@ static int wcd938x_probe(struct platform_device *pdev) dev_set_drvdata(dev, wcd938x); mutex_init(&wcd938x->micb_lock); + wcd938x->common.dev = dev; + wcd938x->common.max_bias = 4; ret = wcd938x_populate_dt_data(wcd938x, dev); if (ret) @@ -3592,13 +3502,13 @@ static int wcd938x_probe(struct platform_device *pdev) ret = wcd938x_add_slave_components(wcd938x, dev, &match); if (ret) - goto err_disable_regulators; + return ret; wcd938x_reset(wcd938x); ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match); if (ret) - goto err_disable_regulators; + return ret; pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_use_autosuspend(dev); @@ -3608,12 +3518,6 @@ static int wcd938x_probe(struct platform_device *pdev) pm_runtime_idle(dev); return 0; - -err_disable_regulators: - regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); - - return ret; } static void wcd938x_remove(struct platform_device *pdev) @@ -3627,8 +3531,8 @@ static void wcd938x_remove(struct platform_device *pdev) pm_runtime_set_suspended(dev); pm_runtime_dont_use_autosuspend(dev); - regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); + if (wcd938x->us_euro_mux && wcd938x->mux_setup_done) + mux_control_deselect(wcd938x->us_euro_mux); } #if defined(CONFIG_OF) @@ -3642,7 +3546,7 @@ MODULE_DEVICE_TABLE(of, wcd938x_dt_match); static struct platform_driver wcd938x_codec_driver = { .probe = wcd938x_probe, - .remove_new = wcd938x_remove, + .remove = wcd938x_remove, .driver = { .name = "wcd938x_codec", .of_match_table = of_match_ptr(wcd938x_dt_match), |
