diff options
Diffstat (limited to 'target/linux/at91/patches-5.15/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch')
-rw-r--r-- | target/linux/at91/patches-5.15/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/target/linux/at91/patches-5.15/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch b/target/linux/at91/patches-5.15/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch new file mode 100644 index 0000000000..5047e04d5b --- /dev/null +++ b/target/linux/at91/patches-5.15/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch @@ -0,0 +1,113 @@ +From 5bef4e8125d09443b5486971d5550ed285cde4b1 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Mon, 1 Mar 2021 19:09:01 +0200 +Subject: [PATCH 151/247] ASoC: mchp-i2s-mcc: Add multi-channel support for I2S + and LEFT_J formats + +The latest I2S-MCC available in SAMA7G5 supports multi-channel for I2S and +Left-Justified formats. For this, the new version uses 8 (4 * 2) input and +output pins, with each pin being responsible for 2 channels. This sums up +to a total of 8 channels for synchronous capture and playback. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210301170905.835091-4-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/mchp-i2s-mcc.c | 38 ++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/sound/soc/atmel/mchp-i2s-mcc.c ++++ b/sound/soc/atmel/mchp-i2s-mcc.c +@@ -16,6 +16,7 @@ + #include <linux/clk.h> + #include <linux/mfd/syscon.h> + #include <linux/lcm.h> ++#include <linux/of_device.h> + + #include <sound/core.h> + #include <sound/pcm.h> +@@ -225,6 +226,10 @@ static const struct regmap_config mchp_i + .max_register = MCHP_I2SMCC_VERSION, + }; + ++struct mchp_i2s_mcc_soc_data { ++ unsigned int data_pin_pair_num; ++}; ++ + struct mchp_i2s_mcc_dev { + struct wait_queue_head wq_txrdy; + struct wait_queue_head wq_rxrdy; +@@ -232,6 +237,7 @@ struct mchp_i2s_mcc_dev { + struct regmap *regmap; + struct clk *pclk; + struct clk *gclk; ++ const struct mchp_i2s_mcc_soc_data *soc; + struct snd_dmaengine_dai_dma_data playback; + struct snd_dmaengine_dai_dma_data capture; + unsigned int fmt; +@@ -549,6 +555,17 @@ static int mchp_i2s_mcc_hw_params(struct + } + + if (dev->fmt & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) { ++ /* for I2S and LEFT_J one pin is needed for every 2 channels */ ++ if (channels > dev->soc->data_pin_pair_num * 2) { ++ dev_err(dev->dev, ++ "unsupported number of audio channels: %d\n", ++ channels); ++ return -EINVAL; ++ } ++ ++ /* enable for interleaved format */ ++ mrb |= MCHP_I2SMCC_MRB_CRAMODE_REGULAR; ++ + switch (channels) { + case 1: + if (is_playback) +@@ -558,6 +575,12 @@ static int mchp_i2s_mcc_hw_params(struct + break; + case 2: + break; ++ case 4: ++ mra |= MCHP_I2SMCC_MRA_WIRECFG_I2S_2_TDM_1; ++ break; ++ case 8: ++ mra |= MCHP_I2SMCC_MRA_WIRECFG_I2S_4_TDM_2; ++ break; + default: + dev_err(dev->dev, "unsupported number of audio channels\n"); + return -EINVAL; +@@ -869,12 +892,22 @@ static const struct snd_soc_component_dr + }; + + #ifdef CONFIG_OF ++static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sam9x60 = { ++ .data_pin_pair_num = 1, ++}; ++ ++static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = { ++ .data_pin_pair_num = 4, ++}; ++ + static const struct of_device_id mchp_i2s_mcc_dt_ids[] = { + { + .compatible = "microchip,sam9x60-i2smcc", ++ .data = &mchp_i2s_mcc_sam9x60, + }, + { + .compatible = "microchip,sama7g5-i2smcc", ++ .data = &mchp_i2s_mcc_sama7g5, + }, + { /* sentinel */ } + }; +@@ -932,6 +965,11 @@ static int mchp_i2s_mcc_probe(struct pla + dev->gclk = NULL; + } + ++ dev->soc = of_device_get_match_data(&pdev->dev); ++ if (!dev->soc) { ++ dev_err(&pdev->dev, "failed to get soc data\n"); ++ return -ENODEV; ++ } + dev->dev = &pdev->dev; + dev->regmap = regmap; + platform_set_drvdata(pdev, dev); |