Created
January 20, 2024 19:17
-
-
Save mesheets/4352f976dd17a8dbf8491f3a67d16d8a to your computer and use it in GitHub Desktop.
Add support for HiFiBerry Stage to Raspberry Pi Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts | |
| index cafa2ccd7ff7..561cd84bbb79 100644 | |
| --- a/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts | |
| +++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts | |
| @@ -43,6 +43,11 @@ | |
| clocks = <&dacpro_osc>; | |
| status = "okay"; | |
| }; | |
| + hpamp: hpamp@60 { | |
| + compatible = "ti,tpa6130a2"; | |
| + reg = <0x60>; | |
| + status = "disabled"; | |
| + }; | |
| }; | |
| }; | |
| diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig | |
| index d65df373c39e..c85714895f1e 100644 | |
| --- a/sound/soc/bcm/Kconfig | |
| +++ b/sound/soc/bcm/Kconfig | |
| @@ -79,7 +79,8 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO | |
| tristate "Support for HifiBerry DAC+ADC PRO" | |
| depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S | |
| select SND_SOC_PCM512x_I2C | |
| - select SND_SOC_PCM186X_I2C | |
| + select SND_SOC_PCM186X_I2C | |
| + select SND_SOC_TPA6130A2 | |
| select COMMON_CLK_HIFIBERRY_DACPRO | |
| help | |
| Say Y or M if you want to add support for HifiBerry DAC+ADC PRO. | |
| diff --git a/sound/soc/bcm/hifiberry_dacplusadcpro.c b/sound/soc/bcm/hifiberry_dacplusadcpro.c | |
| index 79eccdb4dc8c..728040720fa8 100644 | |
| --- a/sound/soc/bcm/hifiberry_dacplusadcpro.c | |
| +++ b/sound/soc/bcm/hifiberry_dacplusadcpro.c | |
| @@ -5,7 +5,7 @@ | |
| * Copyright 2014-2015 | |
| * based on code by Florian Meier <florian.meier@koalo.de> | |
| * ADC added by Joerg Schambacher <joerg@i2audio.com> | |
| - * Copyright 2018-19 | |
| + * Copyright 2018-21 | |
| * | |
| * This program is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU General Public License | |
| @@ -26,6 +26,7 @@ | |
| #include <linux/of.h> | |
| #include <linux/slab.h> | |
| #include <linux/delay.h> | |
| +#include <linux/i2c.h> | |
| #include <sound/core.h> | |
| #include <sound/pcm.h> | |
| @@ -468,6 +469,14 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_dacplusadcpro_dai[] = { | |
| }, | |
| }; | |
| +static struct snd_soc_aux_dev hifiberry_dacplusadcpro_aux_devs[] = { | |
| + { | |
| + .dlc = { | |
| + .name = "tpa6130a2.1-0060", | |
| + }, | |
| + }, | |
| +}; | |
| + | |
| /* audio machine driver */ | |
| static struct snd_soc_card snd_rpi_hifiberry_dacplusadcpro = { | |
| .name = "snd_rpi_hifiberry_dacplusadcpro", | |
| @@ -477,11 +486,72 @@ static struct snd_soc_card snd_rpi_hifiberry_dacplusadcpro = { | |
| .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplusadcpro_dai), | |
| }; | |
| +static int hb_hp_detect(void) | |
| +{ | |
| + struct i2c_adapter *adap = i2c_get_adapter(1); | |
| + int ret; | |
| + struct i2c_client tpa_i2c_client = { | |
| + .addr = 0x60, | |
| + .adapter = adap, | |
| + }; | |
| + | |
| + if (!adap) | |
| + return -EPROBE_DEFER; /* I2C module not yet available */ | |
| + | |
| + ret = i2c_smbus_read_byte(&tpa_i2c_client) >= 0; | |
| + i2c_put_adapter(adap); | |
| + return ret; | |
| +}; | |
| + | |
| +static struct property tpa_enable_prop = { | |
| + .name = "status", | |
| + .length = 4 + 1, /* length 'okay' + 1 */ | |
| + .value = "okay", | |
| + }; | |
| + | |
| static int snd_rpi_hifiberry_dacplusadcpro_probe(struct platform_device *pdev) | |
| { | |
| int ret = 0, i = 0; | |
| struct snd_soc_card *card = &snd_rpi_hifiberry_dacplusadcpro; | |
| + /* probe for headphone amp of HiFiBerry Stage */ | |
| + int len; | |
| + struct device_node *tpa_node; | |
| + struct property *tpa_prop; | |
| + struct of_changeset ocs; | |
| + | |
| + ret = hb_hp_detect(); | |
| + | |
| + /* if head phone amp not detected, ignore and continue with standard probe */ | |
| + if (ret > 0) { | |
| + card->aux_dev = hifiberry_dacplusadcpro_aux_devs; | |
| + card->num_aux_devs = | |
| + ARRAY_SIZE(hifiberry_dacplusadcpro_aux_devs); | |
| + tpa_node = of_find_compatible_node(NULL, NULL, "ti,tpa6130a2"); | |
| + tpa_prop = of_find_property(tpa_node, "status", &len); | |
| + | |
| + if (strcmp((char *)tpa_prop->value, "okay")) { | |
| + /* and activate headphone using change_sets */ | |
| + dev_info(&pdev->dev, "activating headphone amplifier"); | |
| + of_changeset_init(&ocs); | |
| + ret = of_changeset_update_property(&ocs, tpa_node, | |
| + &tpa_enable_prop); | |
| + if (ret) { | |
| + dev_err(&pdev->dev, | |
| + "cannot activate headphone amplifier\n"); | |
| + /* -ENODEV; */ | |
| + } else { | |
| + ret = of_changeset_apply(&ocs); | |
| + if (ret) { | |
| + dev_err(&pdev->dev, | |
| + "cannot activate headphone amplifier\n"); | |
| + /* -ENODEV; */ | |
| + } | |
| + } | |
| + } | |
| + } | |
| + | |
| + /* standard probe for HiFiBerry DAC+ ADC Pro */ | |
| snd_rpi_hifiberry_dacplusadcpro.dev = &pdev->dev; | |
| if (pdev->dev.of_node) { | |
| struct device_node *i2s_node; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment