ASoC: msm: Add the support for 16kHz AUX PCM
There are use cases that 16kHz sample rate AUX PCM needed
besides 8kHz. Add the support so that the corresponding
sample rate dependent platform data is used to configure
the AUX PCM port.
Change-Id: I58715238cacdeea5e59b5e1693a34f005f289e0f
Signed-off-by: Kuirong Wang <kuirongw@codeaurora.org>
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 29a90e4..424edce 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -477,13 +477,24 @@
*/
struct msm_dai_auxpcm_pdata apq_auxpcm_pdata = {
.clk = "pcm_clk",
- .mode = AFE_PCM_CFG_MODE_PCM,
- .sync = AFE_PCM_CFG_SYNC_INT,
- .frame = AFE_PCM_CFG_FRM_256BPF,
- .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
- .slot = 0,
- .data = AFE_PCM_CFG_CDATAOE_MASTER,
- .pcm_clk_rate = 2048000,
+ .mode_8k = {
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 2048000,
+ },
+ .mode_16k = {
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 4096000,
+ }
};
struct platform_device apq_cpudai_auxpcm_rx = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index f1553b6..e474e36 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1892,13 +1892,24 @@
*/
struct msm_dai_auxpcm_pdata auxpcm_pdata = {
.clk = "pcm_clk",
- .mode = AFE_PCM_CFG_MODE_PCM,
- .sync = AFE_PCM_CFG_SYNC_INT,
- .frame = AFE_PCM_CFG_FRM_256BPF,
- .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
- .slot = 0,
- .data = AFE_PCM_CFG_CDATAOE_MASTER,
- .pcm_clk_rate = 2048000,
+ .mode_8k = {
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 2048000,
+ },
+ .mode_16k = {
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 4096000,
+ }
};
struct platform_device msm_cpudai_auxpcm_rx = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 8eb1580..3629490 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -448,13 +448,24 @@
*/
struct msm_dai_auxpcm_pdata auxpcm_pdata = {
.clk = "pcm_clk",
- .mode = AFE_PCM_CFG_MODE_PCM,
- .sync = AFE_PCM_CFG_SYNC_INT,
- .frame = AFE_PCM_CFG_FRM_256BPF,
- .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
- .slot = 0,
- .data = AFE_PCM_CFG_CDATAOE_MASTER,
- .pcm_clk_rate = 2048000,
+ .mode_8k = {
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 2048000,
+ },
+ .mode_16k = {
+ .mode = AFE_PCM_CFG_MODE_PCM,
+ .sync = AFE_PCM_CFG_SYNC_INT,
+ .frame = AFE_PCM_CFG_FRM_256BPF,
+ .quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+ .slot = 0,
+ .data = AFE_PCM_CFG_CDATAOE_MASTER,
+ .pcm_clk_rate = 4096000,
+ }
};
struct platform_device msm_cpudai_auxpcm_rx = {
diff --git a/include/sound/msm-dai-q6.h b/include/sound/msm-dai-q6.h
index 6328256..042aa6f 100644
--- a/include/sound/msm-dai-q6.h
+++ b/include/sound/msm-dai-q6.h
@@ -21,8 +21,7 @@
#define MSM_MI2S_CAP_RX 0
#define MSM_MI2S_CAP_TX 1
-struct msm_dai_auxpcm_pdata {
- const char *clk;
+struct msm_dai_auxpcm_config {
u16 mode;
u16 sync;
u16 frame;
@@ -36,4 +35,11 @@
u16 rx_sd_lines;
u16 tx_sd_lines;
};
+
+struct msm_dai_auxpcm_pdata {
+ const char *clk;
+ struct msm_dai_auxpcm_config mode_8k;
+ struct msm_dai_auxpcm_config mode_16k;
+};
+
#endif
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 6c44cba..a050771 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -256,21 +256,21 @@
{
.playback = {
.stream_name = "AUXPCM Hostless Playback",
- .rates = SNDRV_PCM_RATE_8000,
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 1,
.rate_min = 8000,
- .rate_max = 8000,
+ .rate_max = 16000,
},
.capture = {
.stream_name = "AUXPCM Hostless Capture",
- .rates = SNDRV_PCM_RATE_8000,
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 1,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 16000,
},
.ops = &msm_fe_dai_ops,
.name = "AUXPCM_HOSTLESS",
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index fb7756c..a62541a 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -532,17 +532,28 @@
}
dai_data->channels = params_channels(params);
- if (params_rate(params) != 8000) {
- dev_err(dai->dev, "AUX PCM supports only 8KHz sampling rate\n");
+ dai_data->rate = params_rate(params);
+ switch (dai_data->rate) {
+ case 8000:
+ dai_data->port_config.pcm.mode = auxpcm_pdata->mode_8k.mode;
+ dai_data->port_config.pcm.sync = auxpcm_pdata->mode_8k.sync;
+ dai_data->port_config.pcm.frame = auxpcm_pdata->mode_8k.frame;
+ dai_data->port_config.pcm.quant = auxpcm_pdata->mode_8k.quant;
+ dai_data->port_config.pcm.slot = auxpcm_pdata->mode_8k.slot;
+ dai_data->port_config.pcm.data = auxpcm_pdata->mode_8k.data;
+ break;
+ case 16000:
+ dai_data->port_config.pcm.mode = auxpcm_pdata->mode_16k.mode;
+ dai_data->port_config.pcm.sync = auxpcm_pdata->mode_16k.sync;
+ dai_data->port_config.pcm.frame = auxpcm_pdata->mode_16k.frame;
+ dai_data->port_config.pcm.quant = auxpcm_pdata->mode_16k.quant;
+ dai_data->port_config.pcm.slot = auxpcm_pdata->mode_16k.slot;
+ dai_data->port_config.pcm.data = auxpcm_pdata->mode_16k.data;
+ break;
+ default:
+ dev_err(dai->dev, "AUX PCM supports only 8kHz and 16kHz sampling rate\n");
return -EINVAL;
}
- dai_data->rate = params_rate(params);
- dai_data->port_config.pcm.mode = auxpcm_pdata->mode;
- dai_data->port_config.pcm.sync = auxpcm_pdata->sync;
- dai_data->port_config.pcm.frame = auxpcm_pdata->frame;
- dai_data->port_config.pcm.quant = auxpcm_pdata->quant;
- dai_data->port_config.pcm.slot = auxpcm_pdata->slot;
- dai_data->port_config.pcm.data = auxpcm_pdata->data;
return 0;
}
@@ -702,9 +713,9 @@
{
struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
int rc = 0;
-
struct msm_dai_auxpcm_pdata *auxpcm_pdata =
(struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
+ unsigned long pcm_clk_rate;
mutex_lock(&aux_pcm_mutex);
@@ -753,8 +764,17 @@
afe_open(PCM_RX, &dai_data->port_config, dai_data->rate);
afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
+ if (dai_data->rate == 8000) {
+ pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate;
+ } else if (dai_data->rate == 16000) {
+ pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate;
+ } else {
+ dev_err(dai->dev, "%s: Invalid AUX PCM rate %d\n", __func__,
+ dai_data->rate);
+ return -EINVAL;
+ }
- rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate);
+ rc = clk_set_rate(pcm_clk, pcm_clk_rate);
if (rc < 0) {
pr_err("%s: clk_set_rate failed\n", __func__);
return rc;
@@ -1377,11 +1397,11 @@
static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_rx_dai = {
.playback = {
- .rates = SNDRV_PCM_RATE_8000,
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 1,
- .rate_max = 8000,
+ .rate_max = 16000,
.rate_min = 8000,
},
.ops = &msm_dai_q6_auxpcm_ops,
@@ -1391,11 +1411,11 @@
static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_tx_dai = {
.capture = {
- .rates = SNDRV_PCM_RATE_8000,
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 1,
- .rate_max = 8000,
+ .rate_max = 16000,
.rate_min = 8000,
},
.ops = &msm_dai_q6_auxpcm_ops,