summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/wcd937x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wcd937x.c')
-rw-r--r--sound/soc/codecs/wcd937x.c102
1 files changed, 66 insertions, 36 deletions
diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c
index c9d5e67bf66e..3b0a8cc314e0 100644
--- a/sound/soc/codecs/wcd937x.c
+++ b/sound/soc/codecs/wcd937x.c
@@ -24,10 +24,8 @@
#include "wcd-mbhc-v2.h"
#include "wcd937x.h"
-enum {
- CHIPID_WCD9370 = 0,
- CHIPID_WCD9375 = 5,
-};
+#define CHIPID_WCD9370 0x0
+#define CHIPID_WCD9375 0x5
/* Z value defined in milliohm */
#define WCD937X_ZDET_VAL_32 (32000)
@@ -88,10 +86,7 @@ struct wcd937x_priv {
struct wcd_mbhc_intr intr_ids;
struct wcd_clsh_ctrl *clsh_info;
struct irq_domain *virq;
- struct regmap_irq_chip *wcd_regmap_irq_chip;
struct regmap_irq_chip_data *irq_chip;
- struct regulator_bulk_data supplies[WCD937X_MAX_BULK_SUPPLY];
- struct regulator *buck_supply;
struct snd_soc_jack *jack;
unsigned long status_mask;
s32 micb_ref[WCD937X_MAX_MICBIAS];
@@ -114,6 +109,10 @@ struct wcd937x_priv {
atomic_t ana_clk_count;
};
+static const char * const wcd937x_supplies[] = {
+ "vdd-rxtx", "vdd-px", "vdd-mic-bias", "vdd-buck",
+};
+
static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
@@ -1197,13 +1196,21 @@ static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch
const struct wcd937x_sdw_ch_info *ch_info = &wcd->ch_info[ch_id];
u8 port_num = ch_info->port_num;
u8 ch_mask = ch_info->ch_mask;
+ u8 mstr_port_num, mstr_ch_mask;
+ struct sdw_slave *sdev = wcd->sdev;
port_config->num = port_num;
- if (enable)
+ mstr_port_num = sdev->m_port_map[port_num];
+ mstr_ch_mask = ch_info->master_ch_mask;
+
+ if (enable) {
port_config->ch_mask |= ch_mask;
- else
+ wcd->master_channel_map[mstr_port_num] |= mstr_ch_mask;
+ } else {
port_config->ch_mask &= ~ch_mask;
+ wcd->master_channel_map[mstr_port_num] &= ~mstr_ch_mask;
+ }
return 0;
}
@@ -2472,7 +2479,7 @@ static const struct irq_domain_ops wcd_domain_ops = {
static int wcd937x_irq_init(struct wcd937x_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;
@@ -2563,6 +2570,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
ARRAY_SIZE(wcd9375_dapm_widgets));
if (ret < 0) {
dev_err(component->dev, "Failed to add snd_ctls\n");
+ wcd_clsh_ctrl_free(wcd937x->clsh_info);
return ret;
}
@@ -2570,6 +2578,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
ARRAY_SIZE(wcd9375_audio_map));
if (ret < 0) {
dev_err(component->dev, "Failed to add routes\n");
+ wcd_clsh_ctrl_free(wcd937x->clsh_info);
return ret;
}
}
@@ -2646,7 +2655,7 @@ static void wcd937x_dt_parse_micbias_info(struct device *dev, struct wcd937x_pri
dev_warn(dev, "Micbias3 DT property not found\n");
}
-static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component, bool active)
+static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component)
{
int value;
struct wcd937x_priv *wcd937x;
@@ -2689,10 +2698,51 @@ static int wcd937x_codec_set_sdw_stream(struct snd_soc_dai *dai,
return 0;
}
+static int wcd937x_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)
+{
+ struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev);
+ struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id];
+ int i;
+
+ switch (dai->id) {
+ case AIF1_PB:
+ if (!rx_slot || !rx_num) {
+ dev_err(dai->dev, "Invalid rx_slot %p or rx_num %p\n",
+ rx_slot, rx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ rx_slot[i] = wcd->master_channel_map[i];
+
+ *rx_num = i;
+ break;
+ case AIF1_CAP:
+ if (!tx_slot || !tx_num) {
+ dev_err(dai->dev, "Invalid tx_slot %p or tx_num %p\n",
+ tx_slot, tx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ tx_slot[i] = wcd->master_channel_map[i];
+
+ *tx_num = i;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops wcd937x_sdw_dai_ops = {
.hw_params = wcd937x_codec_hw_params,
.hw_free = wcd937x_codec_free,
.set_stream = wcd937x_codec_set_sdw_stream,
+ .get_channel_map = wcd937x_get_channel_map,
};
static struct snd_soc_dai_driver wcd937x_dais[] = {
@@ -2884,20 +2934,10 @@ static int wcd937x_probe(struct platform_device *pdev)
cfg = &wcd937x->mbhc_cfg;
cfg->swap_gnd_mic = wcd937x_swap_gnd_mic;
- wcd937x->supplies[0].supply = "vdd-rxtx";
- wcd937x->supplies[1].supply = "vdd-px";
- wcd937x->supplies[2].supply = "vdd-mic-bias";
- wcd937x->supplies[3].supply = "vdd-buck";
-
- ret = devm_regulator_bulk_get(dev, WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd937x_supplies),
+ wcd937x_supplies);
if (ret)
- return dev_err_probe(dev, ret, "Failed to get supplies\n");
-
- ret = regulator_bulk_enable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
- if (ret) {
- regulator_bulk_free(WCD937X_MAX_BULK_SUPPLY, wcd937x->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");
wcd937x_dt_parse_micbias_info(dev, wcd937x);
@@ -2914,13 +2954,13 @@ static int wcd937x_probe(struct platform_device *pdev)
ret = wcd937x_add_slave_components(wcd937x, dev, &match);
if (ret)
- goto err_disable_regulators;
+ return ret;
wcd937x_reset(wcd937x);
ret = component_master_add_with_match(dev, &wcd937x_comp_ops, match);
if (ret)
- goto err_disable_regulators;
+ return ret;
pm_runtime_set_autosuspend_delay(dev, 1000);
pm_runtime_use_autosuspend(dev);
@@ -2930,27 +2970,17 @@ static int wcd937x_probe(struct platform_device *pdev)
pm_runtime_idle(dev);
return 0;
-
-err_disable_regulators:
- regulator_bulk_disable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
- regulator_bulk_free(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
-
- return ret;
}
static void wcd937x_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);
component_master_del(&pdev->dev, &wcd937x_comp_ops);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_dont_use_autosuspend(dev);
-
- regulator_bulk_disable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
- regulator_bulk_free(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
}
#if defined(CONFIG_OF)