#!/bin/dash
# vim: set sts=4 expandtab:
#
# vdev equivalent of udev 90-alsa-restore.rules (alsa-utils):
# restore ALSA mixer/control state when a sound control device appears.

. "$VDEV_HELPERS/subr.sh"

HDA_ANALOG_FILE="/run/udev/alsa-hda-analog-card"

# Unmute primary playback on internal analog codecs when alsactl left Master off.
# Saved asound.state often has Master Playback Switch=false after a muted session.
alsa_unmute_analog_playback() {
   local _card="$1"
   local _sysfs="$2"

   command -v amixer >/dev/null 2>&1 || return 0

   # Analog laptop/desktop codecs usually expose a capture PCM (D0c).
   if ! [ -d "$_sysfs/device/pcmC${_card}D0c" ]; then
      return 0
   fi

   if amixer -c "$_card" sget Master >/dev/null 2>&1; then
      if amixer -c "$_card" sget Master 2>/dev/null | grep -q '\[off\]'; then
         amixer -c "$_card" sset Master unmute >/dev/null 2>&1
      fi
   fi

   for _ctl in Speaker Headphone PCM Front; do
      amixer -c "$_card" sset "$_ctl" unmute >/dev/null 2>&1
   done
}

main() {
   local _SYSFS _CARD_NUM _CMD _HDA_ANALOG _DEV

   if [ "$VDEV_ACTION" != "add" ]; then
      return 0
   fi

   if [ -z "$(echo "$VDEV_PATH" | /bin/egrep '^snd/controlC[0-9]+$')" ]; then
      return 0
   fi

   if ! [ -d /usr/sbin ] || ! [ -d /usr/share/alsa ]; then
      return 0
   fi

   if ! [ -x /usr/sbin/alsactl ]; then
      return 0
   fi

   _SYSFS="$VDEV_OS_SYSFS_MOUNTPOINT/$VDEV_OS_DEVPATH"
   if ! [ -f "$_SYSFS/device/number" ]; then
      vdev_warn "alsa-restore: missing device/number for $VDEV_PATH"
      return 0
   fi

   _CARD_NUM="$(/bin/cat "$_SYSFS/device/number")"

   if [ -n "$(vdev_drivers "$_SYSFS" | /bin/grep '^snd_hda_intel$')" ]; then
      if [ -d "$_SYSFS/device/pcmC${_CARD_NUM}D0p" ]; then
         /bin/mkdir -p "$(dirname "$HDA_ANALOG_FILE")"
         echo "ALSA_CARD_HDA_ANALOG=$_CARD_NUM" >> "$HDA_ANALOG_FILE"
      fi
   fi

   _DEV="$_SYSFS/device/device"
   if [ -e "$_DEV/acp3x-dmic-capture" ] || [ -e "$_DEV/acp6x-dmic-capture" ] || \
      [ -e "$_DEV/acp63-dmic-capture" ] || [ -e "$_DEV/acp-dmic-codec" ]; then
      if [ -f "$HDA_ANALOG_FILE" ]; then
         _HDA_ANALOG="$(/bin/grep '^ALSA_CARD_HDA_ANALOG=' "$HDA_ANALOG_FILE" | /bin/tail -1 | /bin/sed 's/^ALSA_CARD_HDA_ANALOG=//')"
         if [ -n "$_HDA_ANALOG" ]; then
            _CARD_NUM="$_HDA_ANALOG"
         fi
      fi
   fi

   if [ -f /etc/alsa/state-daemon.conf ]; then
      _CMD="nrestore"
   else
      _CMD="restore"
   fi

   /usr/sbin/alsactl -E HOME=/run/alsa -E XDG_RUNTIME_DIR=/run/alsa/runtime "$_CMD" "$_CARD_NUM"
   _RC=$?

   if [ $_RC -ne 0 ]; then
      vdev_warn "alsa-restore: alsactl $_CMD $_CARD_NUM failed (rc=$_RC)"
   fi

   alsa_unmute_analog_playback "$_CARD_NUM" "$_SYSFS"

   return 0
}

if [ $VDEV_DAEMONLET -eq 0 ]; then
   main
   exit $?
fi
