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

Commit 79274c74 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: sdm660: Enable mclk for dmic for RD LC variant"

parents e0400de2 1152497c
Loading
Loading
Loading
Loading
+419 −20
Original line number Diff line number Diff line
@@ -23,7 +23,9 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <linux/regulator/consumer.h>
#include <dsp/q6afe-v2.h>
#include <dsp/q6core.h>
#include <ipc/apr.h>
#include <soc/internal.h>
#include "sdm660-cdc-registers.h"
@@ -40,6 +42,8 @@
#define CF_MIN_3DB_150HZ		0x2

#define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32
#define MAX_ON_DEMAND_DIG_SUPPLY_NAME_LENGTH 64
#define CODEC_DT_MAX_PROP_SIZE 40

static unsigned long rx_digital_gain_reg[] = {
	MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL,
@@ -65,6 +69,13 @@ static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
struct snd_soc_codec *registered_digcodec;
struct hpf_work tx_hpf_work[NUM_DECIMATORS];

static int msm_dig_cdc_enable_on_demand_supply(
			struct snd_soc_dapm_widget *w,
			struct snd_kcontrol *kcontrol, int event);
static char on_demand_supply_name[][MAX_ON_DEMAND_DIG_SUPPLY_NAME_LENGTH] = {
	"cdc-vdd-digital",
};

/* Codec supports 2 IIR filters */
enum {
	IIR1 = 0,
@@ -72,6 +83,33 @@ enum {
	IIR_MAX,
};

/*
 * msm_digcdc_mclk_enable - add mclk support in digital codec
 * @codec: codec instance
 * @mclk_enable: mclk enable/disable
 * @dapm: check for dapm widget
 */
int msm_digcdc_mclk_enable(struct snd_soc_codec *codec,
			int mclk_enable, bool dapm)
{
	dev_dbg(codec->dev, "%s: mclk_enable = %u, dapm = %d\n",
			__func__, mclk_enable, dapm);
	if (mclk_enable) {
		snd_soc_update_bits(codec,
			MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x01);
		snd_soc_update_bits(codec,
			MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x01);
	} else {
		snd_soc_update_bits(codec,
			MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x00);
		snd_soc_update_bits(codec,
			MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x00);
	}

	return 0;
}
EXPORT_SYMBOL(msm_digcdc_mclk_enable);

static int msm_digcdc_clock_control(bool flag)
{
	int ret = -EINVAL;
@@ -239,7 +277,8 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec,

	if (SND_SOC_DAPM_EVENT_ON(event)) {
		/* compander is not enabled */
		if (!dig_cdc->comp_enabled[interp_n]) {
		if (!dig_cdc->comp_enabled[interp_n] &&
			dig_cdc->set_compander_mode) {
			dig_cdc->set_compander_mode(dig_cdc->handle, 0x00);
			return 0;
		};
@@ -261,6 +300,7 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec,
				return 0;
			}
		}
		if (dig_cdc->set_compander_mode)
			dig_cdc->set_compander_mode(dig_cdc->handle, 0x08);
		/* Enable Compander Clock */
		snd_soc_update_bits(codec,
@@ -606,6 +646,7 @@ static void tx_hpf_corner_freq_callback(struct work_struct *work)

	dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n",
		 __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
	if (msm_dig_cdc->update_clkdiv)
		msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x51);

	snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
@@ -961,6 +1002,7 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w,
			snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
					    CF_MIN_3DB_150HZ << 4);
		}
		if (msm_dig_cdc->update_clkdiv)
			msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x42);
		break;
	case SND_SOC_DAPM_POST_PMU:
@@ -1240,6 +1282,29 @@ int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
}
EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry);

static void msm_dig_cdc_update_micbias_regulator(
				const struct msm_dig_priv *dig_cdc,
				const char *name,
				struct on_demand_dig_supply *micbias_supply)
{
	int i;

	for (i = 0; i < dig_cdc->num_of_supplies; i++) {
		if (dig_cdc->supplies[i].supply &&
				!strcmp(dig_cdc->supplies[i].supply, name)) {
			micbias_supply->supply =
				dig_cdc->supplies[i].consumer;
			micbias_supply->min_uv = dig_cdc->regulator[i].min_uv;
			micbias_supply->max_uv = dig_cdc->regulator[i].max_uv;
			micbias_supply->optimum_ua =
				dig_cdc->regulator[i].optimum_ua;
			return;
		}
	}

	dev_dbg(dig_cdc->dev, "Error: regulator not found:%s\n", name);
}

static void sdm660_tx_mute_update_callback(struct work_struct *work)
{
	struct tx_mute_work *tx_mute_dwork;
@@ -1306,6 +1371,13 @@ static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
			return ret;
		}
	}

	msm_dig_cdc_update_micbias_regulator(
			msm_dig_cdc,
			on_demand_supply_name[ON_DEMAND_DIGITAL],
			&msm_dig_cdc->on_demand_list[ON_DEMAND_DIGITAL]);
	atomic_set(&msm_dig_cdc->on_demand_list[ON_DEMAND_DIGITAL].ref, 0);

	registered_digcodec = codec;

	snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
@@ -1796,6 +1868,11 @@ static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = {
	SND_SOC_DAPM_SUPPLY("TX_I2S_CLK",
		MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0),

	SND_SOC_DAPM_MICBIAS_E("DIGITAL_REGULATOR", SND_SOC_NOPM,
		ON_DEMAND_DIGITAL, 0,
		msm_dig_cdc_enable_on_demand_supply,
		SND_SOC_DAPM_PRE_PMU |
		SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0,
			&i2s_tx2_inp1_mux),
@@ -1979,6 +2056,218 @@ static const struct snd_kcontrol_new msm_dig_snd_controls[] = {
		MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0),
};

static int msm_dig_cdc_enable_on_demand_supply(
		struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
{
	int ret = 0;
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
	struct on_demand_dig_supply *supply;

	if (w->shift >= ON_DEMAND_DIG_SUPPLIES_MAX) {
		dev_err(codec->dev, "%s: error index >= MAX on demand supplies",
			__func__);
		ret = -EINVAL;
		goto out;
	}
	dev_dbg(codec->dev, "%s: supply: %s event: %d ref: %d\n",
		__func__, on_demand_supply_name[w->shift], event,
		atomic_read(&msm_dig_cdc->on_demand_list[w->shift].ref));

	supply = &msm_dig_cdc->on_demand_list[w->shift];
	if (!supply->supply) {
		dev_err(codec->dev, "%s: err supply not present ond for %d",
			__func__, w->shift);
		goto out;
	}
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (atomic_inc_return(&supply->ref) == 1) {
			ret = regulator_set_voltage(supply->supply,
						supply->min_uv,
						supply->max_uv);
			if (ret) {
				dev_err(codec->dev,
					"Setting regulator voltage(en) for micbias with err = %d\n",
					ret);
				goto out;
			}
			ret = regulator_set_load(supply->supply,
						supply->optimum_ua);
			if (ret < 0) {
				dev_err(codec->dev,
					"Setting regulator optimum mode(en) failed for micbias with err = %d\n",
					ret);
				goto out;
			}
			ret = regulator_enable(supply->supply);
			if (ret)
				dev_err(codec->dev, "%s: Failed to enable %s\n",
					__func__,
					on_demand_supply_name[w->shift]);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (atomic_read(&supply->ref) == 0) {
			dev_dbg(codec->dev, "%s: %s supply has been disabled.\n",
				__func__, on_demand_supply_name[w->shift]);
			goto out;
		}
		if (atomic_dec_return(&supply->ref) == 0) {
			ret = regulator_disable(supply->supply);
			if (ret)
				dev_err(codec->dev, "%s: Failed to disable %s\n",
					__func__,
					on_demand_supply_name[w->shift]);
			ret = regulator_set_voltage(supply->supply,
					0,
					supply->max_uv);
			if (ret) {
				dev_err(codec->dev,
					"Setting regulator voltage(dis) failed for micbias with err = %d\n",
					ret);
				goto out;
			}
			ret = regulator_set_load(supply->supply, 0);
			if (ret < 0)
				dev_err(codec->dev,
					"Setting regulator optimum mode(dis) failed for micbias with err = %d\n",
					ret);
		}
		break;
	default:
		break;
	}
out:
	return ret;
}

static int msm_digital_cdc_init_supplies(struct msm_dig_priv *msm_cdc)
{
	int ret;
	int i;

	msm_cdc->supplies = devm_kzalloc(msm_cdc->dev,
					sizeof(struct regulator_bulk_data) *
					ARRAY_SIZE(msm_cdc->regulator),
					GFP_KERNEL);
	if (!msm_cdc->supplies) {
		ret = -ENOMEM;
		goto err;
	}

	msm_cdc->num_of_supplies = 0;

	if (ARRAY_SIZE(msm_cdc->regulator) > MAX_REGULATOR) {
		dev_err(msm_cdc->dev, "%s: Array Size out of bound\n",
			__func__);
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < ARRAY_SIZE(msm_cdc->regulator); i++) {
		if (msm_cdc->regulator[i].name) {
			msm_cdc->supplies[i].supply =
						msm_cdc->regulator[i].name;
			msm_cdc->num_of_supplies++;
		}
	}

	ret = devm_regulator_bulk_get(msm_cdc->dev,
				      msm_cdc->num_of_supplies,
				      msm_cdc->supplies);
	if (ret != 0) {
		dev_err(msm_cdc->dev,
			"Failed to get supplies: err = %d\n",
			ret);
		goto err_supplies;
	}

	for (i = 0; i < msm_cdc->num_of_supplies; i++) {
		if (regulator_count_voltages(
			msm_cdc->supplies[i].consumer) <= 0)
			continue;
		ret = regulator_set_voltage(
					msm_cdc->supplies[i].consumer,
					msm_cdc->regulator[i].min_uv,
					msm_cdc->regulator[i].max_uv);
		if (ret) {
			dev_err(msm_cdc->dev,
				"Setting regulator voltage failed for regulator %s err = %d\n",
				msm_cdc->supplies[i].supply, ret);
			goto err_supplies;
		}
		ret = regulator_set_load(msm_cdc->supplies[i].consumer,
				msm_cdc->regulator[i].optimum_ua);
		if (ret < 0) {
			dev_err(msm_cdc->dev,
				"Setting regulator optimum mode failed for regulator %s err = %d\n",
				msm_cdc->supplies[i].supply, ret);
			goto err_supplies;
		} else {
			ret = 0;
		}
	}

	return ret;

err_supplies:
err:
	return ret;
}

static int msm_digital_cdc_dt_parse_vreg_info(struct device *dev,
	struct dig_cdc_regulator *vreg, const char *vreg_name)
{
	int len, ret = 0;
	const __be32 *prop;
	char prop_name[CODEC_DT_MAX_PROP_SIZE];
	struct device_node *regnode = NULL;
	u32 prop_val;

	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
			vreg_name);
	regnode = of_parse_phandle(dev->of_node, prop_name, 0);

	if (!regnode) {
		dev_err(dev, "Looking up %s property in node %s failed\n",
			prop_name, dev->of_node->full_name);
		return -ENODEV;
	}

	dev_dbg(dev, "Looking up %s property in node %s\n",
		prop_name, dev->of_node->full_name);

	vreg->name = vreg_name;

	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
		"qcom,%s-voltage", vreg_name);
	prop = of_get_property(dev->of_node, prop_name, &len);

	if (!prop || (len != (2 * sizeof(__be32)))) {
		dev_err(dev, "%s %s property\n",
			prop ? "invalid format" : "no", prop_name);
		return -EINVAL;
	}
	vreg->min_uv = be32_to_cpup(&prop[0]);
	vreg->max_uv = be32_to_cpup(&prop[1]);

	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
		"qcom,%s-current", vreg_name);

	ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
	if (ret) {
		dev_err(dev, "Looking up %s property in node %s failed",
			prop_name, dev->of_node->full_name);
		return -EFAULT;
	}
	vreg->optimum_ua = prop_val;
	dev_dbg(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
		vreg->min_uv, vreg->max_uv, vreg->optimum_ua);
	return 0;
}

static struct snd_soc_dai_ops msm_dig_dai_ops = {
	.hw_params = msm_dig_cdc_hw_params,
};
@@ -2095,23 +2384,131 @@ const struct regmap_config msm_digital_regmap_config = {
	.max_register = MSM89XX_CDC_CORE_MAX_REGISTER,
};

static bool msm_digital_cdc_populate_dt_pdata(
					struct device *dev,
					struct msm_dig_priv *dig_priv)
{
	int ret, ond_cnt, i, idx = 0;
	const char *name = NULL;
	const char *ond_prop_name = "qcom,cdc-on-demand-supplies";

	ond_cnt = of_property_count_strings(dev->of_node, ond_prop_name);
	if (ond_cnt < 0)
		ond_cnt = 0;

	if (ond_cnt > ARRAY_SIZE(dig_priv->regulator)) {
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < ond_cnt; i++, idx++) {
		ret = of_property_read_string_index(dev->of_node, ond_prop_name,
							i, &name);
		if (ret) {
			dev_err(dev, "%s: err parsing on_demand for %s idx %d\n",
				__func__, ond_prop_name, i);
			goto err;
		}

		dev_dbg(dev, "%s: Found on-demand cdc supply %s\n", __func__,
			name);
		ret = msm_digital_cdc_dt_parse_vreg_info(dev,
						&dig_priv->regulator[idx],
						name);
		if (ret) {
			dev_err(dev, "%s: err parsing vreg on_demand for %s idx %d\n",
				__func__, name, idx);
			goto err;
		}
	}

	return true;
err:
	dev_err(dev, "%s: Failed to populate DT data ret = %d\n",
		__func__, ret);
	return false;
}

static void msm_digital_cdc_disable_supplies(struct msm_dig_priv *msm_cdc)
{
	int i;

	if (!msm_cdc->supplies)
		return;

	regulator_bulk_disable(msm_cdc->num_of_supplies,
			       msm_cdc->supplies);
	for (i = 0; i < msm_cdc->num_of_supplies; i++) {
		if (regulator_count_voltages(
				msm_cdc->supplies[i].consumer) <= 0)
			continue;
		regulator_set_voltage(msm_cdc->supplies[i].consumer, 0,
				msm_cdc->regulator[i].max_uv);
		regulator_set_load(msm_cdc->supplies[i].consumer, 0);
	}
	regulator_bulk_free(msm_cdc->num_of_supplies,
			    msm_cdc->supplies);
	devm_kfree(msm_cdc->dev, msm_cdc->supplies);
}

static int msm_dig_cdc_probe(struct platform_device *pdev)
{
	int ret;
	int ret = -EINVAL;
	u32 dig_cdc_addr;
	struct msm_dig_priv *msm_dig_cdc;
	struct dig_ctrl_platform_data *pdata;
	struct dig_ctrl_platform_data *pdata = NULL;
	bool no_analog_codec = false;
	int adsp_state;

	adsp_state = apr_get_subsys_state();
	if ((adsp_state != APR_SUBSYS_LOADED) || (!q6core_is_adsp_ready())) {
		dev_err(&pdev->dev, "Adsp is not loaded yet %d\n",
			adsp_state);
		return -EPROBE_DEFER;
	}

	device_init_wakeup(&pdev->dev, true);

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

	msm_dig_cdc->dev = &pdev->dev;
	if (pdev->dev.of_node == NULL)
		return -EINVAL;

	if (pdev->dev.of_node)
		no_analog_codec = of_property_read_bool(pdev->dev.of_node,
					"qcom,no-analog-codec");

	if (no_analog_codec) {
		dev_dbg(&pdev->dev, "%s:Platform data from device tree\n",
				__func__);
		if (msm_digital_cdc_populate_dt_pdata(&pdev->dev,
							msm_dig_cdc)) {
			ret = msm_digital_cdc_init_supplies(
							msm_dig_cdc);
			if (ret) {
				dev_err(&pdev->dev,
				"%s: Fail to enable Codec supplies\n",
				__func__);
				goto rtn;
			}
		}
	} else {
		pdata = dev_get_platdata(&pdev->dev);
		if (!pdata) {
			dev_err(&pdev->dev, "%s: pdata from parent is NULL\n",
				__func__);
			ret = -EINVAL;
		goto rtn;
			goto err_supplies;
		}
		msm_dig_cdc->update_clkdiv = pdata->update_clkdiv;
		msm_dig_cdc->set_compander_mode = pdata->set_compander_mode;
		msm_dig_cdc->get_cdc_version = pdata->get_cdc_version;
		msm_dig_cdc->handle = pdata->handle;
		msm_dig_cdc->register_notifier = pdata->register_notifier;
	}

	ret = of_property_read_u32(pdev->dev.of_node, "reg",
@@ -2119,37 +2516,39 @@ static int msm_dig_cdc_probe(struct platform_device *pdev)
	if (ret) {
		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "reg");
		return ret;
		goto err_supplies;
	}

	msm_dig_cdc->dig_base = ioremap(dig_cdc_addr,
					MSM89XX_CDC_CORE_MAX_REGISTER);
	if (msm_dig_cdc->dig_base == NULL) {
		dev_err(&pdev->dev, "%s ioremap failed\n", __func__);
		return -ENOMEM;
		ret = -ENOMEM;
		goto err_supplies;
	}
	msm_dig_cdc->regmap =
		devm_regmap_init_mmio_clk(&pdev->dev, NULL,
			msm_dig_cdc->dig_base, &msm_digital_regmap_config);

	msm_dig_cdc->update_clkdiv = pdata->update_clkdiv;
	msm_dig_cdc->set_compander_mode = pdata->set_compander_mode;
	msm_dig_cdc->get_cdc_version = pdata->get_cdc_version;
	msm_dig_cdc->handle = pdata->handle;
	msm_dig_cdc->register_notifier = pdata->register_notifier;

	dev_set_drvdata(&pdev->dev, msm_dig_cdc);
	snd_soc_register_codec(&pdev->dev, &soc_msm_dig_codec,
				msm_codec_dais, ARRAY_SIZE(msm_codec_dais));
	dev_dbg(&pdev->dev, "%s: registered DIG CODEC 0x%x\n",
			__func__, dig_cdc_addr);
	return ret;
err_supplies:
	if (no_analog_codec)
		msm_digital_cdc_disable_supplies(msm_dig_cdc);
rtn:
	return ret;
}

static int msm_dig_cdc_remove(struct platform_device *pdev)
{
	struct msm_dig_priv *msm_cdc = dev_get_drvdata(&pdev->dev);

	snd_soc_unregister_codec(&pdev->dev);
	msm_digital_cdc_disable_supplies(msm_cdc);
	return 0;
}

+34 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
#define HPHL_PA_DISABLE (0x01 << 1)
#define HPHR_PA_DISABLE (0x01 << 2)
#define SPKR_PA_DISABLE (0x01 << 3)

#define MAX_REGULATOR   7
#define NUM_DECIMATORS	5
/* Codec supports 1 compander */
enum {
@@ -32,6 +32,27 @@ enum {
	MSM89XX_RX_MAX,
};

enum {
	ON_DEMAND_DIGITAL = 0,
	ON_DEMAND_DIG_SUPPLIES_MAX,
};

struct on_demand_dig_supply {
	struct regulator *supply;
	atomic_t ref;
	int min_uv;
	int max_uv;
	int optimum_ua;
};

struct dig_cdc_regulator {
	const char *name;
	int min_uv;
	int max_uv;
	int optimum_ua;
	struct regulator *regulator;
};

struct tx_mute_work {
	struct msm_dig_priv *dig_cdc;
	u32 decimator;
@@ -45,6 +66,7 @@ struct msm_cap_mode {

struct msm_dig_priv {
	struct snd_soc_codec *codec;
	struct device *dev;
	u32 comp_enabled[MSM89XX_RX_MAX];
	int (*codec_hph_comp_gpio)(bool enable, struct snd_soc_codec *codec);
	s32 dmic_1_2_clk_cnt;
@@ -60,6 +82,7 @@ struct msm_dig_priv {
	u32 mute_mask;
	int dapm_bias_off;
	void *handle;
	struct on_demand_dig_supply on_demand_list[ON_DEMAND_DIG_SUPPLIES_MAX];
	void (*set_compander_mode)(void *handle, int val);
	void (*update_clkdiv)(void *handle, int val);
	int (*get_cdc_version)(void *handle);
@@ -67,6 +90,9 @@ struct msm_dig_priv {
				 struct notifier_block *nblock,
				 bool enable);
	struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
	u32 num_of_supplies;
	struct regulator_bulk_data *supplies;
	struct dig_cdc_regulator regulator[MAX_REGULATOR];
};

struct dig_ctrl_platform_data {
@@ -104,6 +130,8 @@ extern void msm_dig_cdc_hph_comp_cb(
		struct snd_soc_codec *codec);
int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
					  struct snd_soc_codec *codec);
extern int msm_digcdc_mclk_enable(struct snd_soc_codec *codec,
				int mclk_enable, bool dapm);
#else /* CONFIG_SND_SOC_DIGITAL_CDC */
static inline void msm_dig_cdc_hph_comp_cb(
		int (*codec_hph_comp_gpio)(
@@ -118,5 +146,10 @@ static inline int msm_dig_codec_info_create_codec_entry(
{
	return 0;
}
static inline int msm_digcdc_mclk_enable(struct snd_soc_codec *codec,
				int mclk_enable, bool dapm)
{
	return 0;
}
#endif /* CONFIG_SND_SOC_DIGITAL_CDC */
#endif
+36 −4
Original line number Diff line number Diff line
@@ -3043,10 +3043,30 @@ static int msm_populate_dai_link_component_of_node(
				index = of_property_match_string(cdev->of_node,
							"asoc-codec-names",
							PMIC_INT_ANALOG_CODEC);
				phandle = of_parse_phandle(
							cdev->of_node,
							"asoc-codec",
							index);
				dai_link[i].codecs[ANA_CDC].of_node =
								phandle;
			}
		}
		if (pdata->snd_card_val == INT_DIG_SND_CARD) {
			if ((dai_link[i].id ==
					MSM_BACKEND_DAI_INT0_MI2S_RX) ||
			    (dai_link[i].id ==
					MSM_BACKEND_DAI_INT1_MI2S_RX) ||
			    (dai_link[i].id ==
					MSM_BACKEND_DAI_INT2_MI2S_TX) ||
			    (dai_link[i].id ==
					MSM_BACKEND_DAI_INT3_MI2S_TX)) {
				index = of_property_match_string(cdev->of_node,
							"asoc-codec-names",
							MSM_INT_DIGITAL_CODEC);
				phandle = of_parse_phandle(cdev->of_node,
							   "asoc-codec",
							   index);
				dai_link[i].codecs[ANA_CDC].of_node = phandle;
				dai_link[i].codec_of_node = phandle;
			}
		}
	}
@@ -3342,6 +3362,8 @@ static const struct of_device_id sdm660_asoc_machine_of_match[] = {
	  .data = "tasha_codec"},
	{ .compatible = "qcom,sdm670-asoc-snd-tavil",
	  .data = "tavil_codec"},
	{ .compatible = "qcom,qcs605-dig-asoc-snd",
	  .data = "digital_codec"},
	{},
};

@@ -3388,6 +3410,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
		ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg);
		if (ret)
			goto err;
	} else if (!strcmp(match->data, "digital_codec")) {
		pdata->snd_card_val = INT_DIG_SND_CARD;
		ret = msm_int_cdc_init(pdev, pdata, &card, NULL);
		if (ret)
			goto err;
	} else {
		dev_err(&pdev->dev,
			"%s: Not a matching DT sound node\n", __func__);
@@ -3408,6 +3435,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
					"qcom,cdc-ext-spk-gpios", 0);
	}

	if (pdata->snd_card_val == INT_DIG_SND_CARD) {
		/*reading the gpio configurations from dtsi file*/
		pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node,
					"qcom,cdc-dmic-gpios", 0);
	}
	pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node,
					"qcom,pri-mi2s-gpios", 0);
	pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node,
@@ -3479,7 +3511,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
			ret);
		goto err;
	}
	if (pdata->snd_card_val != INT_SND_CARD)
	if (pdata->snd_card_val > INT_MAX_SND_CARD)
		msm_ext_register_audio_notifier(pdev);

	return 0;
@@ -3510,7 +3542,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
	struct snd_soc_card *card = platform_get_drvdata(pdev);
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);

	if (pdata->snd_card_val == INT_SND_CARD)
	if (pdata->snd_card_val <= INT_MAX_SND_CARD)
		mutex_destroy(&pdata->cdc_int_mclk0_mutex);

	if (gpio_is_valid(pdata->us_euro_gpio)) {
@@ -3526,7 +3558,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
		pdata->hph_en0_gpio = 0;
	}

	if (pdata->snd_card_val != INT_SND_CARD)
	if (pdata->snd_card_val > INT_MAX_SND_CARD)
		audio_notifier_deregister("sdm660");

	snd_soc_unregister_card(card);
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -87,6 +87,8 @@ struct sdm660_codec {

enum {
	INT_SND_CARD,
	INT_DIG_SND_CARD,
	INT_MAX_SND_CARD = INT_DIG_SND_CARD,
	EXT_SND_CARD_TASHA,
	EXT_SND_CARD_TAVIL,
};
+234 −20

File changed.

Preview size limit exceeded, changes collapsed.