Skip to content

Instantly share code, notes, and snippets.

@kevinlekiller
Last active May 31, 2018 21:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kevinlekiller/f533f4d1f7318a7cf81a to your computer and use it in GitHub Desktop.
Save kevinlekiller/f533f4d1f7318a7cf81a to your computer and use it in GitHub Desktop.
Reduces the POP noise when switching outputs on the Asus Xonar Essence STX (ST also probably). Linux Kernel Patch.
#!/bin/bash
MAKE_FLAGS="-j8"
<<About
This script compiles the snd_oxygen_lib/snd_oxygen/snd_virtuoso modules with the patch in this gist and installs them.
You will need to rerun this every time you use a new kernel.
Tested on Arch Linux (Kernel 4.4).
Copyright (C) 2016 kevinlekiller
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
About
kernel_version=$(uname -r | grep -Po "^[\d.]+")
if [[ -z $kernel_version ]]; then
echo "Error: Problem detecting current kernel version."
exit 1
fi
modules_path="/lib/modules/$(uname -r)"
if [[ ! -f "$modules_path/build/Module.symvers" ]]; then
echo "Error: Can not find the Modules.symvers file for the current kernel."
exit 1
fi
if [[ ! -f "xonar_pcm179x.c.patch" ]]; then
wget "https://gist.githubusercontent.com/kevinlekiller/f533f4d1f7318a7cf81a/raw/xonar_pcm179x.c.patch"
if [[ $? != 0 ]] || [[ ! -f "xonar_pcm179x.c.patch" ]]; then
echo "Error: Problem downloading kernel patch."
exit 1
fi
fi
if [[ ! -f "linux-$kernel_version.tar.xz" ]]; then
wget "https://cdn.kernel.org/pub/linux/kernel/v$(echo $kernel_version | head -c 1).x/linux-$kernel_version.tar.xz"
if [[ $? != 0 ]]; then
echo "Error: Problem downloading kernel source."
exit 1
fi
tar -xf "linux-$kernel_version.tar.xz"
if [[ $? != 0 ]]; then
echo "Error: Could not extract kernel."
exit 1
fi
else
tar -xf "linux-$kernel_version.tar.xz"
if [[ $? != 0 ]]; then
echo "Error: Could not extract kernel."
exit 1
fi
fi
if [[ ! -d "linux-$kernel_version" ]]; then
echo "Error: Kernel directory not found."
exit 1
fi
cd "linux-$kernel_version"
make clean
cp "$modules_path/build/Module.symvers" .
zcat /proc/config.gz > .config
sed -i "s/CONFIG_LOCALVERSION=\".*\"/CONFIG_LOCALVERSION=\"$(uname -r | grep -Po "\-.*$")\"/" .config
patch sound/pci/oxygen/xonar_pcm179x.c ../xonar_pcm179x.c.patch
if [[ $? != 0 ]]; then
echo "Error: Problem patching xonar_pcm179x.c"
exit 1
fi
make prepare
make "$MAKE_FLAGS" sound/pci/oxygen
make modules_prepare
make "$MAKE_FLAGS" modules SUBDIRS=sound/pci/oxygen
sudo make modules_install SUBDIRS=sound/pci/oxygen
sudo mv "$modules_path"/extra/snd-*.ko.* "$modules_path"/extramodules/
sudo depmod -a
cd ..
sudo rm -rf linux-$kernel_version*
sudo rm -rf linux-$kernel-version
rm -f xonar_pcm179x.c.patch
rm -f "linux-$kernel_version.tar.xz"
echo "Done, reboot to safely reload the compiled modules."
--- linux-4.4.17/sound/pci/oxygen/xonar_pcm179x.c 2016-08-10 05:49:43.000000000 -0400
+++ linux-4.4.17/sound/pci/oxygen/xonar_pcm179x.c 2016-08-18 18:40:53.814312616 -0400
@@ -430,11 +430,14 @@
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
GPIO_ST_MAGIC | GPIO_ST_HP);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
- GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
+ // From what I gather, all this does is resets the output to speakers, which clicks a relay for no reason.
+ /*oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
+ GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);*/
xonar_init_cs53x1(chip);
- xonar_enable_output(chip);
+ // Do not enable the DATA right now, only the CONTROL, we will enable the DATA later, otherwise we get the POP.
+ //xonar_enable_output(chip);
+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->generic.output_enable_bit);
snd_component_add(chip->card, "PCM1792A");
snd_component_add(chip->card, "CS5381");
@@ -834,9 +837,20 @@
gpio = (gpio | GPIO_ST_HP) & ~GPIO_ST_HP_REAR;
break;
}
+ // Disable the output.
+ oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->generic.output_enable_bit);
+ msleep(data->generic.anti_pop_delay);
+ gpio &= ~GPIO_ST_OUTPUT_ENABLE;
+
oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
data->hp_active = gpio & GPIO_ST_HP;
update_pcm1796_volume(chip);
+
+ // Undo the change to gpio for the return, enable the output.
+ gpio &= GPIO_ST_OUTPUT_ENABLE;
+ msleep(data->generic.anti_pop_delay);
+ oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->generic.output_enable_bit);
+
mutex_unlock(&chip->mutex);
return gpio != gpio_old;
}
@menskiz0r
Copy link

Well I tip my fedora to you mister. Been looking for a way to fix the loud pop on STX for roughly 5 years now and now its almost completely fixed.

Worked perfectly on Archlunux Kernel 4.9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment