summaryrefslogtreecommitdiff
path: root/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/Kconfig1
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c32
-rw-r--r--sound/soc/fsl/fsl_aud2htx.c2
-rw-r--r--sound/soc/fsl/fsl_easrc.c2
-rw-r--r--sound/soc/fsl/fsl_esai.c4
-rw-r--r--sound/soc/fsl/fsl_micfil.c132
-rw-r--r--sound/soc/fsl/fsl_mqs.c41
-rw-r--r--sound/soc/fsl/fsl_qmc_audio.c2
-rw-r--r--sound/soc/fsl/fsl_sai.c5
-rw-r--r--sound/soc/fsl/fsl_sai.h1
-rw-r--r--sound/soc/fsl/fsl_xcvr.c94
-rw-r--r--sound/soc/fsl/fsl_xcvr.h5
-rw-r--r--sound/soc/fsl/imx-audmix.c18
-rw-r--r--sound/soc/fsl/imx-card.c70
14 files changed, 338 insertions, 71 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index e283751abfef..8e88830e8e57 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -30,6 +30,7 @@ config SND_SOC_FSL_MQS
tristate "Medium Quality Sound (MQS) module support"
depends on SND_SOC_FSL_SAI
select REGMAP_MMIO
+ select IMX_SCMI_MISC_DRV if IMX_SCMI_MISC_EXT !=n
help
Say Y if you want to add Medium Quality Sound (MQS)
support for the Freescale CPUs.
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index f6c3aeff0d8e..02e1594e8223 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -317,8 +317,6 @@ static const struct snd_soc_dai_link fsl_asoc_card_dai[] = {
{
.name = "HiFi-ASRC-FE",
.stream_name = "HiFi-ASRC-FE",
- .dpcm_playback = 1,
- .dpcm_capture = 1,
.dynamic = 1,
},
{
@@ -326,8 +324,6 @@ static const struct snd_soc_dai_link fsl_asoc_card_dai[] = {
.stream_name = "HiFi-ASRC-BE",
.be_hw_params_fixup = be_hw_params_fixup,
.ops = &fsl_asoc_card_ops,
- .dpcm_playback = 1,
- .dpcm_capture = 1,
.no_pcm = 1,
},
};
@@ -504,13 +500,13 @@ static int fsl_asoc_card_spdif_init(struct device_node *codec_np[],
}
if (priv->dai_link[0].playback_only) {
- priv->dai_link[1].dpcm_capture = false;
- priv->dai_link[2].dpcm_capture = false;
+ priv->dai_link[1].playback_only = true;
+ priv->dai_link[2].playback_only = true;
priv->card.dapm_routes = audio_map_tx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else if (priv->dai_link[0].capture_only) {
- priv->dai_link[1].dpcm_playback = false;
- priv->dai_link[2].dpcm_playback = false;
+ priv->dai_link[1].capture_only = true;
+ priv->dai_link[2].capture_only = true;
priv->card.dapm_routes = audio_map_rx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_rx);
}
@@ -764,8 +760,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
} else if (of_device_is_compatible(np, "fsl,imx-audio-tlv320aic31xx")) {
codec_dai_name[0] = "tlv320dac31xx-hifi";
priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
- priv->dai_link[1].dpcm_capture = 0;
- priv->dai_link[2].dpcm_capture = 0;
+ priv->dai_link[1].playback_only = 1;
+ priv->dai_link[2].playback_only = 1;
priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT;
priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
priv->card.dapm_routes = audio_map_tx;
@@ -791,15 +787,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
SND_SOC_DAIFMT_CBC_CFC |
SND_SOC_DAIFMT_NB_NF;
- priv->dai_link[1].dpcm_capture = 0;
- priv->dai_link[2].dpcm_capture = 0;
+ priv->dai_link[1].playback_only = 1;
+ priv->dai_link[2].playback_only = 1;
priv->card.dapm_routes = audio_map_tx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else if (of_device_is_compatible(np, "fsl,imx-audio-wm8524")) {
codec_dai_name[0] = "wm8524-hifi";
priv->dai_fmt |= SND_SOC_DAIFMT_CBC_CFC;
- priv->dai_link[1].dpcm_capture = 0;
- priv->dai_link[2].dpcm_capture = 0;
+ priv->dai_link[1].playback_only = 1;
+ priv->dai_link[2].playback_only = 1;
priv->cpu_priv.slot_width = 32;
priv->card.dapm_routes = audio_map_tx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
@@ -1033,14 +1029,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
}
/*
- * Properties "hp-det-gpio" and "mic-det-gpio" are optional, and
+ * Properties "hp-det-gpios" and "mic-det-gpios" are optional, and
* simple_util_init_jack() uses these properties for creating
* Headphone Jack and Microphone Jack.
*
* The notifier is initialized in snd_soc_card_jack_new(), then
* snd_soc_jack_notifier_register can be called.
*/
- if (of_property_read_bool(np, "hp-det-gpio")) {
+ if (of_property_read_bool(np, "hp-det-gpios") ||
+ of_property_read_bool(np, "hp-det-gpio") /* deprecated */) {
ret = simple_util_init_jack(&priv->card, &priv->hp_jack,
1, NULL, "Headphone Jack");
if (ret)
@@ -1049,7 +1046,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
snd_soc_jack_notifier_register(&priv->hp_jack.jack, &hp_jack_nb);
}
- if (of_property_read_bool(np, "mic-det-gpio")) {
+ if (of_property_read_bool(np, "mic-det-gpios") ||
+ of_property_read_bool(np, "mic-det-gpio") /* deprecated */) {
ret = simple_util_init_jack(&priv->card, &priv->mic_jack,
0, NULL, "Mic Jack");
if (ret)
diff --git a/sound/soc/fsl/fsl_aud2htx.c b/sound/soc/fsl/fsl_aud2htx.c
index 021d73e409aa..bde642318835 100644
--- a/sound/soc/fsl/fsl_aud2htx.c
+++ b/sound/soc/fsl/fsl_aud2htx.c
@@ -169,7 +169,7 @@ static const struct regmap_config fsl_aud2htx_regmap_config = {
.readable_reg = fsl_aud2htx_readable_reg,
.volatile_reg = fsl_aud2htx_volatile_reg,
.writeable_reg = fsl_aud2htx_writeable_reg,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static const struct of_device_id fsl_aud2htx_dt_ids[] = {
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 82359edd6a8b..d22f0621c465 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1748,7 +1748,7 @@ static const struct regmap_config fsl_easrc_regmap_config = {
.rd_table = &fsl_easrc_readable_table,
.wr_table = &fsl_easrc_writeable_table,
.volatile_table = &fsl_easrc_volatileable_table,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
#ifdef DEBUG
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index a65f5b9935a2..0b247f16a163 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -119,10 +119,10 @@ static irqreturn_t esai_isr(int irq, void *devid)
dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
if (esr & ESAI_ESR_RFF_MASK)
- dev_warn(&pdev->dev, "isr: Receiving overrun\n");
+ dev_dbg(&pdev->dev, "isr: Receiving overrun\n");
if (esr & ESAI_ESR_TFE_MASK)
- dev_warn(&pdev->dev, "isr: Transmission underrun\n");
+ dev_dbg(&pdev->dev, "isr: Transmission underrun\n");
if (esr & ESAI_ESR_TLS_MASK)
dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 193be098fa5e..8c15389c9a04 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -28,6 +28,13 @@
#define MICFIL_OSR_DEFAULT 16
+#define MICFIL_NUM_RATES 7
+#define MICFIL_CLK_SRC_NUM 3
+/* clock source ids */
+#define MICFIL_AUDIO_PLL1 0
+#define MICFIL_AUDIO_PLL2 1
+#define MICFIL_CLK_EXT3 2
+
enum quality {
QUALITY_HIGH,
QUALITY_MEDIUM,
@@ -45,9 +52,12 @@ struct fsl_micfil {
struct clk *mclk;
struct clk *pll8k_clk;
struct clk *pll11k_clk;
+ struct clk *clk_src[MICFIL_CLK_SRC_NUM];
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct sdma_peripheral_config sdmacfg;
struct snd_soc_card *card;
+ struct snd_pcm_hw_constraint_list constraint_rates;
+ unsigned int constraint_rates_list[MICFIL_NUM_RATES];
unsigned int dataline;
char name[32];
int irq[MICFIL_IRQ_LINES];
@@ -58,6 +68,7 @@ struct fsl_micfil {
int vad_detected;
struct fsl_micfil_verid verid;
struct fsl_micfil_param param;
+ bool mclk_flag; /* mclk enable flag */
};
struct fsl_micfil_soc_data {
@@ -67,6 +78,7 @@ struct fsl_micfil_soc_data {
bool imx;
bool use_edma;
bool use_verid;
+ bool volume_sx;
u64 formats;
};
@@ -76,6 +88,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mm = {
.fifo_depth = 8,
.dataline = 0xf,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .volume_sx = true,
};
static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
@@ -84,6 +97,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
.fifo_depth = 32,
.dataline = 0xf,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .volume_sx = false,
};
static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
@@ -94,6 +108,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.use_edma = true,
.use_verid = true,
+ .volume_sx = false,
};
static const struct of_device_id fsl_micfil_dt_ids[] = {
@@ -317,7 +332,26 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
+static const struct snd_kcontrol_new fsl_micfil_volume_controls[] = {
+ SOC_SINGLE_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, gain_tlv),
+ SOC_SINGLE_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
+ MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, gain_tlv),
+};
+
+static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = {
SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv),
SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
@@ -334,6 +368,9 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv),
SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv),
+};
+
+static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
SOC_ENUM_EXT("MICFIL Quality Select",
fsl_micfil_quality_enum,
micfil_quality_get, micfil_quality_set),
@@ -449,12 +486,34 @@ static int fsl_micfil_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+ unsigned int rates[MICFIL_NUM_RATES] = {8000, 11025, 16000, 22050, 32000, 44100, 48000};
+ int i, j, k = 0;
+ u64 clk_rate;
if (!micfil) {
dev_err(dai->dev, "micfil dai priv_data not set\n");
return -EINVAL;
}
+ micfil->constraint_rates.list = micfil->constraint_rates_list;
+ micfil->constraint_rates.count = 0;
+
+ for (j = 0; j < MICFIL_NUM_RATES; j++) {
+ for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) {
+ clk_rate = clk_get_rate(micfil->clk_src[i]);
+ if (clk_rate != 0 && do_div(clk_rate, rates[j]) == 0) {
+ micfil->constraint_rates_list[k++] = rates[j];
+ micfil->constraint_rates.count++;
+ break;
+ }
+ }
+ }
+
+ if (micfil->constraint_rates.count > 0)
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &micfil->constraint_rates);
+
return 0;
}
@@ -650,7 +709,7 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
/* Enable the module */
ret = regmap_set_bits(micfil->regmap, REG_MICFIL_CTRL1,
- MICFIL_CTRL1_PDMIEN);
+ MICFIL_CTRL1_PDMIEN | MICFIL_CTRL1_ERREN);
if (ret)
return ret;
@@ -666,7 +725,7 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
/* Disable the module */
ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
- MICFIL_CTRL1_PDMIEN);
+ MICFIL_CTRL1_PDMIEN | MICFIL_CTRL1_ERREN);
if (ret)
return ret;
@@ -693,7 +752,6 @@ static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int s
clk = micfil->mclk;
/* Disable clock first, for it was enabled by pm_runtime */
- clk_disable_unprepare(clk);
fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk,
micfil->pll11k_clk, ratio);
ret = clk_prepare_enable(clk);
@@ -730,6 +788,8 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
if (ret)
return ret;
+ micfil->mclk_flag = true;
+
ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8);
if (ret)
return ret;
@@ -764,6 +824,17 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
return 0;
}
+static int fsl_micfil_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+
+ clk_disable_unprepare(micfil->mclk);
+ micfil->mclk_flag = false;
+
+ return 0;
+}
+
static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
{
struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
@@ -801,11 +872,26 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
return 0;
}
+static int fsl_micfil_component_probe(struct snd_soc_component *component)
+{
+ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(component);
+
+ if (micfil->soc->volume_sx)
+ snd_soc_add_component_controls(component, fsl_micfil_volume_sx_controls,
+ ARRAY_SIZE(fsl_micfil_volume_sx_controls));
+ else
+ snd_soc_add_component_controls(component, fsl_micfil_volume_controls,
+ ARRAY_SIZE(fsl_micfil_volume_controls));
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
.probe = fsl_micfil_dai_probe,
.startup = fsl_micfil_startup,
.trigger = fsl_micfil_trigger,
.hw_params = fsl_micfil_hw_params,
+ .hw_free = fsl_micfil_hw_free,
};
static struct snd_soc_dai_driver fsl_micfil_dai = {
@@ -821,6 +907,7 @@ static struct snd_soc_dai_driver fsl_micfil_dai = {
static const struct snd_soc_component_driver fsl_micfil_component = {
.name = "fsl-micfil-dai",
+ .probe = fsl_micfil_component_probe,
.controls = fsl_micfil_snd_controls,
.num_controls = ARRAY_SIZE(fsl_micfil_snd_controls),
.legacy_dai_naming = 1,
@@ -926,6 +1013,7 @@ static bool fsl_micfil_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case REG_MICFIL_STAT:
+ case REG_MICFIL_FIFO_STAT:
case REG_MICFIL_DATACH0:
case REG_MICFIL_DATACH1:
case REG_MICFIL_DATACH2:
@@ -934,6 +1022,7 @@ static bool fsl_micfil_volatile_reg(struct device *dev, unsigned int reg)
case REG_MICFIL_DATACH5:
case REG_MICFIL_DATACH6:
case REG_MICFIL_DATACH7:
+ case REG_MICFIL_OUT_STAT:
case REG_MICFIL_VERID:
case REG_MICFIL_PARAM:
case REG_MICFIL_VAD0_STAT:
@@ -955,7 +1044,7 @@ static const struct regmap_config fsl_micfil_regmap_config = {
.readable_reg = fsl_micfil_readable_reg,
.volatile_reg = fsl_micfil_volatile_reg,
.writeable_reg = fsl_micfil_writeable_reg,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/* END OF REGMAP */
@@ -988,7 +1077,7 @@ static irqreturn_t micfil_isr(int irq, void *devid)
regmap_write_bits(micfil->regmap,
REG_MICFIL_STAT,
MICFIL_STAT_CHXF(i),
- 1);
+ MICFIL_STAT_CHXF(i));
}
for (i = 0; i < MICFIL_FIFO_NUM; i++) {
@@ -1010,6 +1099,8 @@ static irqreturn_t micfil_err_isr(int irq, void *devid)
{
struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
struct platform_device *pdev = micfil->pdev;
+ u32 fifo_stat_reg;
+ u32 out_stat_reg;
u32 stat_reg;
regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg);
@@ -1023,9 +1114,17 @@ static irqreturn_t micfil_err_isr(int irq, void *devid)
if (stat_reg & MICFIL_STAT_LOWFREQF) {
dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n");
regmap_write_bits(micfil->regmap, REG_MICFIL_STAT,
- MICFIL_STAT_LOWFREQF, 1);
+ MICFIL_STAT_LOWFREQF, MICFIL_STAT_LOWFREQF);
}
+ regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg);
+ regmap_write_bits(micfil->regmap, REG_MICFIL_FIFO_STAT,
+ fifo_stat_reg, fifo_stat_reg);
+
+ regmap_read(micfil->regmap, REG_MICFIL_OUT_STAT, &out_stat_reg);
+ regmap_write_bits(micfil->regmap, REG_MICFIL_OUT_STAT,
+ out_stat_reg, out_stat_reg);
+
return IRQ_HANDLED;
}
@@ -1134,6 +1233,12 @@ static int fsl_micfil_probe(struct platform_device *pdev)
fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk,
&micfil->pll11k_clk);
+ micfil->clk_src[MICFIL_AUDIO_PLL1] = micfil->pll8k_clk;
+ micfil->clk_src[MICFIL_AUDIO_PLL2] = micfil->pll11k_clk;
+ micfil->clk_src[MICFIL_CLK_EXT3] = devm_clk_get(&pdev->dev, "clkext3");
+ if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3]))
+ micfil->clk_src[MICFIL_CLK_EXT3] = NULL;
+
/* init regmap */
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(regs))
@@ -1279,7 +1384,8 @@ static int fsl_micfil_runtime_suspend(struct device *dev)
regcache_cache_only(micfil->regmap, true);
- clk_disable_unprepare(micfil->mclk);
+ if (micfil->mclk_flag)
+ clk_disable_unprepare(micfil->mclk);
clk_disable_unprepare(micfil->busclk);
return 0;
@@ -1294,10 +1400,12 @@ static int fsl_micfil_runtime_resume(struct device *dev)
if (ret < 0)
return ret;
- ret = clk_prepare_enable(micfil->mclk);
- if (ret < 0) {
- clk_disable_unprepare(micfil->busclk);
- return ret;
+ if (micfil->mclk_flag) {
+ ret = clk_prepare_enable(micfil->mclk);
+ if (ret < 0) {
+ clk_disable_unprepare(micfil->busclk);
+ return ret;
+ }
}
regcache_cache_only(micfil->regmap, false);
diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
index 145f9ca15e43..0513e9e8402e 100644
--- a/sound/soc/fsl/fsl_mqs.c
+++ b/sound/soc/fsl/fsl_mqs.c
@@ -6,6 +6,7 @@
// Copyright 2019 NXP
#include <linux/clk.h>
+#include <linux/firmware/imx/sm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/mfd/syscon.h>
@@ -74,6 +75,29 @@ struct fsl_mqs {
#define FSL_MQS_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
#define FSL_MQS_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+static int fsl_mqs_sm_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct fsl_mqs *mqs_priv = context;
+ int num = 1;
+
+ if (IS_ENABLED(CONFIG_IMX_SCMI_MISC_DRV) &&
+ mqs_priv->soc->ctrl_off == reg)
+ return scmi_imx_misc_ctrl_get(SCMI_IMX_CTRL_MQS1_SETTINGS, &num, val);
+
+ return -EINVAL;
+};
+
+static int fsl_mqs_sm_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct fsl_mqs *mqs_priv = context;
+
+ if (IS_ENABLED(CONFIG_IMX_SCMI_MISC_DRV) &&
+ mqs_priv->soc->ctrl_off == reg)
+ return scmi_imx_misc_ctrl_set(SCMI_IMX_CTRL_MQS1_SETTINGS, val);
+
+ return -EINVAL;
+};
+
static int fsl_mqs_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -188,6 +212,13 @@ static const struct regmap_config fsl_mqs_regmap_config = {
.cache_type = REGCACHE_NONE,
};
+static const struct regmap_config fsl_mqs_sm_regmap = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_read = fsl_mqs_sm_read,
+ .reg_write = fsl_mqs_sm_write,
+};
+
static int fsl_mqs_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -219,6 +250,16 @@ static int fsl_mqs_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to get gpr regmap\n");
return PTR_ERR(mqs_priv->regmap);
}
+ } else if (mqs_priv->soc->type == TYPE_REG_SM) {
+ mqs_priv->regmap = devm_regmap_init(&pdev->dev,
+ NULL,
+ mqs_priv,
+ &fsl_mqs_sm_regmap);
+ if (IS_ERR(mqs_priv->regmap)) {
+ dev_err(&pdev->dev, "failed to init regmap: %ld\n",
+ PTR_ERR(mqs_priv->regmap));
+ return PTR_ERR(mqs_priv->regmap);
+ }
} else {
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index 8668abd35208..e257b8adafe0 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -838,8 +838,6 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *
qmc_dai->id, i, ret);
return ret;
}
- dev_info(qmc_audio->dev, "dai %d QMC channel %d mode %d, nb_tx_ts %u, nb_rx_ts %u\n",
- qmc_dai->id, i, info.mode, info.nb_tx_ts, info.nb_rx_ts);
if (info.mode != QMC_TRANSPARENT) {
dev_err(qmc_audio->dev, "dai %d QMC chan %d mode %d is not QMC_TRANSPARENT\n",
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index ab58a4461073..634168d2bb6e 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -613,6 +613,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
+ /* Set to avoid channel swap */
+ val_cr4 |= FSL_SAI_CR4_FCONT;
+
/* Set to output mode to avoid tri-stated data pins */
if (tx)
val_cr4 |= FSL_SAI_CR4_CHMOD;
@@ -699,7 +702,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
- FSL_SAI_CR4_CHMOD_MASK,
+ FSL_SAI_CR4_CHMOD_MASK | FSL_SAI_CR4_FCONT_MASK,
val_cr4);
regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index dadbd16ee394..9c4d19fe22c6 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -137,6 +137,7 @@
/* SAI Transmit and Receive Configuration 4 Register */
+#define FSL_SAI_CR4_FCONT_MASK BIT(28)
#define FSL_SAI_CR4_FCONT BIT(28)
#define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
#define FSL_SAI_CR4_FCOMB_SOFT BIT(27)
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index beede7344efd..1e0bfd59d511 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -53,6 +53,8 @@ struct fsl_xcvr {
struct snd_aes_iec958 rx_iec958;
struct snd_aes_iec958 tx_iec958;
u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
+ struct work_struct work_rst;
+ spinlock_t lock; /* Protect hw_reset and trigger */
};
static const struct fsl_xcvr_pll_conf {
@@ -663,7 +665,10 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- int ret;
+ unsigned long lock_flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&xcvr->lock, lock_flags);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -675,7 +680,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_EXT_CTRL_DPTH_RESET(tx));
if (ret < 0) {
dev_err(dai->dev, "Failed to set DPATH RESET: %d\n", ret);
- return ret;
+ goto release_lock;
}
if (tx) {
@@ -687,7 +692,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_ISR_CMDC_TX_EN);
if (ret < 0) {
dev_err(dai->dev, "err updating isr %d\n", ret);
- return ret;
+ goto release_lock;
}
fallthrough;
case FSL_XCVR_MODE_SPDIF:
@@ -696,7 +701,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
if (ret < 0) {
dev_err(dai->dev, "Failed to start DATA_TX: %d\n", ret);
- return ret;
+ goto release_lock;
}
break;
}
@@ -707,14 +712,14 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_EXT_CTRL_DMA_DIS(tx), 0);
if (ret < 0) {
dev_err(dai->dev, "Failed to enable DMA: %d\n", ret);
- return ret;
+ goto release_lock;
}
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
FSL_XCVR_IRQ_EARC_ALL, FSL_XCVR_IRQ_EARC_ALL);
if (ret < 0) {
dev_err(dai->dev, "Error while setting IER0: %d\n", ret);
- return ret;
+ goto release_lock;
}
/* clear DPATH RESET */
@@ -723,7 +728,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
0);
if (ret < 0) {
dev_err(dai->dev, "Failed to clear DPATH RESET: %d\n", ret);
- return ret;
+ goto release_lock;
}
break;
@@ -736,14 +741,14 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_EXT_CTRL_DMA_DIS(tx));
if (ret < 0) {
dev_err(dai->dev, "Failed to disable DMA: %d\n", ret);
- return ret;
+ goto release_lock;
}
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
FSL_XCVR_IRQ_EARC_ALL, 0);
if (ret < 0) {
dev_err(dai->dev, "Failed to clear IER0: %d\n", ret);
- return ret;
+ goto release_lock;
}
if (tx) {
@@ -754,7 +759,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
if (ret < 0) {
dev_err(dai->dev, "Failed to stop DATA_TX: %d\n", ret);
- return ret;
+ goto release_lock;
}
if (xcvr->soc_data->spdif_only)
break;
@@ -768,17 +773,20 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
if (ret < 0) {
dev_err(dai->dev,
"Err updating ISR %d\n", ret);
- return ret;
+ goto release_lock;
}
break;
}
}
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
}
- return 0;
+release_lock:
+ spin_unlock_irqrestore(&xcvr->lock, lock_flags);
+ return ret;
}
static int fsl_xcvr_load_firmware(struct fsl_xcvr *xcvr)
@@ -1198,6 +1206,34 @@ static const struct regmap_config fsl_xcvr_regmap_cfg = {
.cache_type = REGCACHE_FLAT,
};
+static void reset_rx_work(struct work_struct *work)
+{
+ struct fsl_xcvr *xcvr = container_of(work, struct fsl_xcvr, work_rst);
+ struct device *dev = &xcvr->pdev->dev;
+ unsigned long lock_flags;
+ u32 ext_ctrl;
+
+ dev_dbg(dev, "reset rx path\n");
+ spin_lock_irqsave(&xcvr->lock, lock_flags);
+ regmap_read(xcvr->regmap, FSL_XCVR_EXT_CTRL, &ext_ctrl);
+
+ if (!(ext_ctrl & FSL_XCVR_EXT_CTRL_DMA_RD_DIS)) {
+ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
+ FSL_XCVR_EXT_CTRL_DMA_RD_DIS,
+ FSL_XCVR_EXT_CTRL_DMA_RD_DIS);
+ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
+ FSL_XCVR_EXT_CTRL_RX_DPTH_RESET,
+ FSL_XCVR_EXT_CTRL_RX_DPTH_RESET);
+ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
+ FSL_XCVR_EXT_CTRL_DMA_RD_DIS,
+ 0);
+ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
+ FSL_XCVR_EXT_CTRL_RX_DPTH_RESET,
+ 0);
+ }
+ spin_unlock_irqrestore(&xcvr->lock, lock_flags);
+}
+
static irqreturn_t irq0_isr(int irq, void *devid)
{
struct fsl_xcvr *xcvr = (struct fsl_xcvr *)devid;
@@ -1265,6 +1301,33 @@ static irqreturn_t irq0_isr(int irq, void *devid)
dev_dbg(dev, "DMA write request\n");
isr_clr |= FSL_XCVR_IRQ_DMA_WR_REQ;
}
+ if (isr & FSL_XCVR_IRQ_CMDC_STATUS_UPD) {
+ dev_dbg(dev, "CMDC status update\n");
+ isr_clr |= FSL_XCVR_IRQ_CMDC_STATUS_UPD;
+ }
+ if (isr & FSL_XCVR_IRQ_PREAMBLE_MISMATCH) {
+ dev_dbg(dev, "Preamble mismatch\n");
+ isr_clr |= FSL_XCVR_IRQ_PREAMBLE_MISMATCH;
+ }
+ if (isr & FSL_XCVR_IRQ_UNEXP_PRE_REC) {
+ dev_dbg(dev, "Unexpected preamble received\n");
+ isr_clr |= FSL_XCVR_IRQ_UNEXP_PRE_REC;
+ }
+ if (isr & FSL_XCVR_IRQ_M_W_PRE_MISMATCH) {
+ dev_dbg(dev, "M/W preamble mismatch\n");
+ isr_clr |= FSL_XCVR_IRQ_M_W_PRE_MISMATCH;
+ }
+ if (isr & FSL_XCVR_IRQ_B_PRE_MISMATCH) {
+ dev_dbg(dev, "B preamble mismatch\n");
+ isr_clr |= FSL_XCVR_IRQ_B_PRE_MISMATCH;
+ }
+
+ if (isr & (FSL_XCVR_IRQ_PREAMBLE_MISMATCH |
+ FSL_XCVR_IRQ_UNEXP_PRE_REC |
+ FSL_XCVR_IRQ_M_W_PRE_MISMATCH |
+ FSL_XCVR_IRQ_B_PRE_MISMATCH)) {
+ schedule_work(&xcvr->work_rst);
+ }
if (isr_clr) {
regmap_write(regmap, FSL_XCVR_EXT_ISR_CLR, isr_clr);
@@ -1411,11 +1474,16 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
fsl_xcvr_comp.name);
}
+ INIT_WORK(&xcvr->work_rst, reset_rx_work);
+ spin_lock_init(&xcvr->lock);
return ret;
}
static void fsl_xcvr_remove(struct platform_device *pdev)
{
+ struct fsl_xcvr *xcvr = dev_get_drvdata(&pdev->dev);
+
+ cancel_work_sync(&xcvr->work_rst);
pm_runtime_disable(&pdev->dev);
}
diff --git a/sound/soc/fsl/fsl_xcvr.h b/sound/soc/fsl/fsl_xcvr.h
index 882428592e1a..c72cb05184df 100644
--- a/sound/soc/fsl/fsl_xcvr.h
+++ b/sound/soc/fsl/fsl_xcvr.h
@@ -165,6 +165,11 @@
FSL_XCVR_IRQ_MUTE | \
FSL_XCVR_IRQ_FIFO_UOFL_ERR | \
FSL_XCVR_IRQ_HOST_WAKEUP | \
+ FSL_XCVR_IRQ_CMDC_STATUS_UPD |\
+ FSL_XCVR_IRQ_B_PRE_MISMATCH |\
+ FSL_XCVR_IRQ_M_W_PRE_MISMATCH |\
+ FSL_XCVR_IRQ_PREAMBLE_MISMATCH |\
+ FSL_XCVR_IRQ_UNEXP_PRE_REC |\
FSL_XCVR_IRQ_ARC_MODE)
#define FSL_XCVR_ISR_CMDC_TX_EN BIT(3)
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
index 6fbcf33fd0de..dcf770b55c4b 100644
--- a/sound/soc/fsl/imx-audmix.c
+++ b/sound/soc/fsl/imx-audmix.c
@@ -264,11 +264,10 @@ static int imx_audmix_probe(struct platform_device *pdev)
priv->dai[i].cpus->dai_name = name[1][i];
priv->dai[i].dynamic = 1;
- priv->dai[i].dpcm_playback = 1;
- if (i == num_dai - 1) {
- priv->dai[i].dpcm_capture = 1;
- priv->dai[i].dpcm_playback = 0;
- }
+ if (i == num_dai - 1)
+ priv->dai[i].capture_only = 1;
+ else
+ priv->dai[i].playback_only = 1;
priv->dai[i].ignore_pmdown_time = 1;
priv->dai[i].ops = &imx_audmix_fe_ops;
@@ -285,11 +284,10 @@ static int imx_audmix_probe(struct platform_device *pdev)
priv->dai[num_dai + i].cpus->of_node = audmix_np;
priv->dai[num_dai + i].cpus->dai_name = be_name;
priv->dai[num_dai + i].no_pcm = 1;
- priv->dai[num_dai + i].dpcm_playback = 1;
- if (i == num_dai - 1) {
- priv->dai[num_dai + i].dpcm_capture = 1;
- priv->dai[num_dai + i].dpcm_playback = 0;
- }
+ if (i == num_dai - 1)
+ priv->dai[num_dai + i].capture_only = 1;
+ else
+ priv->dai[num_dai + i].playback_only = 1;
priv->dai[num_dai + i].ignore_pmdown_time = 1;
priv->dai[num_dai + i].ops = &imx_audmix_be_ops;
diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
index 98b37dd2b901..95a57fda0250 100644
--- a/sound/soc/fsl/imx-card.c
+++ b/sound/soc/fsl/imx-card.c
@@ -25,6 +25,7 @@ enum codec_type {
CODEC_AK4458,
CODEC_AK4497,
CODEC_AK5552,
+ CODEC_CS42888,
};
/*
@@ -185,6 +186,16 @@ static struct imx_akcodec_tdm_fs_mul ak5558_tdm_fs_mul[] = {
{ .min = 512, .max = 512, .mul = 1024 },
};
+static struct imx_akcodec_fs_mul cs42888_fs_mul[] = {
+ { .rmin = 8000, .rmax = 48000, .wmin = 256, .wmax = 1024, },
+ { .rmin = 64000, .rmax = 96000, .wmin = 128, .wmax = 512, },
+ { .rmin = 176400, .rmax = 192000, .wmin = 64, .wmax = 256, },
+};
+
+static struct imx_akcodec_tdm_fs_mul cs42888_tdm_fs_mul[] = {
+ { .min = 256, .max = 256, .mul = 256 },
+};
+
static const u32 akcodec_rates[] = {
8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
96000, 176400, 192000, 352800, 384000, 705600, 768000,
@@ -210,6 +221,14 @@ static const u32 ak5558_tdm_channels[] = {
1, 2, 3, 4, 5, 6, 7, 8,
};
+static const u32 cs42888_channels[] = {
+ 1, 2, 4, 6, 8,
+};
+
+static const u32 cs42888_tdm_channels[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+};
+
static bool format_is_dsd(struct snd_pcm_hw_params *params)
{
snd_pcm_format_t format = params_format(params);
@@ -241,6 +260,7 @@ static bool codec_is_akcodec(unsigned int type)
case CODEC_AK4497:
case CODEC_AK5558:
case CODEC_AK5552:
+ case CODEC_CS42888:
return true;
default:
break;
@@ -255,7 +275,7 @@ static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card);
const struct imx_card_plat_data *plat_data = data->plat_data;
- struct dai_link_data *link_data = &data->link_data[rtd->num];
+ struct dai_link_data *link_data = &data->link_data[rtd->id];
unsigned int width = slots * slot_width;
unsigned int rate = params_rate(params);
int i;
@@ -293,7 +313,7 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_card *card = rtd->card;
struct imx_card_data *data = snd_soc_card_get_drvdata(card);
- struct dai_link_data *link_data = &data->link_data[rtd->num];
+ struct dai_link_data *link_data = &data->link_data[rtd->id];
struct imx_card_plat_data *plat_data = data->plat_data;
struct device *dev = card->dev;
struct snd_soc_dai *codec_dai;
@@ -340,13 +360,15 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- ret = snd_soc_dai_set_tdm_slot(codec_dai,
- BIT(slots) - 1,
- BIT(slots) - 1,
- slots, slot_width);
- if (ret && ret != -ENOTSUPP) {
- dev_err(dev, "failed to set codec dai[%d] tdm slot: %d\n", i, ret);
- return ret;
+ if (format_is_tdm(link_data)) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ BIT(slots) - 1,
+ BIT(slots) - 1,
+ slots, slot_width);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(dev, "failed to set codec dai[%d] tdm slot: %d\n", i, ret);
+ return ret;
+ }
}
}
@@ -370,6 +392,11 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream,
dev_err(dev, "failed to set cpui dai mclk1 rate (%lu): %d\n", mclk_freq, ret);
return ret;
}
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_freq, SND_SOC_CLOCK_IN);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(dev, "failed to set codec dai mclk rate (%lu): %d\n", mclk_freq, ret);
+ return ret;
+ }
return 0;
}
@@ -408,7 +435,7 @@ static int imx_aif_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct imx_card_data *data = snd_soc_card_get_drvdata(card);
- struct dai_link_data *link_data = &data->link_data[rtd->num];
+ struct dai_link_data *link_data = &data->link_data[rtd->id];
static struct snd_pcm_hw_constraint_list constraint_rates;
static struct snd_pcm_hw_constraint_list constraint_channels;
int ret = 0;
@@ -604,6 +631,8 @@ static int imx_card_parse_of(struct imx_card_data *data)
plat_data->type = CODEC_AK5558;
else if (!strcmp(link->codecs->dai_name, "ak5552-aif"))
plat_data->type = CODEC_AK5552;
+ else if (!strcmp(link->codecs->dai_name, "cs42888"))
+ plat_data->type = CODEC_CS42888;
} else {
link->codecs = &snd_soc_dummy_dlc;
@@ -710,6 +739,7 @@ static int imx_card_probe(struct platform_device *pdev)
data->plat_data = plat_data;
data->card.dev = &pdev->dev;
+ data->card.owner = THIS_MODULE;
dev_set_drvdata(&pdev->dev, &data->card);
snd_soc_card_set_drvdata(&data->card, data);
@@ -760,6 +790,12 @@ static int imx_card_probe(struct platform_device *pdev)
data->dapm_routes[i].sink = "ASRC-Capture";
data->dapm_routes[i].source = "CPU-Capture";
break;
+ case CODEC_CS42888:
+ data->dapm_routes[0].sink = "Playback";
+ data->dapm_routes[0].source = "CPU-Playback";
+ data->dapm_routes[1].sink = "CPU-Capture";
+ data->dapm_routes[1].source = "Capture";
+ break;
default:
break;
}
@@ -799,6 +835,16 @@ static int imx_card_probe(struct platform_device *pdev)
plat_data->support_tdm_channels = ak5558_tdm_channels;
plat_data->num_tdm_channels = ARRAY_SIZE(ak5558_tdm_channels);
break;
+ case CODEC_CS42888:
+ plat_data->fs_mul = cs42888_fs_mul;
+ plat_data->num_fs_mul = ARRAY_SIZE(cs42888_fs_mul);
+ plat_data->tdm_fs_mul = cs42888_tdm_fs_mul;
+ plat_data->num_tdm_fs_mul = ARRAY_SIZE(cs42888_tdm_fs_mul);
+ plat_data->support_channels = cs42888_channels;
+ plat_data->num_channels = ARRAY_SIZE(cs42888_channels);
+ plat_data->support_tdm_channels = cs42888_tdm_channels;
+ plat_data->num_tdm_channels = ARRAY_SIZE(cs42888_tdm_channels);
+ break;
default:
break;
}
@@ -814,8 +860,8 @@ static int imx_card_probe(struct platform_device *pdev)
}
for_each_card_prelinks(&data->card, i, link) {
if (link->dynamic == 1 && link_be) {
- link->dpcm_playback = link_be->dpcm_playback;
- link->dpcm_capture = link_be->dpcm_capture;
+ link->playback_only = link_be->playback_only;
+ link->capture_only = link_be->capture_only;
}
}
}