init (5336B)
1 #!/bin/sh 2 # 3 # alsa-utils initscript 4 # 5 ### BEGIN INIT INFO 6 # Provides: alsa-utils 7 # Required-Start: $local_fs $remote_fs 8 # Required-Stop: $remote_fs 9 # Default-Start: S 10 # Default-Stop: 0 1 6 11 # Short-Description: Restore and store ALSA driver settings 12 # Description: This script stores and restores mixer levels on 13 # shutdown and bootup.On sysv-rc systems: to 14 # disable storing of mixer levels on shutdown, 15 # remove /etc/rc[06].d/K50alsa-utils. To disable 16 # restoring of mixer levels on bootup, rename the 17 # "S50alsa-utils" symbolic link in /etc/rcS.d/ to 18 # "K50alsa-utils". 19 ### END INIT INFO 20 21 # Don't use set -e; check exit status instead 22 23 # Exit silently if package is no longer installed 24 [ -x /usr/sbin/alsactl ] || exit 0 25 26 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 27 MYNAME=/etc/init.d/alsa-utils 28 ALSACTLHOME=/run/alsa 29 30 [ -d "$ALSACTLHOME" ] || mkdir -p "$ALSACTLHOME" 31 32 . /lib/lsb/init-functions 33 . /usr/share/alsa/utils.sh 34 35 # $1 EXITSTATUS 36 # [$2 MESSAGE] 37 log_action_end_msg_and_exit() 38 { 39 log_action_end_msg "$1" ${2:+"$2"} 40 exit $1 41 } 42 43 # $1 PROGRAM 44 executable() 45 { 46 # If which is not available then we must be running before 47 # /usr is mounted on a system that has which in /usr/bin/. 48 # Conclude that $1 is not executable. 49 [ -x /bin/which ] || [ -x /usr/bin/which ] || return 1 50 which "$1" >/dev/null 2>&1 51 } 52 53 executable amixer || { echo "${MYNAME}: Error: No amixer program available." >&2 ; exit 1 ; } 54 55 # $1 <card ID> | "all" 56 restore_levels() 57 { 58 [ -f /var/lib/alsa/asound.state ] || return 1 59 CARD="$1" 60 [ "$1" = all ] && CARD="" 61 # Assume that if alsactl prints a message on stderr 62 # then it failed somehow. This works around the fact 63 # that alsactl doesn't return nonzero status when it 64 # can't restore settings for the card 65 if MSG="$(alsactl -E HOME="$ALSACTLHOME" restore $CARD 2>&1 >/dev/null)" && [ ! "$MSG" ] ; then 66 return 0 67 else 68 # Retry with the "force" option. This restores more levels 69 # but it results in much longer error messages. 70 alsactl -F restore $CARD >/dev/null 2>&1 71 log_action_cont_msg "warning: 'alsactl -E HOME="$ALSACTLHOME" restore${CARD:+ $CARD}' failed with error message '$MSG'" 72 return 1 73 fi 74 } 75 76 # $1 <card ID> | "all" 77 store_levels() 78 { 79 CARD="$1" 80 [ "$1" = all ] && CARD="" 81 if MSG="$(alsactl -E HOME="$ALSACTLHOME" store $CARD 2>&1)" ; then 82 sleep 1 83 return 0 84 else 85 log_action_cont_msg "warning: 'alsactl store${CARD:+ $CARD}' failed with error message '$MSG'" 86 return 1 87 fi 88 } 89 90 91 # $1 <card ID> 92 mute_and_zero_levels_on_card() 93 { 94 CARDOPT="-c $1" 95 for CTL in \ 96 Master \ 97 PCM \ 98 Synth \ 99 CD \ 100 Line \ 101 Mic \ 102 "PCM,1" \ 103 Wave \ 104 Music \ 105 AC97 \ 106 "Master Digital" \ 107 DAC \ 108 "DAC,0" \ 109 "DAC,1" \ 110 Headphone \ 111 Speaker \ 112 Playback 113 do 114 mute_and_zero_level "$CTL" 115 done 116 # for CTL in \ 117 # "Audigy Analog/Digital Output Jack" \ 118 # "SB Live Analog/Digital Output Jack" 119 # do 120 # switch_control "$CTL" off 121 # done 122 return 0 123 } 124 125 # $1 <card ID> | "all" 126 mute_and_zero_levels() 127 { 128 TTZML_RETURNSTATUS=0 129 case "$1" in 130 all) 131 for CARD in $(echo_card_indices) ; do 132 mute_and_zero_levels_on_card "$CARD" || TTZML_RETURNSTATUS=1 133 done 134 ;; 135 *) 136 mute_and_zero_levels_on_card "$1" || TTZML_RETURNSTATUS=1 137 ;; 138 esac 139 return $TTZML_RETURNSTATUS 140 } 141 142 143 # $1 <card ID> | "all" 144 card_OK() 145 { 146 [ "$1" ] || bugout 147 if [ "$1" = all ] ; then 148 [ -d /proc/asound ] 149 return $? 150 else 151 [ -d "/proc/asound/card$1" ] || [ -d "/proc/asound/$1" ] 152 return $? 153 fi 154 } 155 156 # If a card identifier is provided in $2 then regard it as an error 157 # if that card is not present; otherwise don't regard it as an error. 158 159 case "$1" in 160 start) 161 EXITSTATUS=0 162 TARGET_CARD="$2" 163 case "$TARGET_CARD" in 164 ""|all) TARGET_CARD=all ; log_action_begin_msg "Setting up ALSA" ;; 165 *) log_action_begin_msg "Setting up ALSA card ${TARGET_CARD}" ;; 166 esac 167 card_OK "$TARGET_CARD" || log_action_end_msg_and_exit "$( [ ! "$2" ] ; echo $? ; )" "none loaded" 168 preinit_levels "$TARGET_CARD" || EXITSTATUS=1 169 if ! restore_levels "$TARGET_CARD" ; then 170 sanify_levels "$TARGET_CARD" || EXITSTATUS=1 171 restore_levels "$TARGET_CARD" >/dev/null 2>&1 || : 172 fi 173 log_action_end_msg_and_exit "$EXITSTATUS" 174 ;; 175 stop) 176 EXITSTATUS=0 177 TARGET_CARD="$2" 178 case "$TARGET_CARD" in 179 ""|all) TARGET_CARD=all ; log_action_begin_msg "Shutting down ALSA" ;; 180 *) log_action_begin_msg "Shutting down ALSA card ${TARGET_CARD}" ;; 181 esac 182 card_OK "$TARGET_CARD" || log_action_end_msg_and_exit "$( [ ! "$2" ] ; echo $? ; )" "none loaded" 183 store_levels "$TARGET_CARD" || EXITSTATUS=1 184 #mute_and_zero_levels "$TARGET_CARD" || EXITSTATUS=1 185 log_action_end_msg_and_exit "$EXITSTATUS" 186 ;; 187 restart|force-reload) 188 EXITSTATUS=0 189 $0 stop || EXITSTATUS=1 190 $0 start || EXITSTATUS=1 191 exit $EXITSTATUS 192 ;; 193 reset) 194 TARGET_CARD="$2" 195 case "$TARGET_CARD" in 196 ""|all) TARGET_CARD=all ; log_action_begin_msg "Resetting ALSA" ;; 197 *) log_action_begin_msg "Resetting ALSA card ${TARGET_CARD}" ;; 198 esac 199 card_OK "$TARGET_CARD" || log_action_end_msg_and_exit "$( [ ! "$2" ] ; echo $? ; )" "none loaded" 200 preinit_levels "$TARGET_CARD" 201 sanify_levels "$TARGET_CARD" 202 log_action_end_msg_and_exit "$?" 203 ;; 204 *) 205 echo "Usage: $MYNAME {start [CARD]|stop [CARD]|restart [CARD]|reset [CARD]}" >&2 206 exit 3 207 ;; 208 esac 209