#!/bin/bash
# set_audio.sh
# MSI WIND Audio Switcher
# works with the Azalia driver
# based on eeePC audio output script by Quinn Storm <livinglatexkali@gmail.com>

config()
{
    #change SOUND_STATE_FILE if you would like it elsewhere
    SOUND_STATE_FILE=/etc/last_sound_state

    #set up verb address values
    REG_BASE=$(get_base_addr)
    if [ "$(echo $REG_BASE | cut -b 7-)" == "00" ]
    then
        BASE_ADDR=$(echo $REG_BASE | cut -b 1-6)
        VERB_DATA_ADDR=0x${BASE_ADDR}60
        VERB_CMD_ADDR=0x${BASE_ADDR}68
    else
        echo "ERROR -- Unaligned base address." 1>&2
        exit 1
    fi
}
get_base_addr()
{
    #this ugly line gets the base address, eliminating hand configuration
    ioreg -d 1 -r -n $(ioreg -x | grep 'AzaliaController' -B 1 | head -n 1 | cut -d 'o' -f 2- | cut -d '<' -f 1) -x | grep "IODeviceMemory" | cut -d '=' -f 3 | cut -d ',' -f 1 | cut -b 11-
}
send_verb()
{
    #send a verb to the azalia driver
    reggie_se -D PhysAddr -w "$1" -a ${VERB_DATA_ADDR} -B 32 &> /dev/null
    echo -n "."
    reggie_se -D PhysAddr -w 1 -a ${VERB_CMD_ADDR} -B 32 &> /dev/null
    echo -n "."
}
enable_spk()
{
    #set up internal speaker output
    send_verb 0x01B70C02 #spk pin ctl
    send_verb 0x01B3B000 #spk eapd off (amp on)
    send_verb 0x0143B080 #hp eapd on (amp off)
}
enable_hp()
{
    #set up headphone/line out port output
    send_verb 0x014707C0 #hp pin ctl
    send_verb 0x0143B000 #hp eapd off (amp on)
    send_verb 0x01B3B080 #spk eapd on (amp off)
}
do_sudo()
{
    #make sure script has admin rights for reggie_se
    if [ "$(id -u)" == "0" ]
    then
        main "$@"
    else
        sudo "$0" "$@"
    fi
}
get_state()
{

    if [ -f ${SOUND_STATE_FILE} ] && grep -q hp ${SOUND_STATE_FILE}
    then
        (echo -n "spk") || echo -n "hp"
    else
        (echo -n "hp") || echo -n "spk"
    fi
}
set_state()
{
    #store new state in statefile
    echo -n "Setting state to $1"
    enable_$1
    echo $1 > ${SOUND_STATE_FILE}
    echo "done."
}
main()
{
    #thin wrapper around set_state, called by do_sudo
    config
    set_state $(get_state $1)
}
do_sudo "$@"

