linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Adam Serbinski <adam@serbinski.com>
To: Mark Brown <broonie@kernel.org>,
	Srini Kandagatla <srinivas.kandagatla@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Adam Serbinski <adam@serbinski.com>,
	Andy Gross <agross@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Patrick Lai <plai@codeaurora.org>,
	Banajit Goswami <bgoswami@codeaurora.org>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	alsa-devel@alsa-project.org, linux-arm-msm@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 2/6] ASoC: qdsp6: q6afe: add support to pcm ports
Date: Tue, 11 Feb 2020 20:52:18 -0500	[thread overview]
Message-ID: <20200212015222.8229-3-adam@serbinski.com> (raw)
In-Reply-To: <20200212015222.8229-1-adam@serbinski.com>

This patch adds support to pcm ports in AFE.

Signed-off-by: Adam Serbinski <adam@serbinski.com>
CC: Andy Gross <agross@kernel.org>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Liam Girdwood <lgirdwood@gmail.com>
CC: Patrick Lai <plai@codeaurora.org>
CC: Banajit Goswami <bgoswami@codeaurora.org>
CC: Jaroslav Kysela <perex@perex.cz>
CC: Takashi Iwai <tiwai@suse.com>
CC: alsa-devel@alsa-project.org
CC: linux-arm-msm@vger.kernel.org
CC: devicetree@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 sound/soc/qcom/qdsp6/q6afe.c | 118 +++++++++++++++++++++++++++++++++++
 sound/soc/qcom/qdsp6/q6afe.h |  13 +++-
 2 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
index e0945f7a58c8..11de01679cad 100644
--- a/sound/soc/qcom/qdsp6/q6afe.c
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -40,6 +40,7 @@
 
 #define AFE_PARAM_ID_SLIMBUS_CONFIG    0x00010212
 #define AFE_PARAM_ID_I2S_CONFIG	0x0001020D
+#define AFE_PARAM_ID_PCM_CONFIG        0x0001020E
 #define AFE_PARAM_ID_TDM_CONFIG	0x0001029D
 #define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG	0x00010297
 
@@ -117,6 +118,15 @@
 #define AFE_PORT_ID_QUATERNARY_MI2S_RX      0x1006
 #define AFE_PORT_ID_QUATERNARY_MI2S_TX      0x1007
 
+#define AFE_PORT_ID_PRIMARY_PCM_RX          0x100A
+#define AFE_PORT_ID_PRIMARY_PCM_TX          0x100B
+#define AFE_PORT_ID_SECONDARY_PCM_RX        0x100C
+#define AFE_PORT_ID_SECONDARY_PCM_TX        0x100D
+#define AFE_PORT_ID_TERTIARY_PCM_RX         0x1012
+#define AFE_PORT_ID_TERTIARY_PCM_TX         0x1013
+#define AFE_PORT_ID_QUATERNARY_PCM_RX       0x1014
+#define AFE_PORT_ID_QUATERNARY_PCM_TX       0x1015
+
 /* Start of the range of port IDs for TDM devices. */
 #define AFE_PORT_ID_TDM_PORT_RANGE_START	0x9000
 
@@ -421,6 +431,29 @@ struct afe_digital_clk_cfg {
 	u16                  reserved;
 } __packed;
 
+#define AFE_API_VERSION_PCM_CONFIG		0x1
+#define AFE_PORT_PCM_QUANT_MAX			0x5
+#define AFE_PORT_PCM_SYNC_SRC_EXTERNAL		0x0
+#define AFE_PORT_PCM_SYNC_SRC_INTERNAL		0x1
+#define AFE_PORT_PCM_AUX_MODE_PCM		0x0
+#define AFE_PORT_PCM_BITS_PER_FRAME_64		0x3
+#define AFE_PORT_PCM_BITS_PER_FRAME_128		0x4
+#define AFE_PORT_PCM_CTRL_DATA_OE_DISABLE	0x0
+
+struct afe_param_id_pcm_cfg {
+	u32	pcm_cfg_minor_version;
+	u16	aux_mode;
+	u16	sync_src;
+	u16	frame_setting;
+	u16	quantype;
+	u16	ctrl_data_out_enable;
+	u16	reserved;
+	u32	sample_rate;
+	u16	bit_width;
+	u16	num_channels;
+	u16	slot_number_mapping[AFE_MAX_PCM_SLOT_COUNT];
+} __packed;
+
 struct afe_param_id_i2s_cfg {
 	u32	i2s_cfg_minor_version;
 	u16	bit_width;
@@ -452,6 +485,7 @@ union afe_port_config {
 	struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
 	struct afe_param_id_slimbus_cfg           slim_cfg;
 	struct afe_param_id_i2s_cfg	i2s_cfg;
+	struct afe_param_id_pcm_cfg	pcm_cfg;
 	struct afe_param_id_tdm_cfg	tdm_cfg;
 } __packed;
 
@@ -707,6 +741,22 @@ static struct afe_port_map port_maps[AFE_PORT_MAX] = {
 				QUINARY_TDM_TX_7, 0, 1},
 	[DISPLAY_PORT_RX] = { AFE_PORT_ID_HDMI_OVER_DP_RX,
 				DISPLAY_PORT_RX, 1, 1},
+	[PRIMARY_PCM_RX] = { AFE_PORT_ID_PRIMARY_PCM_RX,
+				PRIMARY_PCM_RX, 1, 1},
+	[PRIMARY_PCM_TX] = { AFE_PORT_ID_PRIMARY_PCM_TX,
+				PRIMARY_PCM_RX, 0, 1},
+	[SECONDARY_PCM_RX] = { AFE_PORT_ID_SECONDARY_PCM_RX,
+				SECONDARY_PCM_RX, 1, 1},
+	[SECONDARY_PCM_TX] = { AFE_PORT_ID_SECONDARY_PCM_TX,
+				SECONDARY_PCM_TX, 0, 1},
+	[TERTIARY_PCM_RX] = { AFE_PORT_ID_TERTIARY_PCM_RX,
+				TERTIARY_PCM_RX, 1, 1},
+	[TERTIARY_PCM_TX] = { AFE_PORT_ID_TERTIARY_PCM_TX,
+				TERTIARY_PCM_TX, 0, 1},
+	[QUATERNARY_PCM_RX] = { AFE_PORT_ID_QUATERNARY_PCM_RX,
+				QUATERNARY_PCM_RX, 1, 1},
+	[QUATERNARY_PCM_TX] = { AFE_PORT_ID_QUATERNARY_PCM_TX,
+				QUATERNARY_PCM_TX, 0, 1},
 };
 
 static void q6afe_port_free(struct kref *ref)
@@ -993,6 +1043,7 @@ int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
 		break;
 	case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
 	case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
+	/* TDM cases overlap with PCM */
 	case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
 		cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET;
 		cset.clk_id = clk_id;
@@ -1145,6 +1196,63 @@ void q6afe_hdmi_port_prepare(struct q6afe_port *port,
 }
 EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare);
 
+/**
+ * q6afe_pcm_port_prepare() - Prepare pcm afe port.
+ *
+ * @port: Instance of afe port
+ * @cfg: PCM configuration for the afe port
+ *
+ */
+int q6afe_pcm_port_prepare(struct q6afe_port *port, struct q6afe_pcm_cfg *cfg)
+{
+	union afe_port_config *pcfg = &port->port_cfg;
+	struct device *dev = port->afe->dev;
+
+	pcfg->pcm_cfg.pcm_cfg_minor_version = AFE_API_VERSION_PCM_CONFIG;
+
+	if (cfg->quantype > AFE_PORT_PCM_QUANT_MAX) {
+		dev_err(dev, "Invalid pcm quantization\n");
+		return -EINVAL;
+	}
+	pcfg->pcm_cfg.quantype = cfg->quantype;
+
+	memcpy(pcfg->pcm_cfg.slot_number_mapping, cfg->slot_number_mapping,
+	       sizeof(u16) * AFE_PORT_MAX_PCM_AUDIO_CHAN_CNT);
+
+	pcfg->pcm_cfg.aux_mode = AFE_PORT_PCM_AUX_MODE_PCM;
+	switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		pcfg->pcm_cfg.sync_src = AFE_PORT_PCM_SYNC_SRC_INTERNAL;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		pcfg->pcm_cfg.sync_src = AFE_PORT_PCM_SYNC_SRC_EXTERNAL;
+		break;
+	default:
+		dev_err(dev, "Unsupported format\n");
+		return -EINVAL;
+	}
+
+	switch (cfg->sample_rate) {
+	case 8000:
+		pcfg->pcm_cfg.frame_setting = AFE_PORT_PCM_BITS_PER_FRAME_128;
+		break;
+	case 16000:
+		pcfg->pcm_cfg.frame_setting = AFE_PORT_PCM_BITS_PER_FRAME_64;
+		break;
+	default:
+		dev_err(dev, "Unsupported sample rate\n");
+		return -EINVAL;
+	}
+	pcfg->pcm_cfg.ctrl_data_out_enable = AFE_PORT_PCM_CTRL_DATA_OE_DISABLE;
+	pcfg->pcm_cfg.reserved = 0;
+	pcfg->pcm_cfg.sample_rate = cfg->sample_rate;
+	pcfg->pcm_cfg.bit_width = 16;
+	pcfg->pcm_cfg.num_channels = 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(q6afe_pcm_port_prepare);
+
 /**
  * q6afe_i2s_port_prepare() - Prepare i2s afe port.
  *
@@ -1417,6 +1525,16 @@ struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 		cfg_type = AFE_PARAM_ID_I2S_CONFIG;
 		break;
+	case AFE_PORT_ID_PRIMARY_PCM_RX:
+	case AFE_PORT_ID_PRIMARY_PCM_TX:
+	case AFE_PORT_ID_SECONDARY_PCM_RX:
+	case AFE_PORT_ID_SECONDARY_PCM_TX:
+	case AFE_PORT_ID_TERTIARY_PCM_RX:
+	case AFE_PORT_ID_TERTIARY_PCM_TX:
+	case AFE_PORT_ID_QUATERNARY_PCM_RX:
+	case AFE_PORT_ID_QUATERNARY_PCM_TX:
+		cfg_type = AFE_PARAM_ID_PCM_CONFIG;
+		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX ... AFE_PORT_ID_QUINARY_TDM_TX_7:
 		cfg_type = AFE_PARAM_ID_TDM_CONFIG;
 		break;
diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h
index c7ed5422baff..d3b79e391e44 100644
--- a/sound/soc/qcom/qdsp6/q6afe.h
+++ b/sound/soc/qcom/qdsp6/q6afe.h
@@ -5,7 +5,7 @@
 
 #include <dt-bindings/sound/qcom,q6afe.h>
 
-#define AFE_PORT_MAX		105
+#define AFE_PORT_MAX		113
 
 #define MSM_AFE_PORT_TYPE_RX 0
 #define MSM_AFE_PORT_TYPE_TX 1
@@ -14,7 +14,9 @@
 #define Q6AFE_MAX_MI2S_LINES	4
 
 #define AFE_MAX_CHAN_COUNT	8
+#define AFE_MAX_PCM_SLOT_COUNT	4
 #define AFE_PORT_MAX_AUDIO_CHAN_CNT	0x8
+#define AFE_PORT_MAX_PCM_AUDIO_CHAN_CNT	0x4
 
 #define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
 #define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
@@ -170,6 +172,13 @@ struct q6afe_i2s_cfg {
 	int fmt;
 };
 
+struct q6afe_pcm_cfg {
+	u16	quantype;
+	u32	sample_rate;
+	u16	slot_number_mapping[AFE_MAX_PCM_SLOT_COUNT];
+	int fmt;
+};
+
 struct q6afe_tdm_cfg {
 	u16	num_channels;
 	u32	sample_rate;
@@ -188,6 +197,7 @@ struct q6afe_port_config {
 	struct q6afe_hdmi_cfg hdmi;
 	struct q6afe_slim_cfg slim;
 	struct q6afe_i2s_cfg i2s_cfg;
+	struct q6afe_pcm_cfg pcm_cfg;
 	struct q6afe_tdm_cfg tdm;
 };
 
@@ -203,6 +213,7 @@ void q6afe_hdmi_port_prepare(struct q6afe_port *port,
 void q6afe_slim_port_prepare(struct q6afe_port *port,
 			  struct q6afe_slim_cfg *cfg);
 int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg);
+int q6afe_pcm_port_prepare(struct q6afe_port *port, struct q6afe_pcm_cfg *cfg);
 void q6afe_tdm_port_prepare(struct q6afe_port *port, struct q6afe_tdm_cfg *cfg);
 
 int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
-- 
2.21.1


  parent reply	other threads:[~2020-02-12  1:52 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200212015222.8229-1-adam@serbinski.com>
2020-02-12  1:52 ` [PATCH v3 1/6] ASoC: qdsp6: dt-bindings: Add q6afe pcm dt binding Adam Serbinski
2020-02-12  1:52 ` Adam Serbinski [this message]
2020-02-12  1:52 ` [PATCH v3 3/6] ASoC: qdsp6: q6afe-dai: add support to pcm port dais Adam Serbinski
2020-02-12  9:52   ` Srinivas Kandagatla
2020-02-12  9:53     ` Srinivas Kandagatla
2020-02-12  1:52 ` [PATCH v3 4/6] ASoC: qdsp6: q6routing: add pcm port routing Adam Serbinski
2020-02-12  1:52 ` [PATCH v3 5/6] ASoC: qcom: apq8096: add support for primary and quaternary I2S/PCM Adam Serbinski
2020-02-12  1:52 ` [PATCH v3 6/6] ASoC: qdsp6: dt-bindings: Add q6afe pcm dt binding documentation Adam Serbinski
2020-02-12  9:59   ` Srinivas Kandagatla
2020-02-12 11:01     ` Adam Serbinski
2020-02-12 11:43       ` Srinivas Kandagatla
2020-02-12 12:07         ` Adam Serbinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200212015222.8229-3-adam@serbinski.com \
    --to=adam@serbinski.com \
    --cc=agross@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=bgoswami@codeaurora.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=perex@perex.cz \
    --cc=plai@codeaurora.org \
    --cc=robh+dt@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).