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

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

Merge changes Ic20c893a,Id7756312,I48359c60,I5532d274,Ia57f335b,I7b28de37 into...

Merge changes Ic20c893a,Id7756312,I48359c60,I5532d274,Ia57f335b,I7b28de37 into audio-drivers.lnx.2.0

* changes:
  ASoC: codecs: Initialized vtable to reference to vport I2S check table.
  autoconf: Enable config support for apq8009 audio.
  ASoC: wcd9335: Add support for Microphone Activity Detection
  ASoC: apq8009: add changes to enable lpass_mclk for apq8009
  AS0C: Add afe_loopback_tx support for apq8009 BE dai
  ASoC: msm: Add machine driver and ext sound card for apq8909 target
parents 46f0b23f a1edfcf1
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -100,6 +100,11 @@ ifdef CONFIG_SND_SOC_MACHINE_SDXPOORWILLS
	MACHINE_OBJS += sdxpoorwills.o
endif

# for APQ8009 external codec sound card driver
ifdef CONFIG_SND_SOC_EXT_CODEC_8909
	MACHINE_EXT_OBJS += apq8009-i2s-ext-codec.o
endif

# for SDM450 internal codec sound card driver
ifdef CONFIG_SND_SOC_SDM450
	MACHINE_OBJS += msm8952.o
@@ -204,6 +209,9 @@ platform_dlkm-y := $(PLATFORM_OBJS)
obj-$(CONFIG_SND_SOC_SDM450) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)

obj-$(CONFIG_SND_SOC_EXT_CODEC_8909) += machine_ext_dlkm.o
machine_ext_dlkm-y := $(MACHINE_EXT_OBJS)

obj-$(CONFIG_SND_SOC_EXT_CODEC_SDM450) += machine_ext_dlkm.o
machine_ext_dlkm-y := $(MACHINE_EXT_OBJS)

+2993 −0

File added.

Preview size limit exceeded, changes collapsed.

+189 −0
Original line number Diff line number Diff line
@@ -25,12 +25,19 @@
#include <dsp/q6afe-v2.h>
#include "audio-ext-clk.h"

#define clk_audio_lpass_mclk 0x575ec22b

enum audio_clk_mux {
	PMI_CLK,
	AP_CLK2,
	LPASS_MCLK,
};

enum clk_enablement {
	CLK_DISABLE = 0,
	CLK_ENABLE,
};

struct pinctrl_info {
	struct pinctrl *pinctrl;
	struct pinctrl_state *sleep;
@@ -56,6 +63,13 @@ struct audio_ext_pmi_clk {
	struct clk c;
};

struct audio_ext_lpass_mclk {
	struct pinctrl_info pnctrl_info;
	struct clk c;
	u32 lpass_clock;
	void __iomem *lpass_csr_gpio_mux_spkrctl_vaddr;
};

static struct afe_clk_set clk2_config = {
	Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
	Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR,
@@ -65,6 +79,120 @@ static struct afe_clk_set clk2_config = {
	0,
};

static struct afe_clk_set digital_cdc_core_clk = {
	Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
	Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE,
	Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
	Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
	Q6AFE_LPASS_CLK_ROOT_DEFAULT,
	0,
};

static int audio_ext_set_lpass_mclk_v2(struct clk *clk,
				       enum clk_enablement enable)
{
	struct audio_ext_lpass_mclk *audio_lpass_mclk;
	int ret, val;

	pr_debug("%s: Setting clock using v2, enable(%d)\n", __func__, enable);

	audio_lpass_mclk = container_of(clk, struct audio_ext_lpass_mclk, c);
	if (audio_lpass_mclk == NULL) {
		pr_err("%s: audio_lpass_mclk is NULL\n", __func__);
		ret = -EINVAL;
		goto done;
	}

	if (audio_lpass_mclk->lpass_csr_gpio_mux_spkrctl_vaddr &&
	    enable) {
		val = ioread32(audio_lpass_mclk->
				lpass_csr_gpio_mux_spkrctl_vaddr);
		val = val | 0x00000002;
		iowrite32(val, audio_lpass_mclk->
				lpass_csr_gpio_mux_spkrctl_vaddr);
	}

	digital_cdc_core_clk.enable = enable;
	ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX,
				     &digital_cdc_core_clk);
	if (ret < 0) {
		pr_err("%s: afe_set_digital_codec_core_clock failed\n"
			" with ret %d\n", __func__, ret);
		goto done;
	}

done:
	return ret;
}

static int audio_ext_lpass_mclk_prepare(struct clk *clk)
{
	struct audio_ext_lpass_mclk *audio_lpass_mclk;
	struct pinctrl_info *pnctrl_info;
	enum lpass_clk_ver lpass_clk_ver;
	int ret;

	audio_lpass_mclk = container_of(clk, struct audio_ext_lpass_mclk, c);
	if (audio_lpass_mclk == NULL) {
		pr_err("%s: audio_lpass_mclk is NULL\n", __func__);
		ret = -EINVAL;
		goto done;
	}

	pnctrl_info = &audio_lpass_mclk->pnctrl_info;
	if (pnctrl_info && pnctrl_info->pinctrl) {
		ret = pinctrl_select_state(pnctrl_info->pinctrl,
					   pnctrl_info->active);
		if (ret) {
			pr_err("%s: pinctrl active state selection failed with %d\n",
				__func__, ret);
			ret = -EIO;
			goto done;
		}
	}

	lpass_clk_ver = afe_get_lpass_clk_ver();

	if (lpass_clk_ver >= LPASS_CLK_VER_2)
		ret = audio_ext_set_lpass_mclk_v2(clk, CLK_ENABLE);
done:
	return ret;
}

static void audio_ext_lpass_mclk_unprepare(struct clk *clk)
{
	struct audio_ext_lpass_mclk *audio_lpass_mclk;
	struct pinctrl_info *pnctrl_info;
	enum lpass_clk_ver lpass_clk_ver;
	int ret;

	audio_lpass_mclk = container_of(clk, struct audio_ext_lpass_mclk, c);
	if (audio_lpass_mclk == NULL) {
		pr_err("%s: audio_lpass_mclk is NULL\n", __func__);
		ret = -EINVAL;
		goto done;
	}

	pnctrl_info = &audio_lpass_mclk->pnctrl_info;
	if (pnctrl_info && pnctrl_info->pinctrl) {
		ret = pinctrl_select_state(pnctrl_info->pinctrl,
					   pnctrl_info->sleep);
		if (ret) {
			pr_err("%s: pinctrl sleep state selection failed with %d\n",
				__func__, ret);
			ret = -EIO;
			goto done;
		}
	}

	lpass_clk_ver = afe_get_lpass_clk_ver();

	if (lpass_clk_ver >= LPASS_CLK_VER_2)
		ret = audio_ext_set_lpass_mclk_v2(clk, CLK_DISABLE);
done:
	pr_debug("%s: Unprepare of mclk exiting with %d\n", __func__, ret);
}

static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk)
{
	return container_of(clk, struct audio_ext_ap_clk, c);
@@ -201,6 +329,12 @@ static const struct clk_ops audio_ext_pmi_clk_ops = {
	.prepare = audio_ext_pmi_clk_prepare,
	.unprepare = audio_ext_pmi_clk_unprepare,
};

static struct clk_ops audio_ext_lpass_mclk_ops = {
	.prepare = audio_ext_lpass_mclk_prepare,
	.unprepare = audio_ext_lpass_mclk_unprepare,
};

static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = {
	.gpio = -EINVAL,
	.c = {
@@ -234,10 +368,19 @@ static struct audio_ext_pmi_clk audio_pmi_clk = {
	},
};

static struct audio_ext_lpass_mclk audio_lpass_mclk = {
	.c = {
		.dbg_name = "audio_ext_lpass_mclk",
		.ops = &audio_ext_lpass_mclk_ops,
		CLK_INIT(audio_lpass_mclk.c),
	},
};

static struct clk_lookup audio_ref_clock[] = {
	CLK_LIST(audio_ap_clk),
	CLK_LIST(audio_pmi_clk),
	CLK_LIST(audio_ap_clk2),
	CLK_LIST(audio_lpass_mclk),
};

static int audio_get_pinctrl(struct platform_device *pdev,
@@ -255,6 +398,9 @@ static int audio_get_pinctrl(struct platform_device *pdev,
	case AP_CLK2:
		pnctrl_info = &audio_ap_clk2.pnctrl_info;
		break;
	case LPASS_MCLK:
		pnctrl_info = &audio_lpass_mclk.pnctrl_info;
		break;
	default:
		dev_err(dev, "%s Not a valid MUX ID: %d\n",
			__func__, mux);
@@ -307,6 +453,40 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
	int clk_gpio;
	int ret;
	struct clk *div_clk1;
	u32 lpass_csr_gpio_mux_spkrctl_reg = 0;

	ret = of_property_read_u32(pdev->dev.of_node,
			"qcom,lpass-clock",
			&audio_lpass_mclk.lpass_clock);
	if (ret)
		dev_dbg(&pdev->dev, "%s: qcom,lpass-clock is undefined\n",
				__func__);

	if (audio_lpass_mclk.lpass_clock) {

		ret = of_property_read_u32(pdev->dev.of_node, "reg",
				&lpass_csr_gpio_mux_spkrctl_reg);
		if (!ret) {
			audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr =
			devm_ioremap(&pdev->dev, lpass_csr_gpio_mux_spkrctl_reg, 4);
			if (audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr == NULL) {
				dev_err(&pdev->dev, "%s devm_ioremap failed\n", __func__);
				return -ENOMEM;
			}
		}

		ret = audio_get_pinctrl(pdev, LPASS_MCLK);
		if (ret)
			dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n",
				__func__, "LPASS_MCLK");

		ret = of_msm_clock_register(pdev->dev.of_node, audio_ref_clock,
			      ARRAY_SIZE(audio_ref_clock));
		if (ret)
			dev_err(&pdev->dev, "%s: clock register failed\n",
				__func__);
		return ret;
	}

	clk_gpio = of_get_named_gpio(pdev->dev.of_node,
				     "qcom,audio-ref-clk-gpio", 0);
@@ -348,6 +528,7 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
static int audio_ref_clk_remove(struct platform_device *pdev)
{
	struct pinctrl_info *pnctrl_info = &audio_ap_clk2.pnctrl_info;
	struct pinctrl_info *lpass_pnctrl_info = &audio_lpass_mclk.pnctrl_info;
	struct pinctrl_info *pmi_pnctrl_info = &audio_pmi_clk.pnctrl_info;

	if (audio_pmi_clk.gpio > 0)
@@ -360,11 +541,19 @@ static int audio_ref_clk_remove(struct platform_device *pdev)
		pnctrl_info->pinctrl = NULL;
	}

	if (lpass_pnctrl_info->pinctrl) {
		devm_pinctrl_put(lpass_pnctrl_info->pinctrl);
		lpass_pnctrl_info->pinctrl = NULL;
	}

	if (pmi_pnctrl_info->pinctrl) {
		devm_pinctrl_put(pmi_pnctrl_info->pinctrl);
		pmi_pnctrl_info->pinctrl = NULL;
	}

	if (audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr)
		devm_iounmap(&pdev->dev,
		 audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr);
	return 0;
}

+17 −2
Original line number Diff line number Diff line
@@ -2371,9 +2371,9 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,

	mutex_lock(&tasha_p->codec_mutex);

	if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
	if (tasha_p->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
		if (dai_id != AIF1_CAP) {
			dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
			dev_err(codec->dev, "%s: invalid AIF for Slimbus mode\n",
				__func__);
			mutex_unlock(&tasha_p->codec_mutex);
			return -EINVAL;
@@ -11923,6 +11923,21 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = {
		},
		.ops = &tasha_dai_ops,
	},
	{
		.name = "tasha_mad1",
		.id = AIF4_MAD_TX,
		.capture = {
			.stream_name = "AIF4 MAD TX",
			.rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
				SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
			.formats = TASHA_FORMATS_S16_S24_S32_LE,
			.rate_min = 16000,
			.rate_max = 384000,
			.channels_min = 1,
			.channels_max = 1,
		},
		.ops = &tasha_dai_ops,
	},
};

static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha)
+36 −5
Original line number Diff line number Diff line
@@ -2800,6 +2800,30 @@ static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai[] = {
	},
};

static struct snd_soc_dai_driver msm_dai_q6_afe_lb_tx_dai[] = {
	{
		.capture = {
			.stream_name = "AFE Loopback Capture",
			.aif_name = "AFE_LOOPBACK_TX",
			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
			 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
			 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
			 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_S24_3LE |
			SNDRV_PCM_FMTBIT_S32_LE ),
			.channels_min = 1,
			.channels_max = 8,
			.rate_min =     8000,
			.rate_max =     192000,
		},
		.id = AFE_LOOPBACK_TX,
		.probe = msm_dai_q6_dai_probe,
		.remove = msm_dai_q6_dai_remove,
	},
};

static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = {
	{
		.capture = {
@@ -4258,9 +4282,10 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
				 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
				 SNDRV_PCM_RATE_192000,
			.formats = SNDRV_PCM_FMTBIT_S16_LE |
			.formats = (SNDRV_PCM_FMTBIT_S16_LE|
						SNDRV_PCM_FMTBIT_S24_LE |
				SNDRV_PCM_FMTBIT_S24_3LE,
						SNDRV_PCM_FMTBIT_S24_3LE |
						SNDRV_PCM_FMTBIT_S32_LE ),
			.rate_min =     8000,
			.rate_max =     192000,
		},
@@ -4960,6 +4985,12 @@ static int msm_dai_q6_dev_probe(struct platform_device *pdev)
			pr_err("%s: Device not found stream name %s\n",
				__func__, stream_name);
		break;
	case AFE_LOOPBACK_TX:
		rc = snd_soc_register_component(&pdev->dev,
						&msm_dai_q6_component,
						&msm_dai_q6_afe_lb_tx_dai[0],
						1);
		break;
	case INT_BT_SCO_RX:
		rc = snd_soc_register_component(&pdev->dev,
			&msm_dai_q6_component, &msm_dai_q6_bt_sco_rx_dai, 1);
Loading