Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47aa5011 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: codecs: remove dmic device during dev err"

parents 5ae37e64 84bb791c
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _BOLERO_CDC_REGISTERS_H
@@ -25,6 +25,12 @@
#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL	(TX_START_OFFSET + 0x00CC)
#define BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL	(TX_START_OFFSET + 0x00D0)
#define BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL	(TX_START_OFFSET + 0x00D4)
#define BOLERO_CDC_TX_TOP_CSR_SWR_MIC2_CTL	(TX_START_OFFSET + 0x00C0)
#define BOLERO_CDC_TX_TOP_CSR_SWR_MIC3_CTL	(TX_START_OFFSET + 0x00C4)
#define BOLERO_CDC_TX_TOP_CSR_SWR_MIC4_CTL	(TX_START_OFFSET + 0x00C8)
#define BOLERO_CDC_TX_TOP_CSR_SWR_MIC5_CTL	(TX_START_OFFSET + 0x00CC)
#define BOLERO_CDC_TX_TOP_CSR_SWR_MIC0_CTL	(TX_START_OFFSET + 0x00D0)
#define BOLERO_CDC_TX_TOP_CSR_SWR_MIC1_CTL	(TX_START_OFFSET + 0x00D4)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0	(TX_START_OFFSET + 0x0100)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1	(TX_START_OFFSET + 0x0104)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0	(TX_START_OFFSET + 0x0108)
+37 −0
Original line number Diff line number Diff line
@@ -904,6 +904,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
	u16 hpf_gate_reg = 0;
	u16 tx_gain_ctl_reg = 0;
	u8 hpf_cut_off_freq = 0;
	u16 adc_mux_reg = 0;
	int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS;
	int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS;
	struct device *tx_dev = NULL;
@@ -925,6 +926,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
				TX_MACRO_TX_PATH_OFFSET * decimator;
	tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL +
				TX_MACRO_TX_PATH_OFFSET * decimator;
	adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
			TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
@@ -1008,6 +1011,32 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
					BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40,
					0x40);
		}
		if (tx_priv->version == BOLERO_VERSION_2_0) {
			if (snd_soc_component_read32(component, adc_mux_reg)
							& SWR_MIC) {
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_CTRL,
					0x01, 0x01);
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_MIC0_CTL,
					0x0E, 0x0C);
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_MIC1_CTL,
					0x0E, 0x0C);
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_MIC2_CTL,
					0x0E, 0x00);
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_MIC3_CTL,
					0x0E, 0x00);
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_MIC4_CTL,
					0x0E, 0x00);
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_MIC5_CTL,
					0x0E, 0x00);
			}
		}
		break;
	case SND_SOC_DAPM_PRE_PMD:
		hpf_cut_off_freq =
@@ -1036,6 +1065,14 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
		}
		cancel_delayed_work_sync(
				&tx_priv->tx_mute_dwork[decimator].dwork);

		if (tx_priv->version == BOLERO_VERSION_2_0) {
			if (snd_soc_component_read32(component, adc_mux_reg)
							& SWR_MIC)
				snd_soc_component_update_bits(component,
					BOLERO_CDC_TX_TOP_CSR_SWR_CTRL,
					0x01, 0x00);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
+190 −264
Original line number Diff line number Diff line
@@ -27,13 +27,25 @@
#include <asoc/msm-cdc-pinctrl.h>
#include <asoc/msm-cdc-supply.h>
#include <dt-bindings/sound/audio-codec-port-types.h>
#include "wcd938x/wcd938x.h"
#include "swr-dmic.h"

#define itoa(x)                   ('0' + x)
#define DAI_NAME_NUM_INDEX        11
#define AIF_NAME_NUM_INDEX        12
#define DEFAULT_CODEC_NAME        "swr_dmic_tx0"
#define DEFAULT_AIF_NAME          "SWR_DMIC_AIF0 Playback"
static int swr_master_channel_map[] = {
	ZERO,
	SWRM_TX1_CH1,
	SWRM_TX1_CH2,
	SWRM_TX1_CH3,
	SWRM_TX1_CH4,
	SWRM_TX2_CH1,
	SWRM_TX2_CH2,
	SWRM_TX2_CH3,
	SWRM_TX2_CH4,
	SWRM_TX3_CH1,
	SWRM_TX3_CH2,
	SWRM_TX3_CH3,
	SWRM_TX3_CH4,
	SWRM_PCM_IN,
};

/*
 * Private data Structure for swr-dmic. All parameters related to
@@ -44,12 +56,12 @@ struct swr_dmic_priv {
	struct swr_device *swr_slave;
	struct snd_soc_component *component;
	struct snd_soc_component_driver *driver;
	struct snd_soc_dai_driver *dai_driver;
	const char *supply_name;
	struct snd_soc_component *supply_component;
	u32 micb_num;
	struct device_node *wcd_handle;
	struct cdc_wcd_supply *cdc_supply;
	bool is_wcd_supply;
	int tx_mode;
	int is_en_supply;
	int port_type;
	u8 tx_master_port_map[SWR_DMIC_MAX_PORTS];
};

@@ -58,127 +70,34 @@ const char *codec_name_list[] = {
	"swr-dmic-02",
	"swr-dmic-03",
	"swr-dmic-04",
	"swr-dmic-05",
};

static int get_master_port(int val)
{
	int master_port = 0;

	switch(val) {
	case 0:
		master_port = SWRM_TX1_CH1;
		break;
	case 1:
		master_port = SWRM_TX1_CH2;
		break;
	case 2:
		master_port = SWRM_TX1_CH3;
		break;
	case 3:
		master_port = SWRM_TX1_CH4;
		break;
	case 4:
		master_port = SWRM_TX2_CH1;
		break;
	case 5:
		master_port = SWRM_TX2_CH2;
		break;
	case 6:
		master_port = SWRM_TX2_CH3;
		break;
	case 7:
		master_port = SWRM_TX2_CH4;
		break;
	case 8:
		master_port = SWRM_TX3_CH1;
		break;
	case 9:
		master_port = SWRM_TX3_CH2;
		break;
	case 10:
		master_port = SWRM_TX3_CH3;
		break;
	case 11:
		master_port = SWRM_TX3_CH4;
		break;
	case 12:
		master_port = SWRM_PCM_IN;
		break;
	default:
		master_port = SWRM_TX1_CH1;
		pr_debug("%s: undefined value, fall back to default master_port: %d\n",
			 __func__, master_port);
		break;
	}

	pr_debug("%s: master_port: %d\n", __func__, master_port);
	return master_port;
}

static int get_master_port_val(int master_port)
{
	int val = 0;
const char *dai_name_list[] = {
	"swr_dmic_tx0",
	"swr_dmic_tx1",
	"swr_dmic_tx2",
	"swr_dmic_tx3",
};

	switch (master_port) {
	case SWRM_TX1_CH1:
		val = 0;
		break;
	case SWRM_TX1_CH2:
		val = 1;
		break;
	case SWRM_TX1_CH3:
		val = 2;
		break;
	case SWRM_TX1_CH4:
		val = 3;
		break;
	case SWRM_TX2_CH1:
		val = 4;
		break;
	case SWRM_TX2_CH2:
		val = 5;
		break;
	case SWRM_TX2_CH3:
		val = 6;
		break;
	case SWRM_TX2_CH4:
		val = 7;
		break;
	case SWRM_TX3_CH1:
		val = 8;
		break;
	case SWRM_TX3_CH2:
		val = 9;
		break;
	case SWRM_TX3_CH3:
		val = 10;
		break;
	case SWRM_TX3_CH4:
		val = 11;
		break;
	case SWRM_PCM_IN:
		val = 12;
		break;
	default:
		val = 0;
		pr_debug("%s: undefined master_port:%d, fallback to default val: %d\n",
			 __func__, master_port, val);
		break;
	}
const char *aif_name_list[] = {
	"SWR_DMIC_AIF0 Playback",
	"SWR_DMIC_AIF1 Playback",
	"SWR_DMIC_AIF2 Playback",
	"SWR_DMIC_AIF3 Playback",
};

	pr_debug("%s: master_port:%d val: %d\n", __func__, master_port, val);
	return val;
}
static int swr_dmic_reset(struct swr_device *pdev);
static int swr_dmic_up(struct swr_device *pdev);
static int swr_dmic_down(struct swr_device *pdev);

static inline int swr_dmic_tx_get_slave_port_type_idx(const char *wname,
				      unsigned int *port_idx)
{
	u8 port_type;

	if (strnstr(wname, "HIFI", sizeof("HIFI")))
	if (strnstr(wname, "HIFI", strlen(wname)))
		port_type = SWR_DMIC_HIFI_PORT;
	else if (strnstr(wname, "LP", sizeof("LP")))
	else if (strnstr(wname, "LP", strlen(wname)))
		port_type = SWR_DMIC_LP_PORT;
	else
		return -EINVAL;
@@ -187,6 +106,16 @@ static inline int swr_dmic_tx_get_slave_port_type_idx(const char *wname,
	return 0;
}

static inline int swr_dmic_get_master_port_val(int port)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(swr_master_channel_map); i++)
		if (port == swr_master_channel_map[i])
			return i;
	return 0;
}

static int swr_dmic_tx_master_port_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
@@ -202,14 +131,15 @@ static int swr_dmic_tx_master_port_get(struct snd_kcontrol *kcontrol,
		dev_dbg(component->dev, "%s: invalid port string\n", __func__);
		return ret;
	}
	swr_dmic->port_type = slave_port_idx;

	if (slave_port_idx >= 0 &&
		slave_port_idx < SWR_DMIC_MAX_PORTS)
		ucontrol->value.integer.value[0] = get_master_port_val(
	ucontrol->value.integer.value[0] =
			swr_dmic_get_master_port_val(
				swr_dmic->tx_master_port_map[slave_port_idx]);

	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
			__func__, ucontrol->value.integer.value[0]);

	return 0;
}

@@ -228,17 +158,13 @@ static int swr_dmic_tx_master_port_put(struct snd_kcontrol *kcontrol,
		dev_dbg(component->dev, "%s: invalid port string\n", __func__);
		return ret;
	}
	swr_dmic->port_type = slave_port_idx;


	dev_dbg(component->dev, "%s: slave_port_idx: %d",
			__func__, slave_port_idx);
	dev_dbg(component->dev, "%s: ucontrol->value.enumerated.item[0] = %ld\n",
			__func__, ucontrol->value.enumerated.item[0]);
	if (slave_port_idx >= 0 &&
		slave_port_idx < SWR_DMIC_MAX_PORTS)
	swr_dmic->tx_master_port_map[slave_port_idx] =
				get_master_port(
					ucontrol->value.enumerated.item[0]);
		swr_master_channel_map[ucontrol->value.enumerated.item[0]];
	dev_dbg(component->dev, "%s: slv port id: %d, master_port_type: %d\n",
		__func__, slave_port_idx,
		swr_dmic->tx_master_port_map[slave_port_idx]);

	return 0;
}
@@ -254,20 +180,27 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w,

	u8 num_ch = 1;
	u8 ch_mask = 0x01; // only DpnChannelEN1 register is available
	u8 port_type = 0;
	u32 ch_rate = 0;
	u32 ch_rate = SWR_CLK_RATE_4P8MHZ;
	u8 num_port = 1;
	u8 port_type = 0;
	u8 port_id = swr_dmic->port_type;

	/*
	 * Port 1 is high quality / 2.4 or 3.072 Mbps
	 * Port 2 is listen low power / 0.6 or 0.768 Mbps
	 */
	u8 port_id = swr_dmic->tx_mode;
	if(swr_dmic->port_type)
		ch_rate = SWR_CLK_RATE_2P4MHZ;
	else
		ch_rate = SWR_CLK_RATE_4P8MHZ;

	port_type = swr_dmic->tx_master_port_map[port_id];

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = swr_connect_port(swr_dmic->swr_slave, &port_id, num_port,
			&ch_mask, &ch_rate, &num_ch, &port_type);
		ret = swr_connect_port(swr_dmic->swr_slave, &port_id,
					num_port, &ch_mask, &ch_rate,
					&num_ch, &port_type);
		break;
	case SND_SOC_DAPM_POST_PMU:
		ret = swr_slvdev_datapath_control(swr_dmic->swr_slave,
@@ -278,56 +211,48 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w,
			swr_dmic->swr_slave->dev_num, false);
		break;
	case SND_SOC_DAPM_POST_PMD:
		ret = swr_disconnect_port(swr_dmic->swr_slave, &port_id,
					  num_port, &ch_mask, &port_type);
		ret = swr_disconnect_port(swr_dmic->swr_slave,
				&port_id, num_port, &ch_mask, &port_type);
		break;
	};

	return ret;
}

static const char * const tx_mode_text_swr_mic[] = {
	"MIC_HIFI", "MIC_LP",
};

static int swr_mic_tx_mode_put(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
static int swr_dmic_enable_supply(struct snd_soc_dapm_widget *w,
			       struct snd_kcontrol *kcontrol,
			       int event)
{
	struct snd_soc_component *component =
			snd_soc_kcontrol_component(kcontrol);
			snd_soc_dapm_to_component(w->dapm);
	struct swr_dmic_priv *swr_dmic =
			snd_soc_component_get_drvdata(component);
	int ret = 0;

	dev_dbg(component->dev, "%s: tx_mode  = %ld\n",
		__func__, ucontrol->value.integer.value[0]);

	swr_dmic->tx_mode =  ucontrol->value.integer.value[0];
	dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
		w->name, event);

	return 0;
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = swr_dmic_up(swr_dmic->swr_slave);
		break;
	case SND_SOC_DAPM_POST_PMU:
		ret = swr_dmic_reset(swr_dmic->swr_slave);
		break;
	case SND_SOC_DAPM_POST_PMD:
		ret = swr_dmic_down(swr_dmic->swr_slave);
		break;
	}

static int swr_mic_tx_mode_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component =
			snd_soc_kcontrol_component(kcontrol);
	struct swr_dmic_priv *swr_dmic =
			snd_soc_component_get_drvdata(component);

	ucontrol->value.integer.value[0] = swr_dmic->tx_mode;
	if (ret)
		dev_dbg(component->dev, "%s wname: %s event: %d ret : %d\n",
			__func__, w->name, event, ret);

	dev_dbg(component->dev, "%s: tx_mode = 0x%x\n", __func__,
			swr_dmic->tx_mode);

	return 0;
	return ret;
}

static const struct soc_enum tx_mode_enum_swr_mic =
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_mode_text_swr_mic),
			    tx_mode_text_swr_mic);

static const char * const tx_master_port_text[] = {
	"SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4",
	"ZERO", "SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4",
	"SWRM_TX2_CH1", "SWRM_TX2_CH2", "SWRM_TX2_CH3", "SWRM_TX2_CH4",
	"SWRM_TX3_CH1", "SWRM_TX3_CH2", "SWRM_TX3_CH3", "SWRM_TX3_CH4",
	"SWRM_PCM_IN",
@@ -338,9 +263,6 @@ static const struct soc_enum tx_master_port_enum =
				tx_master_port_text);

static const struct snd_kcontrol_new swr_dmic_snd_controls[] = {
	SOC_ENUM_EXT("TX MODE", tx_mode_enum_swr_mic,
			swr_mic_tx_mode_get, swr_mic_tx_mode_put),

	SOC_ENUM_EXT("HIFI PortMap", tx_master_port_enum,
		swr_dmic_tx_master_port_get, swr_dmic_tx_master_port_put),
	SOC_ENUM_EXT("LP PortMap", tx_master_port_enum,
@@ -352,17 +274,23 @@ static const struct snd_kcontrol_new dmic_switch[] = {
};

static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = {
	SND_SOC_DAPM_MIXER_E("DMIC_SWR_MIXER", SND_SOC_NOPM, 0, 0,
	SND_SOC_DAPM_MIXER_E("SWR_DMIC_MIXER", SND_SOC_NOPM, 0, 0,
			dmic_switch, ARRAY_SIZE(dmic_switch), dmic_swr_ctrl,
			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
			SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_INPUT("SWR_DMIC"),

	SND_SOC_DAPM_SUPPLY_S("SMIC_SUPPLY", 1, SND_SOC_NOPM, 0, 0,
				swr_dmic_enable_supply,
				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
				SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_OUTPUT("SWR_DMIC_OUTPUT"),
};

static const struct snd_soc_dapm_route swr_dmic_audio_map[] = {
	{"SWR_DMIC", NULL, "SMIC_SUPPLY"},
	{"SWR_DMIC_MIXER", "Switch", "SWR_DMIC"},
	{"SWR_DMIC_OUTPUT", NULL, "SWR_DMIC_MIXER"},
};
@@ -400,55 +328,63 @@ static const struct snd_soc_component_driver soc_codec_dev_swr_dmic = {
	.num_dapm_routes = ARRAY_SIZE(swr_dmic_audio_map),
};

static struct snd_soc_dai_ops wsa_dai_ops = {
};
static int enable_wcd_codec_supply(struct swr_dmic_priv *swr_dmic, bool enable)
{
	int rc = 0;
	int micb_num = swr_dmic->micb_num;
	struct snd_soc_component *component = swr_dmic->supply_component;

	if (!component) {
		pr_err("%s: component is NULL\n", __func__);
		return -EINVAL;
	}

static struct snd_soc_dai_driver swr_dmic_dai[] = {
	if (enable)
		rc = wcd938x_codec_force_enable_micbias_v2(component,
					SND_SOC_DAPM_PRE_PMU, micb_num);
	else
		rc = wcd938x_codec_force_enable_micbias_v2(component,
					SND_SOC_DAPM_POST_PMD, micb_num);

	return rc;
}

static int swr_dmic_parse_supply(struct device_node *np,
				struct swr_dmic_priv *swr_dmic)
{
		.name = "",
		.id = 0,
		.playback = {
			.stream_name = "",
			.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
				SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
				SNDRV_PCM_FMTBIT_S24_LE |
				SNDRV_PCM_FMTBIT_S32_LE),
			.rate_max = 192000,
			.rate_min = 8000,
			.channels_min = 1,
			.channels_max = 2,
		},
		.ops = &wsa_dai_ops,
	},
};
	struct platform_device *pdev = NULL;

	if (!np || !swr_dmic)
		return -EINVAL;

	pdev = of_find_device_by_node(np);
	if (!pdev)
		return -EINVAL;

	swr_dmic->supply_component = snd_soc_lookup_component(&pdev->dev, NULL);

	return 0;
}

static int swr_dmic_probe(struct swr_device *pdev)
{
	int ret = 0;
	struct swr_dmic_priv *swr_dmic;
	int i = 0;
	u8 devnum = 0;
	u8 swr_devnum = 0;
	int dev_index = -1;
	char* prefix_name = NULL;
	struct swr_dmic_priv *swr_dmic = NULL;
	const char *swr_dmic_name_prefix_of = NULL;
	const char *swr_dmic_codec_name_of = NULL;
	struct snd_soc_component *component;
	char *dai_name;
	char *aif_name;
	struct snd_soc_component *component = NULL;

	swr_dmic = devm_kzalloc(&pdev->dev, sizeof(struct swr_dmic_priv),
			    GFP_KERNEL);
	if (!swr_dmic)
		return -ENOMEM;

	swr_dmic->cdc_supply = devm_kzalloc(&pdev->dev,
					sizeof(struct cdc_wcd_supply),
					GFP_KERNEL);
	if (!swr_dmic->cdc_supply)
		return -ENOMEM;

	ret = of_property_read_string(pdev->dev.of_node, "qcom,swr-dmic-supply",
				&swr_dmic->supply_name);
	ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr-dmic-supply",
				&swr_dmic->micb_num);
	if (ret) {
		dev_dbg(&pdev->dev, "%s: Looking up %s property in node %s failed\n",
		__func__, "qcom,swr-dmic-supply",
@@ -462,17 +398,17 @@ static int swr_dmic_probe(struct swr_device *pdev)
			__func__);
		swr_dmic->is_wcd_supply = false;
	} else {
		msm_cdc_init_wcd_supply(swr_dmic->wcd_handle,
				swr_dmic->supply_name, swr_dmic->cdc_supply);
		swr_dmic_parse_supply(swr_dmic->wcd_handle, swr_dmic);
		swr_dmic->is_wcd_supply = true;
	}

	if (swr_dmic->is_wcd_supply) {
		ret = msm_cdc_enable_wcd_supply(swr_dmic->cdc_supply, true);
		ret = enable_wcd_codec_supply(swr_dmic, true);
		if (ret) {
			ret = -EPROBE_DEFER;
			goto err;
		}
		++swr_dmic->is_en_supply;
	}

	swr_set_dev_data(pdev, swr_dmic);
@@ -485,7 +421,7 @@ static int swr_dmic_probe(struct swr_device *pdev)
		dev_dbg(&pdev->dev, "%s: Looking up %s property in node %s failed\n",
		__func__, "qcom,swr-dmic-prefix",
		pdev->dev.of_node->full_name);
		goto err;
		goto dev_err;
	}

	ret = of_property_read_string(pdev->dev.of_node, "qcom,codec-name",
@@ -494,7 +430,7 @@ static int swr_dmic_probe(struct swr_device *pdev)
		dev_dbg(&pdev->dev, "%s: Looking up %s property in node %s failed\n",
		__func__, "qcom,codec-name",
		pdev->dev.of_node->full_name);
		goto err;
		goto dev_err;
	}

	/*
@@ -503,14 +439,16 @@ static int swr_dmic_probe(struct swr_device *pdev)
	 * as per HW requirement.
	 */
	usleep_range(5000, 5010);
	ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
	ret = swr_get_logical_dev_num(pdev, pdev->addr, &swr_devnum);
	if (ret) {
		dev_dbg(&pdev->dev,
			"%s get devnum %d for dev addr %lx failed\n",
			__func__, devnum, pdev->addr);
		goto dev_err;
			__func__, swr_devnum, pdev->addr);
		ret = -EPROBE_DEFER;
		goto err;
	}
	pdev->dev_num = devnum;
	pdev->dev_num = swr_devnum;


	swr_dmic->driver = devm_kzalloc(&pdev->dev,
			sizeof(struct snd_soc_component_driver), GFP_KERNEL);
@@ -521,53 +459,23 @@ static int swr_dmic_probe(struct swr_device *pdev)

	memcpy(swr_dmic->driver, &soc_codec_dev_swr_dmic,
			sizeof(struct snd_soc_component_driver));
	swr_dmic->driver->name = devm_kzalloc(&pdev->dev,
			strlen(swr_dmic_codec_name_of), GFP_KERNEL);
	if (!swr_dmic->driver->name) {
		ret = -ENOMEM;
		goto dev_err;
	}

	for (i = 0; i < ARRAY_SIZE(codec_name_list); i++) {
		if (!strcmp(swr_dmic_codec_name_of, codec_name_list[i]))
		if (!strcmp(swr_dmic_codec_name_of, codec_name_list[i])) {
			dev_index = i;
			break;
		}
	if (i == ARRAY_SIZE(codec_name_list))
		goto dev_err;

	swr_dmic->dai_driver = devm_kzalloc(&pdev->dev,
			sizeof(struct snd_soc_dai_driver), GFP_KERNEL);
	if (!swr_dmic->dai_driver) {
		ret = -ENOMEM;
		goto dev_err;
	}

	memcpy(swr_dmic->dai_driver, swr_dmic_dai,
			sizeof(struct snd_soc_dai_driver));
	dai_name = devm_kzalloc(&pdev->dev, strlen(DEFAULT_CODEC_NAME),
			GFP_KERNEL);
	if (!dai_name) {
		ret = -ENOMEM;
	if (dev_index < 0) {
		ret = -EINVAL;
		goto dev_err;
	}

	memcpy(dai_name, DEFAULT_CODEC_NAME, strlen(DEFAULT_CODEC_NAME));
	dai_name[DAI_NAME_NUM_INDEX] = itoa(i);
	swr_dmic->dai_driver->name = dai_name;
	swr_dmic->dai_driver->id = i;
	aif_name = devm_kzalloc(&pdev->dev, strlen(DEFAULT_AIF_NAME),
			GFP_KERNEL);
	if (!aif_name) {
		ret = -ENOMEM;
		goto dev_err;
	}

	memcpy(aif_name, DEFAULT_AIF_NAME, strlen(DEFAULT_AIF_NAME));
	aif_name[AIF_NAME_NUM_INDEX] = itoa(i);
	swr_dmic->dai_driver->playback.stream_name = aif_name;
	swr_dmic->driver->name = dai_name_list[dev_index];

	ret = snd_soc_register_component(&pdev->dev, swr_dmic->driver,
				swr_dmic->dai_driver, 1);
				NULL, 0);
	if (ret) {
		dev_err(&pdev->dev, "%s: Codec registration failed\n",
			__func__);
@@ -577,19 +485,26 @@ static int swr_dmic_probe(struct swr_device *pdev)
	component = snd_soc_lookup_component(&pdev->dev,
						swr_dmic->driver->name);
	swr_dmic->component = component;
	component->name_prefix = devm_kzalloc(&pdev->dev,
	prefix_name = devm_kzalloc(&pdev->dev,
					strlen(swr_dmic_name_prefix_of),
					GFP_KERNEL);
	if (!component->name_prefix) {
	if (!prefix_name) {
		ret = -ENOMEM;
		goto dev_err;
	}
	strlcpy(prefix_name, swr_dmic_name_prefix_of,
			strlen(swr_dmic_name_prefix_of));
	component->name_prefix = prefix_name;

	return 0;

dev_err:
	if (swr_dmic->is_wcd_supply)
		msm_cdc_enable_wcd_supply(swr_dmic->cdc_supply, false);
	if (swr_dmic->is_en_supply == 1) {
		enable_wcd_codec_supply(swr_dmic, false);
		--swr_dmic->is_en_supply;
	}
	swr_dmic->is_wcd_supply = false;
	swr_dmic->wcd_handle = NULL;
	swr_remove_device(pdev);
err:
	return ret;
@@ -620,8 +535,10 @@ static int swr_dmic_up(struct swr_device *pdev)
		dev_err(&pdev->dev, "%s: swr_dmic is NULL\n", __func__);
		return -EINVAL;
	}
	if (swr_dmic->is_wcd_supply)
		ret = msm_cdc_enable_wcd_supply(swr_dmic->cdc_supply, true);

	++swr_dmic->is_en_supply;
	if (swr_dmic->is_en_supply == 1)
		ret = enable_wcd_codec_supply(swr_dmic, true);

	return ret;
}
@@ -636,9 +553,18 @@ static int swr_dmic_down(struct swr_device *pdev)
		dev_err(&pdev->dev, "%s: swr_dmic is NULL\n", __func__);
		return -EINVAL;
	}
	if (swr_dmic->is_wcd_supply)
		ret = msm_cdc_enable_wcd_supply(swr_dmic->cdc_supply, false);

	--swr_dmic->is_en_supply;
	if (swr_dmic->is_en_supply < 0) {
		dev_warn(&pdev->dev, "%s: mismatch in supply count %d\n",
			__func__, swr_dmic->is_en_supply);
		swr_dmic->is_en_supply = 0;
		goto done;
	}
	if (!swr_dmic->is_en_supply)
		enable_wcd_codec_supply(swr_dmic, false);

done:
	return ret;
}

+3 −5
Original line number Diff line number Diff line
@@ -43,11 +43,9 @@ static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {

/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */
	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},  /* TX1 */
	{1,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1},  /* TX2 */
	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},  /* TX3 */
	{3,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1},  /* TX4 */
	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},  /* TX1 */
	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},  /* TX2 */
	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},  /* TX3 */
};

/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
+177 −14

File changed.

Preview size limit exceeded, changes collapsed.