diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch b/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch deleted file mode 100644 index 4e15285220..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 0b584f3c2808dba8dc9e74a628b65008302804a5 Mon Sep 17 00:00:00 2001 -From: Joerg Schambacher <joerg@i2audio.com> -Date: Fri, 29 Jan 2021 16:16:39 +0100 -Subject: [PATCH] Enhances the Hifiberry DAC+ driver for Hifiberry - AMP100 support - -Adds the necessary GPIO handling and ALSA mixer extensions. -Also fixes a problem with the PLL/CLK control when switching sample rates. -Thanks to Clive Messer for the support! - -Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> ---- - sound/soc/bcm/hifiberry_dacplus.c | 124 ++++++++++++++++++++++++++---- - 1 file changed, 111 insertions(+), 13 deletions(-) - ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -1,10 +1,10 @@ - /* -- * ASoC Driver for HiFiBerry DAC+ / DAC Pro -+ * ASoC Driver for HiFiBerry DAC+ / DAC Pro / AMP100 - * - * Author: Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com> - * Copyright 2014-2015 - * based on code by Florian Meier <florian.meier@koalo.de> -- * Headphone added by Joerg Schambacher, joerg@i2audio.com -+ * Headphone/AMP100 Joerg Schambacher <joerg@hifiberry.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License -@@ -17,6 +17,8 @@ - */ - - #include <linux/module.h> -+#include <linux/gpio/consumer.h> -+#include <../drivers/gpio/gpiolib.h> - #include <linux/platform_device.h> - #include <linux/kernel.h> - #include <linux/clk.h> -@@ -53,6 +55,47 @@ static bool slave; - static bool snd_rpi_hifiberry_is_dacpro; - static bool digital_gain_0db_limit = true; - static bool leds_off; -+static bool auto_mute; -+static int mute_ext_ctl; -+static int mute_ext; -+static struct gpio_desc *snd_mute_gpio; -+static struct gpio_desc *snd_reset_gpio; -+static struct snd_soc_card snd_rpi_hifiberry_dacplus; -+ -+static int snd_rpi_hifiberry_dacplus_mute_set(int mute) -+{ -+ gpiod_set_value_cansleep(snd_mute_gpio, mute); -+ return 1; -+} -+ -+static int snd_rpi_hifiberry_dacplus_mute_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ ucontrol->value.integer.value[0] = mute_ext; -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_mute_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ if (mute_ext == ucontrol->value.integer.value[0]) -+ return 0; -+ -+ mute_ext = ucontrol->value.integer.value[0]; -+ -+ return snd_rpi_hifiberry_dacplus_mute_set(mute_ext); -+} -+ -+static const char * const mute_text[] = {"Play", "Mute"}; -+static const struct soc_enum hb_dacplus_opt_mute_enum = -+ SOC_ENUM_SINGLE_EXT(2, mute_text); -+ -+static const struct snd_kcontrol_new hb_dacplus_opt_mute_controls[] = { -+ SOC_ENUM_EXT("Mute(ext)", hb_dacplus_opt_mute_enum, -+ snd_rpi_hifiberry_dacplus_mute_get, -+ snd_rpi_hifiberry_dacplus_mute_put), -+}; - - static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_component *component, - int clk_id) -@@ -68,6 +111,7 @@ static void snd_rpi_hifiberry_dacplus_se - snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); - break; - } -+ usleep_range(2000, 2100); - } - - static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_component *component) -@@ -85,13 +129,6 @@ static bool snd_rpi_hifiberry_dacplus_is - return (!(sck & 0x40)); - } - --static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( -- struct snd_soc_component *component) --{ -- msleep(2); -- return snd_rpi_hifiberry_dacplus_is_sclk(component); --} -- - static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_component *component) - { - bool isClk44EN, isClk48En, isNoClk; -@@ -99,13 +136,13 @@ static bool snd_rpi_hifiberry_dacplus_is - snd_rpi_hifiberry_dacplus_clk_gpio(component); - - snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_CLK44EN); -- isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component); -+ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk(component); - - snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK); -- isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component); -+ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk(component); - - snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_CLK48EN); -- isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component); -+ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk(component); - - return (isClk44EN && isClk48En && !isNoClk); - } -@@ -149,6 +186,7 @@ static int snd_rpi_hifiberry_dacplus_ini - { - struct snd_soc_component *component = rtd->codec_dai->component; - struct pcm512x_priv *priv; -+ struct snd_soc_card *card = &snd_rpi_hifiberry_dacplus; - - if (slave) - snd_rpi_hifiberry_is_dacpro = false; -@@ -187,6 +225,20 @@ static int snd_rpi_hifiberry_dacplus_ini - if (ret < 0) - dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); - } -+ if (snd_reset_gpio) { -+ gpiod_set_value_cansleep(snd_reset_gpio, 0); -+ msleep(1); -+ gpiod_set_value_cansleep(snd_reset_gpio, 1); -+ msleep(1); -+ gpiod_set_value_cansleep(snd_reset_gpio, 0); -+ } -+ -+ if (mute_ext_ctl) -+ snd_soc_add_card_controls(card, hb_dacplus_opt_mute_controls, -+ ARRAY_SIZE(hb_dacplus_opt_mute_controls)); -+ -+ if (snd_mute_gpio) -+ gpiod_set_value_cansleep(snd_mute_gpio, mute_ext); - - return 0; - } -@@ -254,6 +306,8 @@ static int snd_rpi_hifiberry_dacplus_sta - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_component *component = rtd->codec_dai->component; - -+ if (auto_mute) -+ gpiod_set_value_cansleep(snd_mute_gpio, 0); - if (leds_off) - return 0; - snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); -@@ -267,6 +321,8 @@ static void snd_rpi_hifiberry_dacplus_sh - struct snd_soc_component *component = rtd->codec_dai->component; - - snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); -+ if (auto_mute) -+ gpiod_set_value_cansleep(snd_mute_gpio, 1); - } - - /* machine stream operations */ -@@ -342,6 +398,8 @@ static int snd_rpi_hifiberry_dacplus_pro - struct device_node *tpa_node; - struct property *tpa_prop; - struct of_changeset ocs; -+ struct property *pp; -+ int tmp; - - /* probe for head phone amp */ - ret = hb_hp_detect(); -@@ -396,6 +454,39 @@ static int snd_rpi_hifiberry_dacplus_pro - "hifiberry-dacplus,slave"); - leds_off = of_property_read_bool(pdev->dev.of_node, - "hifiberry-dacplus,leds_off"); -+ auto_mute = of_property_read_bool(pdev->dev.of_node, -+ "hifiberry-dacplus,auto_mute"); -+ -+ /* -+ * check for HW MUTE as defined in DT-overlay -+ * active high, therefore default to HIGH to MUTE -+ */ -+ snd_mute_gpio = devm_gpiod_get_optional(&pdev->dev, -+ "mute", GPIOD_OUT_HIGH); -+ if (IS_ERR(snd_mute_gpio)) { -+ dev_err(&pdev->dev, "Can't allocate GPIO (HW-MUTE)"); -+ return PTR_ERR(snd_mute_gpio); -+ } -+ -+ /* add ALSA control if requested in DT-overlay (AMP100) */ -+ pp = of_find_property(pdev->dev.of_node, -+ "hifiberry-dacplus,mute_ext_ctl", &tmp); -+ if (pp) { -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "hifiberry-dacplus,mute_ext_ctl", &mute_ext)) { -+ /* ALSA control will be used */ -+ mute_ext_ctl = 1; -+ } -+ } -+ -+ /* check for HW RESET (AMP100) */ -+ snd_reset_gpio = devm_gpiod_get_optional(&pdev->dev, -+ "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR(snd_reset_gpio)) { -+ dev_err(&pdev->dev, "Can't allocate GPIO (HW-RESET)"); -+ return PTR_ERR(snd_reset_gpio); -+ } -+ - } - - ret = devm_snd_soc_register_card(&pdev->dev, -@@ -403,7 +494,14 @@ static int snd_rpi_hifiberry_dacplus_pro - if (ret && ret != -EPROBE_DEFER) - dev_err(&pdev->dev, - "snd_soc_register_card() failed: %d\n", ret); -- -+ if (!ret) { -+ if (snd_mute_gpio) -+ dev_info(&pdev->dev, "GPIO%i for HW-MUTE selected", -+ gpio_chip_hwgpio(snd_mute_gpio)); -+ if (snd_reset_gpio) -+ dev_info(&pdev->dev, "GPIO%i for HW-RESET selected", -+ gpio_chip_hwgpio(snd_reset_gpio)); -+ } - return ret; - } - |