Skip to content

Instantly share code, notes, and snippets.

@loopyd
Last active January 30, 2026 23:52
Show Gist options
  • Select an option

  • Save loopyd/663cf1c8cc8f5f27e9c6268983fea9df to your computer and use it in GitHub Desktop.

Select an option

Save loopyd/663cf1c8cc8f5f27e9c6268983fea9df to your computer and use it in GitHub Desktop.
[bash] HP Omen Fix for Linux Mint - Fixes error with missing audio firmware on this laptop
#!/bin/bash
# This script is used to fix the audio issues on HP Omen 15 laptop
#
# It installs the latest kernel, updates the sof firmware, removes old kernels, enables real-time audio support and disables mitigations for better performance, as well
# as applies additional tweaks to improve the overall system performance and stability on this laptop.
# Function to update sof firmware from sof project to the specified version
function update_sof() {
local sof_firmware_version="${1}"
local backup_folder="${2}"
WORKDIR=$(mktemp -d)
mkdir -p ${WORKDIR}/sof-bin
cd ${WORKDIR}/sof-bin || {
echo "Could not change to ${WORKDIR}/sof-bin directory." >&2
return 1
}
wget -O - "https://github.com/thesofproject/sof-bin/releases/download/v${sof_firmware_version}/sof-bin-${sof_firmware_version}.tar.gz" | tar xz
if [ $? -ne 0 ]; then
echo "Could not download sof-bin package from sof project." >&2
return 1
fi
cd "sof-bin-${sof_firmware_version}" || {
echo "Could not find sof-bin-${sof_firmware_version} directory." >&2
return 1
}
# Take backup, just in case of issues.
if [ ! -d "${backup_folder}" ]; then
echo "Saving backup to: ${backup_folder} ..." >&2
mkdir -p "${backup_folder}" 2>/dev/null
sudo mv /lib/firmware/intel/sof* "${backup_folder}" 2>/dev/null
sudo mv /usr/local/bin/sof-* "${backup_folder}" 2>/dev/null
fi
# Run the installer from the downloaded package
echo "Installing sf-bin firmware package from: ${WORKDIR}/sof-bin/sof-bin-${sof_firmware_version} ..." >&2
sudo chmod +x ./install.sh
sudo ./install.sh >&2
if [ $? -ne 0 ]; then
echo "Failed to install sof-bin package, please check terminal output for details" >&2
return 1
fi
# Cleanup the build directory
cd "$HOME" || {
echo "Could not change to home directory." >&2
return 1
}
echo "Cleaning build directory ..." >&2
rm -rf "${WORKDIR}"/sof-bin 2>/dev/null
}
# Function to install a new kernel
function install_kernel() {
local NEW_KERNEL="${1}"
local EXECUTE="${2}"
IN_USE=$(uname -a | awk '{ print $3 }')
if [[ "$IN_USE" == "$NEW_KERNEL" ]]; then
echo "[WARN] The requested kernel: $NEW_KERNEL is already in use!" >&2
fi
NEW_KERNEL_PACKAGES=$(
apt-cache search "${NEW_KERNEL}" |
grep -Evi "unsigned|nvidia|uc|-dbgsym" |
grep -Ei 'linux-image|linux-headers|linux-modules|linux-modules-extra' |
awk '{ print $1 }'
)
if [[ "$EXECUTE" == "true" ]]; then
for PACKAGE in $NEW_KERNEL_PACKAGES; do
if dpkg -l | grep -q "$PACKAGE"; then
echo "[WARN] Kernel package: $PACKAGE is already installed." >&2
continue
fi
echo "[APT] Installing kernel package: $PACKAGE" >&2
sudo apt install -qqy --no-install-recommends "$PACKAGE" || {
echo "[ERROR] Failed to install kernel package: $PACKAGE" >&2
return 1
}
done
echo "[SUCCESS] Please reboot your system to complete the kernel installation." >&2
return 0
else
echo "[SUCCESS] To install the new kernel, run this function with the second argument set to 'true'." >&2
return 0
fi
}
# Function to remove old kernels
#shellcheck disable=SC2120
function remove_old_kernels() {
local EXECUTE="${1}"
local USE_KERNEL="${2}"
IN_USE=$(uname -a | awk '{ print $3 }')
if [[ "$IN_USE" == "$USE_KERNEL" ]]; then
echo "[WARN] The requested kernel: $USE_KERNEL is in use!" >&2
fi
OLD_KERNELS=$(
dpkg --list |
grep -v "$IN_USE" |
grep -v "$USE_KERNEL" |
grep -Ei 'linux-image|linux-headers|linux-modules|linux-modules-extra' |
awk '{ print $2 }'
)
if [[ "$EXECUTE" == "true" ]]; then
for PACKAGE in $OLD_KERNELS; do
echo "[APT] Removing kernel package: $PACKAGE" >&2
yes | sudo apt purge -qq "$PACKAGE" || {
echo "[ERRPR] Failed to remove kernel package: $PACKAGE" >&2
return 1
}
done
echo "[ALERT] Please reboot your system to complete the kernel removal." >&2
return 0
else
echo "[SUCCESS] To remove old kernels, run this function with the first argument set to 'true'." >&2
return 0
fi
}
# Function to enable real-time audio support for PREEMPT_DYNAMIC kernel
function enable_rt_preempt_audio() {
# check if the kernel is PREEMPT_DYNAMIC
if ! grep -q PREEMPT_DYNAMIC /boot/config-"$(uname -r)"; then
echo "[ERROR] Real-time audio support is only available for PREEMPT_DYNAMIC kernel." >&2
return 1
fi
# if audio group does not exist, create it
if ! grep -q audio /etc/group; then
echo "[INFO] Creating audio group ..." >&2
sudo groupadd audio || {
echo "[ERROR] Failed to create audio group." >&2
return 1
}
echo "[SUCCESS] Audio group is now created." >&2
else
echo "[WARN] Audio group is already created." >&2
fi
# add current user to audio group, if not already added
if ! groups | grep -q audio; then
echo "[INFO] Adding current user to audio group ..." >&2
sudo usermod -aG audio "$USER" || {
echo "[ERROR] Failed to add current user to audio group." >&2
return 1
}
echo "[SUCCESS] Current user is now added to audio group." >&2
else
echo "[WARN] Current user is already added to audio group." >&2
fi
# if ondemand service is running, stop it
if sudo systemctl is-active --quiet ondemand; then
echo "[INFO] Stopping ondemand service ..." >&2
sudo systemctl stop ondemand.service || {
echo "[ERROR] Failed to stop ondemand service." >&2
return 1
}
echo "[SUCCESS] ondemand service is now stopped." >&2
else
echo "[WARN] ondemand service is already stopped." >&2
fi
# if ondemand service is unmasked, mask it
if ! sudo systemctl is-enabled --quiet ondemand; then
echo "[INFO] Masking ondemand service ..." >&2
sudo systemctl mask ondemand || {
echo "[ERROR] Failed to mask ondemand service." >&2
return 1
}
echo "[SUCCESS] ondemand service is now masked." >&2
else
echo "[WARN] ondemand service is already masked." >&2
fi
# install real-time audio service
if [ ! -f /etc/systemd/system/rt-audio-setup.service ]; then
echo "[INFO] Enabling real-time audio service ..." >&2
sudo tee /etc/systemd/system/rt-audio-setup.service <<EOF
[Unit]
Description=Realtime Audio Setup
[Service]
Type=oneshot
ExecStart=/bin/bash /usr/local/bin/rt-audio-setup
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo cat /usr/local/bin/rt-audio-setup <<EOF
echo -n performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
echo -n 950000 | sudo tee /proc/sys/kernel/sched_rt_runtime_us
EOF
sudo chmod +x /usr/local/bin/rt-audio-setup
sudo systemctl enable rt-audio-setup || {
echo "[ERROR] Failed to enable real-time audio service." >&2
return 1
}
sudo systemctl start rt-audio-setup || {
echo "[ERROR] Failed to start real-time audio service." >&2
return 1
}
echo "[SUCCESS] Real-time audio service is now enabled." >&2
else
echo "[WARN] Real-time audio service is already enabled." >&2
fi
# Set real-time audio limits for audio group
if [ -f /etc/security/limits.d/audio.conf ]; then
echo "[WARN] Real-time audio limits are already set." >&2
else
echo "[INFO] Setting real-time audio limits ..." >&2
sudo cat /etc/security/limits.d/audio.conf <<EOF
@audio - rtprio 99
@audio - memlock unlimited
EOF
echo "[SUCCESS] Real-time audio limits are now set." >&2
fi
# Uncomment vm.swappiness line in sysctl.conf
if grep -q "#vm.swappiness" /etc/sysctl.conf; then
sudo sed -i 's/#vm.swappiness/vm.swappiness/' /etc/sysctl.conf || {
echo "[ERROR] Failed to uncomment vm.swappiness line." >&2
return 1
}
fi
# Add vm.swappiness line to sysctl.conf if not found
if ! grep -q "vm.swappiness" /etc/sysctl.conf; then
echo "[INFO] Adding vm.swappiness line to sysctl.conf ..." >&2
sudo tee -a /etc/sysctl.conf <<EOF
vm.swappiness=10
EOF
echo "[SUCCESS] vm.swappiness line is now added to sysctl.conf." >&2
fi
# Adjust swappiness to 10.
SWAPPINESS=$(grep -Ei 'vm.swappiness' /etc/sysctl.conf | awk '{ print $3 }')
if [[ "$SWAPPINESS" != "10" ]]; then
echo "[INFO] Setting vm.swappiness to 10 ..." >&2
sudo sed -i 's/vm.swappiness=.*$/vm.swappiness=10/' /etc/sysctl.conf || {
echo "[ERROR] Failed to set vm.swappiness to 10." >&2
return 1
}
echo "[SUCCESS] vm.swappiness is now set to 10." >&2
else
echo "[WARN] vm.swappiness is already set to 10." >&2
fi
# Add udev rule for cpu_dma_latency
if [ -f /etc/udev/rules.d/50-cpu_dma_latency.rules ]; then
echo "[WARN] udev rule for cpu_dma_latency is already added." >&2
else
echo "[INFO] Adding udev rule for cpu_dma_latency ..." >&2
sudo cat /etc/udev/rules.d/50-cpu_dma_latency.rules <<EOF
DEVPATH=="/devices/virtual/misc/cpu_dma_latency", OWNER="root", GROUP="audio", MODE="0660"
EOF
sudo udevadm control --reload-rules || {
echo "[ERROR] Failed to reload udev rules." >&2
return 1
}
sudo udevadm trigger || {
echo "[ERROR] Failed to trigger udev rules." >&2
return 1
}
echo "[SUCCESS] udev rule for cpu_dma_latency is now added." >&2
fi
return 0
}
# Function to enable or disable kernel arguments
function enable_kernelarg() {
local KERNELARGS=()
KERNELARGS=("${@}")
# If the GRUB_CMDLINE_LINUX_DEFAULT line is not found, add it
if ! grep -q GRUB_CMDLINE_LINUX_DEFAULT /etc/default/grub; then
echo "[INFO] Adding GRUB_CMDLINE_LINUX_DEFAULT line ..." >&2
sudo sed -i 's/GRUB_CMDLINE_LINUX=\"/GRUB_CMDLINE_LINUX_DEFAULT=\"/g' /etc/default/grub || {
echo "[ERROR] Failed to add GRUB_CMDLINE_LINUX_DEFAULT line." >&2
return 1
}
fi
# If the GRUB_CMDLINE_LINUX_DEFAULT line is commented out, uncomment it
if grep -q "#GRUB_CMDLINE_LINUX_DEFAULT" /etc/default/grub; then
sudo sed -i 's/#GRUB_CMDLINE_LINUX_DEFAULT/GRUB_CMDLINE_LINUX_DEFAULT/g' /etc/default/grub || {
echo "[ERROR] Failed to uncomment GRUB_CMDLINE_LINUX_DEFAULT line." >&2
return 1
}
fi
for KERNELARG in "${KERNELARGS[@]}"; do
if grep -q "${KERNELARG}" /etc/default/grub; then
echo "[WARN] Kernel argument: ${KERNELARG} is already enabled." >&2
continue
fi
# Add the kernel argument to the GRUB_CMDLINE_LINUX_DEFAULT line
echo "[INFO] Enabling kernel argument: ${KERNELARG} ..." >&2
sudo sed -i "s/GRUB_CMDLINE_LINUX_DEFAULT=\"/GRUB_CMDLINE_LINUX_DEFAULT=\"${KERNELARG} /" /etc/default/grub || {
echo "[ERROR] Failed to enable kernel argument: ${KERNELARG}" >&2
return 1
}
sudo update-grub >&2 || {
echo "[ERROR] Failed to update grub." >&2
return 1
}
echo "[SUCCESS] Kernel argument: ${KERNELARG} is now enabled." >&2
done
return 0
}
function disable_kernelarg() {
local KERNELARGS=()
KERNELARGS=("${@}")
# if the GRUB_CMDLINE_LINUX_DEFAULT line is not found, return
if ! grep -q GRUB_CMDLINE_LINUX_DEFAULT /etc/default/grub; then
echo "[WARN] GRUB_CMDLINE_LINUX_DEFAULT line is not found, doing nothing." >&2
return 0
fi
# if the GRUB_CMDLINE_LINUX_DEFAULT line is commented out, return
if grep -q "#GRUB_CMDLINE_LINUX_DEFAULT" /etc/default/grub; then
echo "[WARN] GRUB_CMDLINE_LINUX_DEFAULT line is commented out, doing nothing." >&2
return 0
fi
# remove the kernel arguments from the GRUB_CMDLINE_LINUX_DEFAULT line
for KERNELARG in "${KERNELARGS[@]}"; do
if ! grep -q "${KERNELARG}" /etc/default/grub; then
echo "[WARN] Kernel argument: ${KERNELARG} is already disabled." >&2
return 0
fi
echo "[INFO] Disabling kernel argument: ${KERNELARG} ..." >&2
sudo sed -i "s/${KERNELARG} //" /etc/default/grub || {
echo "[ERROR] Failed to disable kernel argument: ${KERNELARG}" >&2
return 1
}
sudo update-grub >&2 || {
echo "[ERROR] Failed to update grub." >&2
return 1
}
done
return 0
}
install_kernel "6.5.0-1014-oem" "true"
update_sof "2023.12" "$HOME/sof-fw-backup"
remove_old_kernels "true" "6.5.0-1014-oem"
disable_kernelarg nospalsh
enable_kernelarg quiet splash threadirqs mitigations=off
enable_rt_preempt_audio
@loopyd
Copy link
Author

loopyd commented Feb 8, 2024

Update: Lock kernel version to 6.5.0-1014-oem and add kernel autocleanup script.

@loopyd
Copy link
Author

loopyd commented Mar 12, 2024

Update: Real-time dynamic preempt auto-configuration and tweaks have been added with PREEMPT_DYNAMIC support. See: linuxaudio for details. These added tweaks fully pass a rtcqs sanity check for real-time audio and improve the overall performance of the laptop.

@timelesscode
Copy link

how do i run or add this?

@emiliodelacrvz
Copy link

May I ask what model of HP Omen you used this with and if any changes have been done since last update?

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