summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/wcd9335.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wcd9335.c')
-rw-r--r--sound/soc/codecs/wcd9335.c393
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:*");