diff options
Diffstat (limited to 'sound/soc/codecs/wcd9335.c')
| -rw-r--r-- | sound/soc/codecs/wcd9335.c | 393 |
1 files changed, 152 insertions, 241 deletions
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 1e60db4056ad..640e43ee1975 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -5,6 +5,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/wait.h> #include <linux/bitops.h> @@ -16,7 +17,7 @@ #include <sound/soc.h> #include <sound/pcm_params.h> #include <sound/soc-dapm.h> -#include <linux/of_gpio.h> +#include <linux/gpio/consumer.h> #include <linux/of.h> #include <linux/of_irq.h> #include <sound/tlv.h> @@ -24,6 +25,8 @@ #include "wcd9335.h" #include "wcd-clsh-v2.h" +#include <dt-bindings/sound/qcom,wcd9335.h> + #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) @@ -156,6 +159,8 @@ {"AMIC MUX" #id, "ADC5", "ADC5"}, \ {"AMIC MUX" #id, "ADC6", "ADC6"} +#define NUM_CODEC_DAIS 7 + enum { WCD9335_RX0 = 0, WCD9335_RX1, @@ -204,17 +209,6 @@ enum wcd9335_sido_voltage { }; enum { - AIF1_PB = 0, - AIF1_CAP, - AIF2_PB, - AIF2_CAP, - AIF3_PB, - AIF3_CAP, - AIF4_PB, - NUM_CODEC_DAIS, -}; - -enum { COMPANDER_1, /* HPH_L */ COMPANDER_2, /* HPH_R */ COMPANDER_3, /* LO1_DIFF */ @@ -306,7 +300,6 @@ struct wcd9335_codec { struct clk *mclk; struct clk *native_clk; u32 mclk_rate; - u8 version; struct slim_device *slim; struct slim_device *slim_ifc_dev; @@ -319,7 +312,6 @@ struct wcd9335_codec { u32 num_rx_port; u32 num_tx_port; - int sido_input_src; enum wcd9335_sido_voltage sido_voltage; struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS]; @@ -338,11 +330,10 @@ struct wcd9335_codec { int comp_enabled[COMPANDER_MAX]; int intr1; - int reset_gpio; - struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; + struct gpio_desc *reset_gpio; unsigned int rx_port_value[WCD9335_RX_MAX]; - unsigned int tx_port_value; + unsigned int tx_port_value[WCD9335_TX_MAX]; int hph_l_gain; int hph_r_gain; u32 rx_bias_count; @@ -354,10 +345,6 @@ struct wcd9335_codec { int dmic_0_1_clk_cnt; int dmic_2_3_clk_cnt; int dmic_4_5_clk_cnt; - int dmic_sample_rate; - int mad_dmic_sample_rate; - - int native_clk_users; }; struct wcd9335_irq { @@ -366,6 +353,10 @@ struct wcd9335_irq { char *name; }; +static const char * const wcd9335_supplies[] = { + "vdd-buck", "vdd-buck-sido", "vdd-tx", "vdd-rx", "vdd-io", +}; + static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = { WCD9335_SLIM_TX_CH(0), WCD9335_SLIM_TX_CH(1), @@ -406,13 +397,13 @@ struct interp_sample_rate { int rate_val; }; -static struct interp_sample_rate int_mix_rate_val[] = { +static const struct interp_sample_rate int_mix_rate_val[] = { {48000, 0x4}, /* 48K */ {96000, 0x5}, /* 96K */ {192000, 0x6}, /* 192K */ }; -static struct interp_sample_rate int_prim_rate_val[] = { +static const struct interp_sample_rate int_prim_rate_val[] = { {8000, 0x0}, /* 8K */ {16000, 0x1}, /* 16K */ {24000, -EINVAL},/* 24K */ @@ -1269,8 +1260,9 @@ static const struct snd_kcontrol_new sb_tx8_mux = static int slim_rx_mux_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); u32 port_id = w->shift; ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id]; @@ -1281,17 +1273,24 @@ static int slim_rx_mux_get(struct snd_kcontrol *kc, static int slim_rx_mux_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); struct soc_enum *e = (struct soc_enum *)kc->private_value; struct snd_soc_dapm_update *update = NULL; u32 port_id = w->shift; + if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) + return 0; + wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + /* Remove channel from any list it's in before adding it to a new one */ + list_del_init(&wcd->rx_chs[port_id].list); + switch (wcd->rx_port_value[port_id]) { case 0: - list_del_init(&wcd->rx_chs[port_id].list); + /* Channel already removed from lists. Nothing to do here */ break; case 1: list_add_tail(&wcd->rx_chs[port_id].list, @@ -1326,10 +1325,16 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kc); + struct device *dev = snd_soc_dapm_to_dev(dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kc); + struct soc_mixer_control *mixer = + (struct soc_mixer_control *)kc->private_value; + int dai_id = widget->shift; + int port_id = mixer->shift; - ucontrol->value.integer.value[0] = wcd->tx_port_value; + ucontrol->value.integer.value[0] = wcd->tx_port_value[port_id] == dai_id; return 0; } @@ -1338,8 +1343,9 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(widget->dapm->dev); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(widget->dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); struct snd_soc_dapm_update *update = NULL; struct soc_mixer_control *mixer = (struct soc_mixer_control *)kc->private_value; @@ -1352,12 +1358,12 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc, case AIF2_CAP: case AIF3_CAP: /* only add to the list if value not set */ - if (enable && !(wcd->tx_port_value & BIT(port_id))) { - wcd->tx_port_value |= BIT(port_id); + if (enable && wcd->tx_port_value[port_id] != dai_id) { + wcd->tx_port_value[port_id] = dai_id; list_add_tail(&wcd->tx_chs[port_id].list, &wcd->dai[dai_id].slim_ch_list); - } else if (!enable && (wcd->tx_port_value & BIT(port_id))) { - wcd->tx_port_value &= ~BIT(port_id); + } else if (!enable && wcd->tx_port_value[port_id] == dai_id) { + wcd->tx_port_value[port_id] = -1; list_del_init(&wcd->tx_chs[port_id].list); } break; @@ -1472,7 +1478,7 @@ static const struct snd_kcontrol_new aif3_cap_mixer[] = { static int wcd9335_put_dec_enum(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kc); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct soc_enum *e = (struct soc_enum *)kc->private_value; unsigned int val, reg, sel; @@ -1527,7 +1533,7 @@ static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc, struct snd_soc_component *component; int reg, val; - component = snd_soc_dapm_kcontrol_component(kc); + component = snd_soc_dapm_kcontrol_to_component(kc); val = ucontrol->value.enumerated.item[0]; if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0) @@ -1807,11 +1813,11 @@ static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai, tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0; shift = (tx_port << 1); shift_val = 0x03; - } else if ((tx_port >= 4) && (tx_port < 8)) { + } else if (tx_port < 8) { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1; shift = ((tx_port - 4) << 1); shift_val = 0x03; - } else if ((tx_port >= 8) && (tx_port < 11)) { + } else if (tx_port < 11) { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2; shift = ((tx_port - 8) << 1); shift_val = 0x03; @@ -1819,12 +1825,10 @@ static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai, tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3; shift = 0; shift_val = 0x0F; - } else if (tx_port == 13) { + } else /* (tx_port == 13) */ { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3; shift = 4; shift_val = 0x03; - } else { - return -EINVAL; } tx_mux_sel = snd_soc_component_read(comp, tx_port_reg) & @@ -1972,8 +1976,8 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - slim_stream_unprepare(dai_data->sruntime); slim_stream_disable(dai_data->sruntime); + slim_stream_unprepare(dai_data->sruntime); break; default: break; @@ -1983,8 +1987,10 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd, } static int wcd9335_set_channel_map(struct snd_soc_dai *dai, - unsigned int tx_num, unsigned int *tx_slot, - unsigned int rx_num, unsigned int *rx_slot) + unsigned int tx_num, + const unsigned int *tx_slot, + unsigned int rx_num, + const unsigned int *rx_slot) { struct wcd9335_codec *wcd; int i; @@ -2012,7 +2018,7 @@ static int wcd9335_set_channel_map(struct snd_soc_dai *dai, return 0; } -static int wcd9335_get_channel_map(struct snd_soc_dai *dai, +static int wcd9335_get_channel_map(const struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { @@ -2175,7 +2181,7 @@ static int wcd9335_get_compander(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kc); + struct snd_soc_component *component = snd_kcontrol_chip(kc); int comp = ((struct soc_mixer_control *)kc->private_value)->shift; struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); @@ -2186,7 +2192,7 @@ static int wcd9335_get_compander(struct snd_kcontrol *kc, static int wcd9335_set_compander(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kc); + struct snd_soc_component *component = snd_kcontrol_chip(kc); struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); int comp = ((struct soc_mixer_control *) kc->private_value)->shift; int value = ucontrol->value.integer.value[0]; @@ -2225,7 +2231,7 @@ static int wcd9335_set_compander(struct snd_kcontrol *kc, static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kc); + struct snd_soc_component *component = snd_kcontrol_chip(kc); struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); ucontrol->value.enumerated.item[0] = wcd->hph_mode; @@ -2236,7 +2242,7 @@ static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc, static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kc); + struct snd_soc_component *component = snd_kcontrol_chip(kc); struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); u32 mode_val; @@ -2253,51 +2259,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, static const struct snd_kcontrol_new wcd9335_snd_controls[] = { /* -84dB min - 40dB max */ - SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", - WCD9335_CDC_RX0_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", - WCD9335_CDC_RX1_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", - WCD9335_CDC_RX2_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", - WCD9335_CDC_RX3_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", - WCD9335_CDC_RX4_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", - WCD9335_CDC_RX5_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", - WCD9335_CDC_RX6_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", - WCD9335_CDC_RX7_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", - WCD9335_CDC_RX8_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL, + -84, 40, digital_gain), SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), @@ -2726,25 +2723,23 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w, struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); unsigned int decimator; char *dec_adc_mux_name = NULL; - char *widget_name = NULL; - char *wname; + char *widget_name; int ret = 0, amic_n; u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; u16 tx_gain_ctl_reg; char *dec; u8 hpf_coff_freq; - widget_name = kmemdup_nul(w->name, 15, GFP_KERNEL); - if (!widget_name) + char *wname __free(kfree) = kmemdup_nul(w->name, 15, GFP_KERNEL); + if (!wname) return -ENOMEM; - wname = widget_name; + widget_name = wname; dec_adc_mux_name = strsep(&widget_name, " "); if (!dec_adc_mux_name) { dev_err(comp->dev, "%s: Invalid decimator = %s\n", __func__, w->name); - ret = -EINVAL; - goto out; + return -EINVAL; } dec_adc_mux_name = widget_name; @@ -2752,16 +2747,14 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w, if (!dec) { dev_err(comp->dev, "%s: decimator index not found\n", __func__); - ret = -EINVAL; - goto out; + return -EINVAL; } ret = kstrtouint(dec, 10, &decimator); if (ret < 0) { dev_err(comp->dev, "%s: Invalid decimator = %s\n", __func__, wname); - ret = -EINVAL; - goto out; + return -EINVAL; } tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator; @@ -2848,62 +2841,20 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x00); break; } -out: - kfree(wname); + return ret; } static u8 wcd9335_get_dmic_clk_val(struct snd_soc_component *component, - u32 mclk_rate, u32 dmic_clk_rate) + u32 mclk_rate) { - u32 div_factor; u8 dmic_ctl_val; - dev_err(component->dev, - "%s: mclk_rate = %d, dmic_sample_rate = %d\n", - __func__, mclk_rate, dmic_clk_rate); - - /* Default value to return in case of error */ if (mclk_rate == WCD9335_MCLK_CLK_9P6MHZ) dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2; else dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3; - if (dmic_clk_rate == 0) { - dev_err(component->dev, - "%s: dmic_sample_rate cannot be 0\n", - __func__); - goto done; - } - - div_factor = mclk_rate / dmic_clk_rate; - switch (div_factor) { - case 2: - dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2; - break; - case 3: - dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3; - break; - case 4: - dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4; - break; - case 6: - dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6; - break; - case 8: - dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8; - break; - case 16: - dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16; - break; - default: - dev_err(component->dev, - "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n", - __func__, div_factor, mclk_rate, dmic_clk_rate); - break; - } - -done: return dmic_ctl_val; } @@ -2957,11 +2908,7 @@ static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - dmic_rate_val = - wcd9335_get_dmic_clk_val(comp, - wcd->mclk_rate, - wcd->dmic_sample_rate); - + dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { snd_soc_component_update_bits(comp, dmic_clk_reg, @@ -2973,10 +2920,7 @@ static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: - dmic_rate_val = - wcd9335_get_dmic_clk_val(comp, - wcd->mclk_rate, - wcd->mad_dmic_sample_rate); + dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate); (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) { snd_soc_component_update_bits(comp, dmic_clk_reg, @@ -3042,7 +2986,6 @@ static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w, { struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); u16 gain_reg; - int offset_val = 0; int val = 0; switch (w->reg) { @@ -3082,7 +3025,6 @@ static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: val = snd_soc_component_read(comp, gain_reg); - val += offset_val; snd_soc_component_write(comp, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD: @@ -3303,33 +3245,32 @@ static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w, u16 gain_reg; u16 reg; int val; - int offset_val = 0; - if (!(strcmp(w->name, "RX INT0 INTERP"))) { + if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT0 INTERP"))) { reg = WCD9335_CDC_RX0_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT1 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT1 INTERP"))) { reg = WCD9335_CDC_RX1_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT2 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT2 INTERP"))) { reg = WCD9335_CDC_RX2_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT3 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT3 INTERP"))) { reg = WCD9335_CDC_RX3_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT4 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT4 INTERP"))) { reg = WCD9335_CDC_RX4_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT5 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT5 INTERP"))) { reg = WCD9335_CDC_RX5_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT6 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT6 INTERP"))) { reg = WCD9335_CDC_RX6_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT7 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT7 INTERP"))) { reg = WCD9335_CDC_RX7_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT8 INTERP"))) { + } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT8 INTERP"))) { reg = WCD9335_CDC_RX8_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL; } else { @@ -3346,7 +3287,6 @@ static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: wcd9335_config_compander(comp, w->shift, event); val = snd_soc_component_read(comp, gain_reg); - val += offset_val; snd_soc_component_write(comp, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD: @@ -4037,7 +3977,7 @@ static irqreturn_t wcd9335_slimbus_irq(int irq, void *data) return ret; } -static struct wcd9335_irq wcd9335_irqs[] = { +static const struct wcd9335_irq wcd9335_irqs[] = { { .irq = WCD9335_IRQ_SLIMBUS, .handler = wcd9335_slimbus_irq, @@ -4788,8 +4728,6 @@ static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = { static void wcd9335_enable_sido_buck(struct snd_soc_component *component) { - struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); - snd_soc_component_update_bits(component, WCD9335_ANA_RCO, WCD9335_ANA_RCO_BG_EN_MASK, WCD9335_ANA_RCO_BG_ENABLE); @@ -4803,7 +4741,6 @@ static void wcd9335_enable_sido_buck(struct snd_soc_component *component) WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT); /* 100us sleep needed after VREF settings */ usleep_range(100, 110); - wcd->sido_input_src = SIDO_SOURCE_RCO_BG; } static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp) @@ -4924,6 +4861,7 @@ static const struct snd_soc_component_driver wcd9335_component_drv = { .num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets), .dapm_routes = wcd9335_audio_map, .num_dapm_routes = ARRAY_SIZE(wcd9335_audio_map), + .endianness = 1, }; static int wcd9335_probe(struct wcd9335_codec *wcd) @@ -4933,7 +4871,6 @@ static int wcd9335_probe(struct wcd9335_codec *wcd) memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs)); memcpy(wcd->tx_chs, wcd9335_tx_chs, sizeof(wcd9335_tx_chs)); - wcd->sido_input_src = SIDO_SOURCE_INTERNAL; wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV; return devm_snd_soc_register_component(dev, &wcd9335_component_drv, @@ -4973,10 +4910,10 @@ static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg) } } -static struct regmap_config wcd9335_regmap_config = { +static const struct regmap_config wcd9335_regmap_config = { .reg_bits = 16, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .max_register = WCD9335_MAX_REGISTER, .can_multi_write = true, .ranges = wcd9335_ranges, @@ -4997,7 +4934,7 @@ static const struct regmap_range_cfg wcd9335_ifc_ranges[] = { }, }; -static struct regmap_config wcd9335_ifc_regmap_config = { +static const struct regmap_config wcd9335_ifc_regmap_config = { .reg_bits = 16, .val_bits = 8, .can_multi_write = true, @@ -5019,68 +4956,51 @@ static const struct regmap_irq wcd9335_codec_irqs[] = { }, }; +static const unsigned int wcd9335_config_regs[] = { + WCD9335_INTR_LEVEL0, +}; + static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { .name = "wcd9335_pin1_irq", .status_base = WCD9335_INTR_PIN1_STATUS0, .mask_base = WCD9335_INTR_PIN1_MASK0, .ack_base = WCD9335_INTR_PIN1_CLEAR0, - .type_base = WCD9335_INTR_LEVEL0, - .num_type_reg = 4, .num_regs = 4, .irqs = wcd9335_codec_irqs, .num_irqs = ARRAY_SIZE(wcd9335_codec_irqs), + .config_base = wcd9335_config_regs, + .num_config_bases = ARRAY_SIZE(wcd9335_config_regs), + .num_config_regs = 4, + .set_type_config = regmap_irq_set_type_config_simple, }; static int wcd9335_parse_dt(struct wcd9335_codec *wcd) { struct device *dev = wcd->dev; - struct device_node *np = dev->of_node; int ret; - wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); - if (wcd->reset_gpio < 0) { - dev_err(dev, "Reset GPIO missing from DT\n"); - return wcd->reset_gpio; - } + wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(wcd->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n"); wcd->mclk = devm_clk_get(dev, "mclk"); - if (IS_ERR(wcd->mclk)) { - dev_err(dev, "mclk not found\n"); - return PTR_ERR(wcd->mclk); - } + if (IS_ERR(wcd->mclk)) + return dev_err_probe(dev, PTR_ERR(wcd->mclk), "mclk not found\n"); wcd->native_clk = devm_clk_get(dev, "slimbus"); - if (IS_ERR(wcd->native_clk)) { - dev_err(dev, "slimbus clock not found\n"); - return PTR_ERR(wcd->native_clk); - } - - wcd->supplies[0].supply = "vdd-buck"; - wcd->supplies[1].supply = "vdd-buck-sido"; - wcd->supplies[2].supply = "vdd-tx"; - wcd->supplies[3].supply = "vdd-rx"; - wcd->supplies[4].supply = "vdd-io"; + if (IS_ERR(wcd->native_clk)) + return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n"); - ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies); - if (ret) { - dev_err(dev, "Failed to get supplies: err = %d\n", ret); - return ret; - } + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd9335_supplies), + wcd9335_supplies); + if (ret) + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); return 0; } static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) { - struct device *dev = wcd->dev; - int ret; - - ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies); - if (ret) { - dev_err(dev, "Failed to get supplies: err = %d\n", ret); - return ret; - } - /* * For WCD9335, it takes about 600us for the Vout_A and * Vout_D to be ready after BUCK_SIDO is powered up. @@ -5090,9 +5010,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) */ usleep_range(600, 650); - gpio_direction_output(wcd->reset_gpio, 0); + gpiod_set_value(wcd->reset_gpio, 1); msleep(20); - gpio_set_value(wcd->reset_gpio, 1); + gpiod_set_value(wcd->reset_gpio, 0); msleep(20); return 0; @@ -5113,7 +5033,6 @@ static int wcd9335_bring_up(struct wcd9335_codec *wcd) if (byte0 == 0x1) { dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n"); - wcd->version = WCD9335_VERSION_2_0; regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01); regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00); regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F); @@ -5140,20 +5059,17 @@ static int wcd9335_irq_init(struct wcd9335_codec *wcd) * INTR2 is a subset of first interrupt sources MAD, VBAT, and SVA */ wcd->intr1 = of_irq_get_byname(wcd->dev->of_node, "intr1"); - if (wcd->intr1 < 0) { - if (wcd->intr1 != -EPROBE_DEFER) - dev_err(wcd->dev, "Unable to configure IRQ\n"); - - return wcd->intr1; - } + if (wcd->intr1 < 0) + return dev_err_probe(wcd->dev, wcd->intr1, + "Unable to configure IRQ\n"); ret = devm_regmap_add_irq_chip(wcd->dev, wcd->regmap, wcd->intr1, IRQF_TRIGGER_HIGH, 0, &wcd9335_regmap_irq1_chip, &wcd->irq_data); if (ret) - dev_err(wcd->dev, "Failed to register IRQ chip: %d\n", ret); + return dev_err_probe(wcd->dev, ret, "Failed to register IRQ chip\n"); - return ret; + return 0; } static int wcd9335_slim_probe(struct slim_device *slim) @@ -5168,10 +5084,8 @@ static int wcd9335_slim_probe(struct slim_device *slim) wcd->dev = dev; ret = wcd9335_parse_dt(wcd); - if (ret) { - dev_err(dev, "Error parsing DT: %d\n", ret); + if (ret) return ret; - } ret = wcd9335_power_on_reset(wcd); if (ret) @@ -5209,17 +5123,15 @@ static int wcd9335_slim_status(struct slim_device *sdev, slim_get_logical_addr(wcd->slim_ifc_dev); wcd->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config); - if (IS_ERR(wcd->regmap)) { - dev_err(dev, "Failed to allocate slim register map\n"); - return PTR_ERR(wcd->regmap); - } + if (IS_ERR(wcd->regmap)) + return dev_err_probe(dev, PTR_ERR(wcd->regmap), + "Failed to allocate slim register map\n"); wcd->if_regmap = regmap_init_slimbus(wcd->slim_ifc_dev, &wcd9335_ifc_regmap_config); - if (IS_ERR(wcd->if_regmap)) { - dev_err(dev, "Failed to allocate ifc register map\n"); - return PTR_ERR(wcd->if_regmap); - } + if (IS_ERR(wcd->if_regmap)) + return dev_err_probe(dev, PTR_ERR(wcd->if_regmap), + "Failed to allocate ifc register map\n"); ret = wcd9335_bring_up(wcd); if (ret) { @@ -5254,4 +5166,3 @@ static struct slim_driver wcd9335_slim_driver = { module_slim_driver(wcd9335_slim_driver); MODULE_DESCRIPTION("WCD9335 slim driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("slim:217:1a0:*"); |
