summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2023-01-18 13:41:51 +0000
committerMark Brown <broonie@kernel.org>2023-01-18 13:41:51 +0000
commit24b401f3e0b1ddd269969e68e947ab0a6f89b017 (patch)
treeeb88d53f3f04e2b8c6848f5f783c4a32be0a7ec0 /sound
parente7e2b92e609f82cd164209509f852de941e1285b (diff)
parentbc36d761cad7f3fec22cd97ddaa80f0120610181 (diff)
ASoC: samsung: fsd: audio support for FSD SoC
Merge series from Padmanabhan Rajanbabu <p.rajanbabu@samsung.com>: This patch series enables audio support on FSD SoC. Changes in v4: 1. Rebased and addressed review comments provided for v3. Changes in v3: 1. Addressed all the review comments provided for v2 patch. 2. Fixed compilation warnings reported by kernel test robot. Changes in v2: 1. New compatible added in Exynos I2S driver for FSD platform. 2. Added Fixup support for Exynos I2S CPU DAI. 3. Migration of manual PSR, OPCLK configuration to Exynos CPU DAI driver as fixup. 4. Migrated from dedicated sound card to simple audio card. 5. Support added for tlv320aic3x-i2c codec on FSD platform. Changes in v1: 1. Add TDM support on samsung I2S interface. 2. Allow sound card to directly configure I2S prescaler divider instead of calculating it from frame clock. 3. The sound card support for FSD SoC which utilizes samsung I2S interface as CPU DAI. Padmanabhan Rajanbabu (5): ASoC: dt-bindings: Add FSD I2S controller bindings ASoC: samsung: i2s: add support for FSD I2S arm64: dts: fsd: Add I2S DAI node for Tesla FSD arm64: dts: fsd: Add codec node for Tesla FSD arm64: dts: fsd: Add sound card node for Tesla FSD .../bindings/sound/samsung-i2s.yaml | 8 +++ arch/arm64/boot/dts/tesla/fsd-evb.dts | 53 +++++++++++++++++++ arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 14 +++++ arch/arm64/boot/dts/tesla/fsd.dtsi | 34 ++++++++++++ sound/soc/samsung/i2s-regs.h | 1 + sound/soc/samsung/i2s.c | 53 +++++++++++++++++++ 6 files changed, 163 insertions(+) -- 2.17.1
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/samsung/i2s-regs.h1
-rw-r--r--sound/soc/samsung/i2s.c53
2 files changed, 54 insertions, 0 deletions
diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h
index b4b5d6053503..138e95581979 100644
--- a/sound/soc/samsung/i2s-regs.h
+++ b/sound/soc/samsung/i2s-regs.h
@@ -132,6 +132,7 @@
#define EXYNOS7_MOD_RCLK_192FS 7
#define PSR_PSREN (1 << 15)
+#define PSR_PSVAL(x) ((((x) - 1) << 8) & 0x3f00)
#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 9505200f3d11..6f96032090de 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -50,6 +50,10 @@ struct samsung_i2s_dai_data {
u32 quirks;
unsigned int pcm_rates;
const struct samsung_i2s_variant_regs *i2s_variant_regs;
+ void (*fixup_early)(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+ void (*fixup_late)(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
};
struct i2s_dai {
@@ -111,6 +115,10 @@ struct samsung_i2s_priv {
u32 suspend_i2spsr;
const struct samsung_i2s_variant_regs *variant_regs;
+ void (*fixup_early)(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
+ void (*fixup_late)(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai);
u32 quirks;
/* The clock provider's data */
@@ -940,6 +948,10 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pm_runtime_get_sync(dai->dev);
+
+ if (priv->fixup_early)
+ priv->fixup_early(substream, dai);
+
spin_lock_irqsave(&priv->lock, flags);
if (config_setup(i2s)) {
@@ -947,6 +959,9 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
return -EINVAL;
}
+ if (priv->fixup_late)
+ priv->fixup_late(substream, dai);
+
if (capture)
i2s_rxctrl(i2s, 1);
else
@@ -1410,6 +1425,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
if (np) {
priv->quirks = i2s_dai_data->quirks;
+ priv->fixup_early = i2s_dai_data->fixup_early;
+ priv->fixup_late = i2s_dai_data->fixup_late;
} else {
if (!i2s_pdata) {
dev_err(&pdev->dev, "Missing platform data\n");
@@ -1563,6 +1580,31 @@ static int samsung_i2s_remove(struct platform_device *pdev)
return 0;
}
+static void fsd_i2s_fixup_early(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct i2s_dai *i2s = to_info(asoc_rtd_to_cpu(rtd, 0));
+ struct i2s_dai *other = get_other_dai(i2s);
+
+ if (!is_opened(other)) {
+ i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, 0, SND_SOC_CLOCK_OUT);
+ i2s_set_sysclk(dai, SAMSUNG_I2S_OPCLK, 0, MOD_OPCLK_PCLK);
+ }
+}
+
+static void fsd_i2s_fixup_late(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
+ struct i2s_dai *i2s = to_info(asoc_rtd_to_cpu(rtd, 0));
+ struct i2s_dai *other = get_other_dai(i2s);
+
+ if (!is_opened(other))
+ writel(PSR_PSVAL(2) | PSR_PSREN, priv->addr + I2SPSR);
+}
+
static const struct samsung_i2s_variant_regs i2sv3_regs = {
.bfs_off = 1,
.rfs_off = 3,
@@ -1652,6 +1694,14 @@ static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 __maybe_unused = {
.i2s_variant_regs = &i2sv5_i2s1_regs,
};
+static const struct samsung_i2s_dai_data fsd_dai_type __maybe_unused = {
+ .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM,
+ .pcm_rates = SNDRV_PCM_RATE_8000_192000,
+ .i2s_variant_regs = &i2sv7_regs,
+ .fixup_early = fsd_i2s_fixup_early,
+ .fixup_late = fsd_i2s_fixup_late,
+};
+
static const struct platform_device_id samsung_i2s_driver_ids[] = {
{
.name = "samsung-i2s",
@@ -1678,6 +1728,9 @@ static const struct of_device_id exynos_i2s_match[] = {
}, {
.compatible = "samsung,exynos7-i2s1",
.data = &i2sv5_dai_type_i2s1,
+ }, {
+ .compatible = "tesla,fsd-i2s",
+ .data = &fsd_dai_type,
},
{},
};