openwrt/target/linux/bcm27xx/patches-6.1/950-1266-ASoC-adds-support-for-AMP4-Pro-to-the-DAC-Plus-drive.patch
Álvaro Fernández Rojas 20fe7e687e bcm27xx: update 6.1 patches from RPi foundation
Sync 6.1 patches with the RPi foundation.
Since rpi-6.6.y is now the main branch of the RPi foundation, there won't be
any new patches for linux 6.1.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-04-07 22:12:42 +02:00

115 lines
3.7 KiB
Diff

From d58c054ba30b313bacbb7d19f559ecb4e3bb5c76 Mon Sep 17 00:00:00 2001
From: Joerg Schambacher <joerg@hifiberry.com>
Date: Fri, 19 Jan 2024 10:58:39 +0100
Subject: [PATCH 1266/1295] ASoC: adds support for AMP4 Pro to the DAC Plus
driver
The AMP4 Pro is a I2S master mode capable amplifier with
clean onboard clock generators.
We can share the card driver between TAS575x amplifiers
and the PCM512x DACs as they are SW compatible.
From a HW perspective though we need to limit the sample
rates to the standard audio rates to avoid running the
onboard clocks through the PLL. Using the PLL would require
even a different HW.
DAI/stream name are also set accordingly to allow the user
a convenient identification of the soundcard
Needs the pcm512x driver with TAS575x support (already in
upstream kernel).
Signed-off-by: Joerg Schambacher <joerg@hifiberry.com>
---
sound/soc/bcm/hifiberry_dacplus.c | 41 ++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
--- a/sound/soc/bcm/hifiberry_dacplus.c
+++ b/sound/soc/bcm/hifiberry_dacplus.c
@@ -58,10 +58,21 @@ static bool leds_off;
static bool auto_mute;
static int mute_ext_ctl;
static int mute_ext;
+static bool tas_device;
static struct gpio_desc *snd_mute_gpio;
static struct gpio_desc *snd_reset_gpio;
static struct snd_soc_card snd_rpi_hifiberry_dacplus;
+static const u32 master_dai_rates[] = {
+ 44100, 48000, 88200, 96000,
+ 176400, 192000, 352800, 384000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_master = {
+ .count = ARRAY_SIZE(master_dai_rates),
+ .list = master_dai_rates,
+};
+
static int snd_rpi_hifiberry_dacplus_mute_set(int mute)
{
gpiod_set_value_cansleep(snd_mute_gpio, mute);
@@ -197,8 +208,13 @@ static int snd_rpi_hifiberry_dacplus_ini
if (snd_rpi_hifiberry_is_dacpro) {
struct snd_soc_dai_link *dai = rtd->dai_link;
- dai->name = "HiFiBerry DAC+ Pro";
- dai->stream_name = "HiFiBerry DAC+ Pro HiFi";
+ if (tas_device) {
+ dai->name = "HiFiBerry AMP4 Pro";
+ dai->stream_name = "HiFiBerry AMP4 Pro HiFi";
+ } else {
+ dai->name = "HiFiBerry DAC+ Pro";
+ dai->stream_name = "HiFiBerry DAC+ Pro HiFi";
+ }
dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM;
@@ -303,6 +319,18 @@ static int snd_rpi_hifiberry_dacplus_sta
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+ int ret;
+
+ if (tas_device && !slave) {
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_master);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "Cannot apply constraints for sample rates\n");
+ return ret;
+ }
+ }
if (auto_mute)
gpiod_set_value_cansleep(snd_mute_gpio, 0);
@@ -324,7 +352,7 @@ static void snd_rpi_hifiberry_dacplus_sh
}
/* machine stream operations */
-static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = {
+static const struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = {
.hw_params = snd_rpi_hifiberry_dacplus_hw_params,
.startup = snd_rpi_hifiberry_dacplus_startup,
.shutdown = snd_rpi_hifiberry_dacplus_shutdown,
@@ -394,6 +422,7 @@ static int snd_rpi_hifiberry_dacplus_pro
struct snd_soc_card *card = &snd_rpi_hifiberry_dacplus;
int len;
struct device_node *tpa_node;
+ struct device_node *tas_node;
struct property *tpa_prop;
struct of_changeset ocs;
struct property *pp;
@@ -430,6 +459,12 @@ static int snd_rpi_hifiberry_dacplus_pro
}
}
+ tas_node = of_find_compatible_node(NULL, NULL, "ti,tas5756");
+ if (tas_node) {
+ tas_device = true;
+ dev_info(&pdev->dev, "TAS5756 device found!\n");
+ };
+
snd_rpi_hifiberry_dacplus.dev = &pdev->dev;
if (pdev->dev.of_node) {
struct device_node *i2s_node;