#!/bin/bash # # ALSA Configurator # # Copyright (c) 1999-2002 SuSE GmbH # Jan ONDREJ # # written by Takashi Iwai # Bernd Kaindl # Jan ONDREJ (SAL) # # based on the original version of Jan ONDREJ's alsaconf for ALSA 0.4. # # 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. # export TEXTDOMAIN=alsaconf prefix=/usr exec_prefix=${prefix} bindir=${exec_prefix}/bin sbindir=${exec_prefix}/sbin version=1.0.25 USE_NLS=yes # Useful for debugging PROCFS="/proc" SYSFS="/sys" # i18n stuff if test "$USE_NLS" = "yes" && type -p gettext > /dev/null; then xecho() { gettext -s "$*" } else xecho() { echo "$*" } gettext() { echo -n "$*" } fi xmsg() { msg=$(gettext "$1") shift printf "$msg" $* } # Check for GNU/Linux distributions if [ -f /etc/slackware-version ]; then distribution="slackware" elif [ -f /etc/SuSE-release ]; then distribution="suse" suse_version=$(grep 'VERSION = ' /etc/SuSE-release | sed -e s/'VERSION = '//) elif [ -f /etc/UnitedLinux-release ]; then distribution="suse" elif [ -f /etc/gentoo-release ]; then distribution="gentoo" elif [ -f /etc/debian_version ]; then distribution="debian" elif [ -f /etc/mandrake-release ]; then distribution="mandrake" elif test -f /etc/redhat-release && grep -q "Red Hat" /etc/redhat-release; then distribution="redhat" elif test -f /etc/fedora-release && grep -q "Fedora" /etc/fedora-release; then distribution="fedora" elif [ -f /etc/slackware-version -o -f /etc/slamd64-version ]; then distribution="slackware" else distribution="unknown" fi for prog in lspci lsmod; do for path in /sbin /usr/sbin /bin /usr/bin;do test -x $path/$prog && eval $prog=$path/$prog done done unset prog path usage() { xecho "ALSA configurator" echo " version $version" xecho "usage: alsaconf [options] -l|--legacy check only legacy non-isapnp cards -m|--modinfo read module descriptions instead of reading card db -s|--sound wav-file use the specified wav file as a test sound -u|--uid uid set the uid for the ALSA devices (default = 0) [obsoleted] -g|--gid gid set the gid for the ALSA devices (default = 0) [obsoleted] -d|--devmode mode set the permission for ALSA devices (default = 0666) [obs.] -r|--strict set strict device mode (equiv. with -g 17 -d 0660) [obsoleted] -L|--log file logging on the specified file (for debugging purpose only) -p|--probe card-name probe a legacy non-isapnp card and print module options -P|--listprobe list the supported legacy card modules -c|--config file specify the module config file -R|--resources list available DMA and IRQ resources with debug for legacy -h|--help what you're reading" } OPTS=`getopt -o lmL:hp:Pu:g:d:rs:c:R --long legacy,modinfo,log:,help,probe:,listprobe,uid:,gid:,devmode:,strict,sound:,config:,resources -n alsaconf -- "$@"` || exit 1 eval set -- "$OPTS" do_legacy_only=0 use_modinfo_db=0 alsa_uid=0 alsa_gid=0 alsa_mode=0666 legacy_probe_card="" LOGFILE="" TESTSOUND="/usr/share/test.wav" try_all_combination=0 resources="false" # legacy support LEGACY_CARDS="opl3sa2 cs4236 cs4232 cs4231 es18xx es1688 sb16 sb8" while true ; do case "$1" in -l|--legacy) do_legacy_only=1; shift ;; -m|--modinfo) use_modinfo_db=1; shift ;; -s|--sound) TESTSOUND=$2; shift 2;; -h|--help) usage; exit 0 ;; -L|--log) LOGFILE="$2"; shift 2;; -p|--probe) legacy_probe_card="$2"; shift 2;; -P|--listprobe) echo "$LEGACY_CARDS"; exit 0;; -u|--uid) alsa_uid="$2"; shift 2;; -g|--gid) alsa_gid="$2"; shift 2;; -d|--devmode) alsa_mode="$2"; shift 2;; -r|--strict) alsa_uid=0; alsa_gid=17; alsa_mode=0660; shift;; -c|--config) cfgfile="$2"; shift 2;; -R|--resources) resources="true"; shift;; --) shift ; break ;; *) usage ; exit 1 ;; esac done # # probe legacy ISA cards # check_dma_avail () { list="" if [ -d $SYSFS/bus/pnp/devices ]; then for dma in $*; do ok="true" for i in $SYSFS/bus/pnp/devices/??:* ; do if grep -q "state = active" $i/resources ; then if grep -q '^dma '$dma'$' $i/resources; then ok="false" fi fi done if [ -r $PROCFS/dma ]; then if grep -q '^ *'$dma': ' $PROCFS/dma ; then ok="false" fi fi if [ "$ok" = "true" ]; then list="$list $dma" fi done else if [ -r $PROCFS/dma ]; then for dma in $*; do grep -q '^ *'$dma': ' $PROCFS/dma || list="$list $dma" done fi fi if [ ! -z "$list" ]; then echo $list fi } check_irq_avail () { list="" if [ -d $SYSFS/bus/pnp/devices ]; then for irq in $*; do ok="true" for i in $SYSFS/bus/pnp/devices/??:* ; do if grep -q "state = active" $i/resources ; then if grep -q '^irq '$irq'$' $i/resources; then ok="false" fi fi done if [ -r $PROCFS/interrupts ]; then if grep -q '^ *'$irq': ' $PROCFS/interrupts ; then ok="false" fi fi if [ "$ok" = "true" ]; then list="$list $irq" fi done else if [ -r $PROCFS/interrupts ]; then for irq in $*; do grep -q '^ *'$irq': ' $PROCFS/interrupts || list="$list $irq" done fi fi if [ ! -z "$list" ]; then echo $list fi } # # # if [ "$resources" = "true" ]; then if [ -d $SYSFS/bus/pnp/devices ]; then for i in $SYSFS/bus/pnp/devices/??:* ; do if [ "$resources" = "true" ]; then echo ">>>>> PnP file: $i/resources" cat $i/resources fi done fi if [ -r $PROCFS/dma ]; then echo ">>>>> Allocated dma channels:" cat $PROCFS/dma fi if [ -r $PROCFS/interrupts ]; then echo ">>>>> Allocated interrupt channels:" cat $PROCFS/interrupts fi echo -n "Valid DMA channels: " check_dma_avail 0 1 2 3 4 5 6 7 echo -n "Valid IRQ channels: " check_irq_avail 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 exit 0 fi # Check for root privileges if [ `id -u` -ne 0 ]; then xecho "You must be root to use this script." exit 1 fi # # check the snd_ prefix for ALSA module options # snd_ prefix is obsoleted since 0.9.0rc4. # if /sbin/modinfo -p snd | grep -q snd_ ; then mpfx="snd_" else mpfx="" fi alsa_device_opts="" if /sbin/modinfo -p snd | grep -q uid ; then if [ x"$alsa_uid" != x0 ]; then alsa_device_opts="$alsa_device_opts ${mpfx}device_uid=$alsa_uid" fi if [ x"$alsa_gid" != x0 ]; then alsa_device_opts="$alsa_device_opts ${mpfx}device_gid=$alsa_gid" fi fi if /sbin/modinfo -p snd | grep -q device_mode ; then if [ x"$alsa_mode" != x0 ]; then alsa_device_opts="$alsa_device_opts ${mpfx}device_mode=$alsa_mode" fi fi case `uname -r` in 2.6.*) kernel="new" ;; *) kernel="old" ;; esac # cfgfile = base config file to remove/update the sound setting # cfgout = new config file to write the sound setting (if different from $cfgfile) cfgout="" cfgoldout="" if [ -n "$cfgfile" ]; then if [ ! -r "$cfgfile" ]; then xecho "ERROR: The config file doesn't exist: " echo $cfgfile exit 1 fi else if [ "$distribution" = "gentoo" ]; then cfgfile="/etc/modules.d/alsa" elif [ "$distribution" = "slackware" ]; then cfgfile="/etc/modprobe.d/sound.conf" elif [ "$kernel" = "new" ]; then cfgfile="/etc/modprobe.conf" if [ -d /etc/modprobe.d ]; then cfgout="/etc/modprobe.d/sound.conf" cfgoldout="/etc/modprobe.d/sound" if [ ! -f $cfgout ]; then modver=$(modprobe -V | sed -e's/^module-init-tools version //') case "$modver" in 3.[789]*) ;; *) cfgout="/etc/modprobe.d/sound" cfgoldout="" ;; esac fi fi elif [ "$distribution" = "debian" ]; then cfgfile="/etc/modutils/sound" elif [ -e /etc/modules.conf ]; then cfgfile="/etc/modules.conf" elif [ -e /etc/conf.modules ]; then cfgfile="/etc/conf.modules" else cfgfile="/etc/modules.conf" touch /etc/modules.conf fi fi # Check for dialog, whiptail, gdialog, awk, ... ? if type -p dialog > /dev/null; then DIALOG=dialog else if type -p whiptail > /dev/null; then whiptail_wrapper() { X1="$1" X2="$2" if [ $1 = --yesno ]; then X3=`expr $3 + 2` else X3=$3 fi shift 3 whiptail "$X1" "$X2" $X3 "$@" } DIALOG=whiptail_wrapper else xecho "Error, dialog or whiptail not found." exit 1 fi fi if type -p awk > /dev/null; then : else xecho "Error, awk not found. Can't continue." exit 1 fi # # remove entries by yast2 sound configurator # remove_y2_block() { awk ' /^alias sound-slot-[0-9]/ { next } /^alias char-major-116 / { next } /^alias char-major-14 / { next } /^alias snd-card-[0-9] / { next } /^options snd / { next } /^options snd-/ { next } /^options off / { next } /^alias sound-service-[0-9]/ { next } /^# YaST2: sound / { next } { print }' } # # remove entries by sndconfig sound configurator # # found strings to search for in WriteConfModules, # from sndconfig 0.68-4 (rawhide version) remove_sndconfig_block() { awk ' /^alias sound-slot-0/ { modulename = $3 ; next } /^alias sound-slot-[0-9]/ { next } /^post-install sound-slot-[0-9] / { next } /^pre-remove sound-slot-[0-9] / { next } /^options sound / { next } /^alias synth0 opl3/ { next } /^options opl3 / { next } /^alias midi / { mididev = $3 ; next } /^options / { if ($2 == mididev) next } /^pre-install / { if ($2 == mididev) next } /^alias synth0 / { synth = $3 ; next } /^post-install / { if ($2 == synth) next } /^options sb / { next } /^post-install .+ \/bin\/modprobe "aci"/ { if ($2 == modulename) next } /^options adlib_card / { next } /^options .+ isapnp=1/ { if ($2 == modulename) next } /^options i810_audio / { next } /^options / {if ($2 == modulename) next } { print }' } # # remove the previous configuration by alsaconf # remove_ac_block() { awk '/^'"$ACB"'$/,/^'"$ACE"'$/ { next } { print }' } # # set default mixer volumes # set_mixers() { amixer -s -q </dev/null 2>&1 $rcalsasound unload >/dev/null 2>&1 /sbin/rmmod dmasound dmasound_awacs 2>/dev/null fi cleanup () { killall -9 aplay arecord >/dev/null 2>&1 /sbin/modprobe -r isapnp >/dev/null 2>&1 /sbin/modprobe -r isa-pnp >/dev/null 2>&1 rm -f "$TMP" "$addcfg" "$FOUND" "$DUMP" } trap cleanup 0 TMP=`mktemp -q /tmp/alsaconf.XXXXXX` if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1 fi addcfg=`mktemp -q /tmp/alsaconf.XXXXXX` if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1 fi FOUND=`mktemp -q /tmp/alsaconf.XXXXXX` if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1 fi DUMP=`mktemp -q /tmp/alsaconf.XXXXXX` if [ $? -ne 0 ]; then xecho "Can't create temp file, exiting..." exit 1 fi # convert ISA PnP id number to string 'ABC' convert_isapnp_id () { if [ -z "$1" ]; then echo "XXXX" return fi let a='('$1'>>2) & 0x3f' let b='(('$1' & 0x03) << 3) | (('$1' >> 13) & 0x07)' let c='('$1'>> 8) & 0x1f' strs='@ABCDEFGHIJKLMNOPQRSTUVWXYZ' echo ${strs:$a:1}${strs:$b:1}${strs:$c:1} } # swap high & low bytes swap_number () { if [ -z "$1" ]; then echo "0000" return fi let v='(('$1'>>8)&0xff)|(('$1'&0xff)<<8)' printf "%04x" $v } # build card database # build_card_db filename build_card_db () { MODDIR=/lib/modules/`uname -r` last_driver="" echo -n > $1 # list pci cards while read driver vendor device dummy; do if expr $driver : 'snd-.*' >/dev/null ; then if [ "$last_driver" != "$driver" ]; then echo $driver.o last_driver=$driver fi id1=`printf '0x%04x' $vendor` id2=`printf '0x%04x' $device` echo "PCI: $id1=$id2" fi done < $MODDIR/modules.pcimap >> $1 # list isapnp cards while read driver cardvendor carddevice data vendor func; do if expr $driver : 'snd-.*' >/dev/null ; then if [ "$last_driver" != "$driver" ]; then echo $driver.o last_driver=$driver fi id1=`convert_isapnp_id $cardvendor` dev1=`swap_number $carddevice` id2=`convert_isapnp_id $vendor` dev2=`swap_number $func` echo "ISAPNP: $id1$dev1=$id2$dev2" fi done < $MODDIR/modules.isapnpmap >> $1 } # # probe cards # probe_cards () { found="0" test -r $PROCFS/isapnp || /sbin/modprobe isapnp >/dev/null 2>&1 test -r $PROCFS/isapnp || /sbin/modprobe isa-pnp >/dev/null 2>&1 if [ -r $PROCFS/isapnp ]; then cat $PROCFS/isapnp >"$DUMP" found="1" elif [ -d $SYSFS/bus/pnp/devices ]; then # use 2.6 kernel's sysfs output # fake the isapnp dump index=0 bindex=0 for d1 in $SYSFS/devices/pnp* ; do for d2 in $d1/*:* ; do if [ -r $d2/card_id ]; then id=`cat $d2/card_id` name=`cat $d2/name` echo "Card $index '$id:$name' " >> "$DUMP" index=$[$index+1] found="1" else if [ -r $d2/id ]; then # FIXME: multiple id might be present (separated with new-line) id=`head -n 1 $d2/id` echo "BIOS $bindex '$id' " >> "$DUMP" bindex=$[$bindex+1] found="1" fi fi done done fi if [ "$found" = "0" ]; then echo -n >"$DUMP" fi CARDID_DB=/var/tmp/alsaconf.cards if [ ! -r $CARDID_DB ]; then use_modinfo_db=1 fi if [ $use_modinfo_db != 1 ]; then if [ $CARDID_DB -ot /lib/modules/`uname -r`/modules.dep ]; then use_modinfo_db=1 fi fi if [ $use_modinfo_db = 1 ]; then xecho "Building card database.." build_card_db $CARDID_DB fi if [ ! -r $CARDID_DB ]; then xecho "No card database is found.." exit 1 fi ncards=`grep '^snd-.*\.o$' $CARDID_DB | wc -w` msg=$(gettext "Searching sound cards") awk ' BEGIN { format="%-40s %s\n"; ncards='"$ncards"'; idx=0; } /^snd-.*\.o$/{ sub(/.o$/, ""); driver=$0; perc=(idx * 100) / (ncards + 1); print int(perc); idx++; } /^[]*PCI: /{ gsub(/0x/, ""); gsub(/=/, ":"); x = sprintf ("'$lspci' -n 2>/dev/null| grep '"' 04..: '"' | grep %s", $2); if (system (x) == 0) printf "%s %s\n", $2, driver >>"'"$FOUND"'" } /^[]*ISAPNP: /{ id2 = substr($0, index($0, "=")+1); gsub(/=.*/, ""); x = sprintf ("grep '\''^Card [0-9] .%s:'\'' '"$DUMP"'", $2); if (system (x) == 0) printf "%s %s\n", $2, driver >>"'"$FOUND"'" else if (index($2, "ffff") > 0) { x = sprintf ("grep '\''^BIOS [0-9]* .%s.'\'' '"$DUMP"'", id2); if (system (x) == 0) printf "%s %s\n", id2, driver >>"'"$FOUND"'" } }' < $CARDID_DB |\ $DIALOG --gauge "$msg" 6 40 0 # # PowerMac # if grep -q MacRISC $PROCFS/cpuinfo; then MODDIR=/lib/modules/`uname -r` find $MODDIR -name 'snd-powermac*' -print | \ while read i; do i=${i##*/} i=${i%%.o} i=${i%%.ko} echo "PowerMac $i" >> $FOUND done fi # # Sparc # if grep -q Sparc $PROCFS/cpuinfo; then test -r $PROCFS/openprom/name || /bin/mount -t openpromfs none $PROCFS/openprom >/dev/null 2>&1 # Check for an "audio" device audio= compat= if test -r $PROCFS/openprom; then audio=`find $PROCFS/openprom -follow -type d -name "audio*" -print` fi if test -n "$audio"; then compat=`cat $audio/compatible` compat=${compat#\'} compat=${compat%\'} compat=${compat#SUNW,} fi # Go through all cards we have MODDIR=/lib/modules/`uname -r` find $MODDIR -name 'snd-sun-*' -print | \ while read i; do i=${i##*/} i=${i%%.o} i=${i%%.ko} sdev=`echo ${i#snd-sun-} | tr "[a-z]" "[A-Z]"` if test "$sdev" = "$compat"; then echo "$sdev $i" >> $FOUND elif test -r $PROCFS/openprom; then find $PROCFS/openprom -follow -type d -name "SUNW,${sdev}*" \ -exec echo "$sdev $i" \; 2>/dev/null >> $FOUND else echo "$sdev $i" >> $FOUND fi done fi } # # look for a descriptive device name from the given device id # find_device_name () { if expr "$1" : '[0-9a-f][0-9a-f][0-9a-f][0-9a-f]:[0-9a-f][0-9a-f][0-9a-f][0-9a-f]' >/dev/null; then $lspci -d $1 2>/dev/null| sed -e 's/^.*:..\.. [^:]*: //g' return elif expr "$1" : '[A-Z@][A-Z@][A-Z@][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' >/dev/null; then cardname=`grep '^Card [0-9]\+ .'$1':' $DUMP | head -n 1 | sed -e 's/^Card [0-9]\+ '\''.*:\(.*\)'\'' .*$/\1/'` echo $cardname else echo $1 fi } # get hwcfg file type from the given driver name get_hwcfg_type () { while read dev driver; do if [ "$driver" = "$1" ]; then case "$dev" in *:*) # FIXME: need to look around /sys/bus/pci/* (or use vpid-* ?) devid=`$lspci -d "$dev" | head -n 1 | sed -e 's/ .*$//'` case "$devid" in *:*:*.*) ;; *) devid="0000:$devid" ;; esac echo bus-pci-$devid ;; *) echo $driver ;; esac break fi done } # clean up all hwcfg-* files containing ALSA modules # alsaconf sets up exclusively cleanup_hwcfg () { for i in /etc/sysconfig/hardware/hwcfg-*; do grep -q "MODULE='snd-" $i && rm -f $i done } # # set up /etc/sysconfig/hardware/hwcfg-* stuff # setup_hwcfg () { card=$1 cleanup_hwcfg cfg=`echo "$devs_olist" | get_hwcfg_type $card` echo "MODULE='$card'" > /etc/sysconfig/hardware/hwcfg-$cfg echo "STARTMODE='auto'" >> /etc/sysconfig/hardware/hwcfg-$cfg } # # configure and try test sound # ac_config_card () { CARD_DRIVER=snd-$1 CARD_OPTS="${*:2}" if [ -n "$cfgout" ]; then msg=$(xmsg " Configuring %s Do you want to modify %s (and %s if present)?" $CARD_DRIVER $cfgout $cfgfile) $DIALOG --yesno "$msg" 10 50 || acex 0 else msg=$(xmsg " Configuring %s Do you want to modify %s?" $CARD_DRIVER $cfgfile) $DIALOG --yesno "$msg" 8 50 || acex 0 fi clear # Copy conf.modules and make changes. ACB="# --- BEGIN: Generated by ALSACONF, do not edit. ---" ACE="# --- END: Generated by ALSACONF, do not edit. ---" # Detect 2.2.X kernel KVER=`uname -r | tr ".-" " "` KVER1=`echo $KVER | cut -d" " -f1` KVER2=`echo $KVER | cut -d" " -f2` if [ $KVER1 -ge 2 ] && [ $KVER2 -ge 2 ]; then SOUND_CORE="soundcore" else SOUND_CORE="snd" fi if [ -r $cfgfile ] ; then if [ "$distribution" = "redhat" -o "$distribution" = "fedora" ] ; then remove_ac_block < $cfgfile | remove_sndconfig_block | uniq > $TMP else remove_ac_block < $cfgfile | remove_y2_block | uniq > $TMP fi fi if [ -z "$have_alias" -a "$kernel" = "new" ]; then if grep -q char-major-116 /lib/modules/`uname -r`/modules.alias; then have_alias="yes" fi fi if [ -z "$have_alias" ]; then echo "alias char-major-116 snd alias char-major-14 $SOUND_CORE alias sound-service-0-0 snd-mixer-oss alias sound-service-0-1 snd-seq-oss alias sound-service-0-3 snd-pcm-oss alias sound-service-0-8 snd-seq-oss alias sound-service-0-12 snd-pcm-oss" >> $addcfg fi if [ -n "$alsa_device_opts" ]; then echo "options snd $alsa_device_opts" >> $addcfg fi echo "alias snd-card-0 $CARD_DRIVER alias sound-slot-0 $CARD_DRIVER" >> $addcfg if [ -n "$CARD_OPTS" ]; then echo "options $CARD_DRIVER $CARD_OPTS" >> $addcfg fi if [ -n "$cfgout" ]; then [ ! -r "$cfgfile" ] || cmp -s "$TMP" "$cfgfile" || cat "$TMP" > "$cfgfile" cmp -s "$addcfg" "$cfgout" || cat "$addcfg" > "$cfgout" test -n "$cfgoldout" && rm -f "$cfgoldout" else echo "$ACB # --- ALSACONF version $version ---" >> $TMP cat "$addcfg" >> "$TMP" echo "$ACE " >> $TMP cmp -s "$TMP" "$cfgfile" || cat "$TMP" > "$cfgfile" fi /sbin/depmod -a 2>/dev/null # remove yast2 entries (- only for suse distro) if [ -f /var/lib/YaST/unique.inf ]; then awk ' BEGIN { in_sound=0; } /^\[sound\]$/ { print; in_sound=1; next; } /^\[.+\]$/ { print; in_sound=0; next; } { if (in_sound == 0) { print; } } ' < /var/lib/YaST/unique.inf > $TMP cp -f $TMP /var/lib/YaST/unique.inf fi # set up /etc/sysconfig/hardware/* if [ "$distribution" = "suse" ]; then case "$suse_version" in 10.[012]*|10) setup_hwcfg $CARD_DRIVER ;; esac fi farewell clear case "$distribution" in gentoo | debian) xecho "Running update-modules..." update-modules ;; esac if [ -x $rcalsasound ] ; then echo Loading driver... $rcalsasound restart fi echo Setting default volumes... if [ -x $bindir/set_default_volume ]; then $bindir/set_default_volume -f else set_mixers fi if [ -f $TESTSOUND ]; then msg=$(gettext " The mixer is set up now for for playing. Shall I try to play a sound sample now? NOTE: If you have a big amplifier, lower your volumes or say no. Otherwise check that your speaker volume is open, and look if you can hear test sound. ") if $DIALOG --yesno "$msg" 13 65 then clear echo aplay -N $TESTSOUND fi fi mkdir -p -m 0755 /var/lib/alsa if [ ! -r /var/lib/alsa/asound.state ]; then xecho "Saving the mixer setup used for this in /var/lib/alsa/asound.state." $sbindir/alsactl store fi clear xecho " =============================================================================== Now ALSA is ready to use. For adjustment of volumes, use your favorite mixer. Have a lot of fun! " } # check playback # return 0 - OK, 1 - NG, 2 - not working (irq/dma problem) ac_try_load () { test -n "$LOGFILE" && echo "$1 ${*:2}" >> "$LOGFILE" /sbin/modprobe snd-$1 ${*:2} >/dev/null 2>&1 if $lsmod | grep -q -E '^(snd-|snd_)'$1' '; then : ; else /sbin/modprobe -r snd-$1 >/dev/null 2>&1 return 1 fi # mute mixers amixer set Master 0% mute >/dev/null 2>&1 amixer set PCM 0% mute >/dev/null 2>&1 # output 0.5 sec head -c 4000 < /dev/zero | aplay -N -r8000 -fS16_LE -traw -c1 > /dev/null 2>&1 & # remember pid pp=$! # sleep for 2 seconds (to be sure -- 1 sec would be enough) sleep 2 # kill the child process if still exists. kill -9 $pp > /dev/null 2>&1 st=$? ac_cardname=`head -n 1 $PROCFS/asound/cards | sed -e 's/^[0-9].* - \(.*\)$/\1/'` /sbin/modprobe -r snd-$1 >/dev/null 2>&1 if [ $st = 0 ]; then # irq problem? test -n "$LOGFILE" && echo "no playback return" >> "$LOGFILE" return 2 else # seems ok! test -n "$LOGFILE" && echo "playback OK" >> "$LOGFILE" return 0 fi } # check capture # return 0 - OK, 1 - NG, 2 - not working (irq/dma problem) # ac_try_capture card duplex opts ac_try_capture () { test -n "$LOGFILE" && echo "$1 ${*:2}" >> "$LOGFILE" /sbin/modprobe snd-$1 ${*:3} >/dev/null 2>&1 if $lsmod | grep -q -E '^(snd-|snd_)'$1' '; then : ; else /sbin/modprobe -r snd-$1 >/dev/null 2>&1 return 1 fi # mute mixers amixer set Master 0% mute >/dev/null 2>&1 amixer set PCM 0% mute >/dev/null 2>&1 play_pid=0 if [ $2 = yes ]; then # try duplex - start dummy playing aplay -N -r8000 -fS16_LE -traw -c1 < /dev/zero > /dev/null 2>&1 & play_pid=$! fi # record 1sec arecord -N -d1 > /dev/null 2>&1 & # remember pid pp=$! # sleep for 2 seconds sleep 2 # kill the child process if still exists. kill -9 $pp > /dev/null 2>&1 st=$? # kill playback process if any test $play_pid != 0 && kill -9 $play_pid /sbin/modprobe -r snd-$1 >/dev/null 2>&1 if [ $st = 0 ]; then test -n "$LOGFILE" && echo "capture no return" >> "$LOGFILE" return 2 else test -n "$LOGFILE" && echo "capture OK" >> "$LOGFILE" return 0 fi } get_dma_pair () { case $1 in 0) echo 1 3 5;; 1) echo 0 3 5;; 3) echo 1 0 5;; 5) echo 3 1 0;; esac } # # check playback on specified irqs # # ac_try_irq card opts irqs... # return 0 - OK, 1 - NG, 2 - not working (dma problem?) # ac_try_irq () { card=$1 opts="$2 ${mpfx}irq=$3" ac_try_load $card $opts >/dev/null 2>&1 result=$? case $result in 0) ac_opts="$opts" return 0 ;; 2) for irq in ${*:4}; do opts="$2 ${mpfx}irq=$irq" ac_try_load $card $opts >/dev/null 2>&1 if [ $? = 0 ]; then ac_opts="$opts" return 0 fi done return 2 ;; esac return 1 } # # check playback/capture on dma1 & dma2 & specified irqs # # ac_try_dmas card opts irqs... # return 0 - OK, 1 - NG # ac_try_dmas () { dma_list=`check_dma_avail 1 0 3 5` for irq in ${*:3}; do for dma1 in $dma_list; do for dma2 in `get_dma_pair $dma1`; do opts="$2 ${mpfx}dma1=$dma1 ${mpfx}dma2=$dma2 ${mpfx}irq=$irq" ac_try_load $1 $opts >/dev/null 2>&1 result=$? if [ $result = 1 ]; then if [ $try_all_combination = 1 ]; then continue else return 1 fi elif [ $result = 0 ]; then test -n "$LOGFILE" && echo "Now checking capture..." >> "$LOGFILE" ac_opts="$opts" ac_try_capture $1 yes $opts >/dev/null 2>&1 && return 0 for d in yes no; do for dma2 in $dma_list; do if [ $dma1 != $dma2 ]; then opts="$2 ${mpfx}dma1=$dma1 ${mpfx}dma2=$dma2 ${mpfx}irq=$irq" ac_opts="$opts" ac_try_capture $1 $d $opts >/dev/null 2>&1 && return 0 fi done done return 0 fi done done done return 1 } # check if the option $2 exists in card $1: set value $3 ac_check_option () { if /sbin/modinfo -p snd-$1 | grep -q $2; then echo "$2=$3" fi } ac_try_card_sb8 () { card=sb8 irq_list=`check_irq_avail 5 3 9 10 7` for dma8 in `check_dma_avail 1 3`; do opts="${mpfx}dma8=$dma8" ac_try_irq $card "$opts" $irq_list && return 0 done return 1 } ac_try_card_sb16 () { card=sb16 isapnp=`ac_check_option $card ${mpfx}isapnp 0` opts="$isapnp" irq_list=`check_irq_avail 5 9 10 7 3` dma_list=`check_dma_avail 0 1 3` dma16_list=`check_dma_avail 5 6 7` # at first try auto-probing by driver itself ac_try_load $card $opts >/dev/null 2>&1 result=$? case $result in 0) ac_opts="$opts" ac_try_capture $card yes $opts >/dev/null 2>&1 && return 0 for d in yes no; do for dma8 in $dma_list; do for irq in $irq_list; do opts="${mpfx}dma8=$dma8 ${mpfx}irq=$irq $isapnp" ac_try_capture $card $d $opts >/dev/null 2>&1 && return 0 done done done return 0 ;; 2) for dma16 in $dma16_list; do opts="${mpfx}dma16=$dma16 $isapnp" if ac_try_irq $card "$opts" $irq_list ; then ac_try_capture $card yes $ac_opts >/dev/null 2>&1 && return 0 ac_opts_saved="$ac_opts" for d in yes no; do for dma8 in $dma_list; do ac_opts="$ac_opts_saved ${mpfx}dma8=$dma8" ac_try_capture $card $d $ac_opts >/dev/null 2>&1 && return 0 done done # return anyway here.. return 0 fi done ;; esac return 1 } ac_try_card_es1688 () { card=es1688 opts="" irq_list=`check_irq_avail 5 9 10 7` for dma8 in `check_dma_avail 1 3 0`; do opts="${mpfx}dma8=$dma8 ${mpfx}mpu_irq=-1" ac_try_irq $card "$opts" $irq_list && return 0 done return 1 } ac_try_card_es18xx () { card=es18xx opts=`ac_check_option $card ${mpfx}isapnp 0` ac_try_dmas $card "$opts" `check_irq_avail 5 9 10 7` && return 0 return 1 } ac_try_card_cs4236 () { card=cs4236 irq_list=`check_irq_avail 5 7 9 11 12 15` isapnp=`ac_check_option $card ${mpfx}isapnp 0` for cport in 0x538 0x210 0xf00; do for port in 0x530 0x534; do opts="${mpfx}port=$port ${mpfx}cport=$cport $isapnp" ac_try_dmas $card "$opts" $irq_list && return 0 done done return 1 } ac_try_card_cs4232 () { card=cs4232 irq_list=`check_irq_avail 5 7 9 11 12 15` isapnp=`ac_check_option $card ${mpfx}isapnp 0` for cport in 0x538 0x210 0xf00; do for port in 0x530 0x534; do opts="${mpfx}port=$port ${mpfx}cport=$cport $isapnp" ac_try_dmas $card "$opts" $irq_list && return 0 done done return 1 } ac_try_card_cs4231 () { card=cs4231 irq_list=`check_irq_avail 5 7 9 11 12 15` for port in 0x530 0x534; do opts="${mpfx}port=$port" ac_try_dmas $card "$opts" $irq_list && return 0 done return 1 } ac_try_card_opl3sa2 () { card=opl3sa2 irq_list=`check_irq_avail 5 9 3 1 11 12 15 0` isapnp=`ac_check_option $card ${mpfx}isapnp 0` for port in 0x370 0x538 0xf86 0x100; do for wss_port in 0x530 0xe80 0xf40 0x604; do opts="${mpfx}fm_port=-1 ${mpfx}midi_port=-1 ${mpfx}port=$port ${mpfx}wss_port=$wss_port $isapnp" ac_try_dmas $card "$opts" $irq_list && return 0 done done return 1 } ac_config_legacy () { title=$(gettext "WARNING") msg=$(gettext " Probing legacy ISA cards might make your system unstable. Do you want to proceed? ") $DIALOG --title "$title" --yesno "$msg" 10 50 || acex 0 if [ x"$1" = x ]; then probe_list="$LEGACY_CARDS" else probe_list=$* fi menu_args=() for card in $probe_list; do cardname=`/sbin/modinfo -d snd-$card | sed -e 's/^\"\(.*\)\"$/\1/g'` if [ x"$cardname" != x ]; then menu_args=("${menu_args[@]}" "$card" "$cardname" "on") fi done if [ x$menu_args = x ]; then msg=$(gettext "No legacy drivers are available for your machine") $DIALOG --msgbox "$msg" 5 50 return 1 fi title=$(gettext "Driver Selection") msg=$(gettext " Probing legacy ISA cards Please select the drivers to probe:") $DIALOG --title "$title" --checklist "$msg" \ 17 64 8 "${menu_args[@]}" 2> $FOUND || acex 0 if [ $try_all_combination != 1 ]; then msg=$(gettext " Shall I try all possible DMA and IRQ combinations? With this option, some unconventional configuration might be found, but it will take much longer time.") if $DIALOG --yesno "$msg" 10 60 then try_all_combination=1 fi fi xecho "Probing legacy cards.. This may take a few minutes.." echo -n $(gettext "Probing: ") cards=`cat $FOUND | tr -d \"` for card in $cards; do echo -n " $card" ac_opts="" if eval ac_try_card_$card ; then xecho " : FOUND!!" ac_config_card $card $ac_opts return 0 fi done echo title=$(gettext "Result") msg=$(gettext "No legacy cards found") $DIALOG --title "$title" --msgbox "$msg" 5 50 return 1 } # # main part continued.. # if test -n "$LOGFILE" ; then touch "$LOGFILE" echo -n "Starting alsaconf: " >> "$LOGFILE" date >> "$LOGFILE" fi if [ x"$legacy_probe_card" != x ]; then ac_opts="" if eval ac_try_card_$legacy_probe_card >/dev/null 2>&1; then echo "$ac_opts" echo "$ac_cardname" exit 0 else echo "FAILED" exit 1 fi fi intro if [ $do_legacy_only = 1 ]; then ac_config_legacy exit 0 fi probe_cards devs_found=() devs_olist="" if [ -s "$FOUND" ]; then while read dev card ; do MODDIR=/lib/modules/`uname -r` find $MODDIR -type f | grep -q -E $card'\.(o|ko)' || continue cardname=`find_device_name $dev | cut -c 1-64` if [ -z "$cardname" ]; then cardname="$card" fi card=${card##snd-} devs_found=("${devs_found[@]}" "$card" "$cardname") devs_devs=("${devs_devs[@]}" "$card" "$dev") done <"$FOUND" devs_olist=`cat $FOUND` fi if [ x$devs_found != x ]; then # # check for TP600E # if [ ${devs_found[0]} = cs46xx ]; then if $lspci -nv 2>/dev/null| grep -q "Subsystem: 1014:1010"; then msg=$(gettext " Looks like you having a Thinkpad 600E or 770 notebook. On this notebook, CS4236 driver should be used although CS46xx chip is detected. Shall I try to snd-cs4236 driver and probe the legacy ISA configuration?") if $DIALOG --yesno "$msg" 13 60 then try_all_combination=1 ac_config_legacy cs4236 exit 0 fi elif $lspci -nv 2>/dev/null| grep -q "Subsystem: 8086:8080"; then msg=$(gettext " Looks like you having a Dell Dimension machine. On this machine, CS4232 driver should be used although CS46xx chip is detected. Shall I try to snd-cs4232 driver and probe the legacy ISA configuration?") if $DIALOG --yesno "$msg" 13 60 then try_all_combination=1 ac_config_legacy cs4232 exit 0 fi fi fi devs_found=("${devs_found[@]}" "legacy" "Probe legacy ISA (non-PnP) chips") title=$(gettext "Soundcard Selection") msg=$(gettext " Following card(s) are found on your system. Choose a soundcard to configure: ") $DIALOG --title "$title" --menu "$msg" 17 76 8 "${devs_found[@]}" --output-fd 3 3> $FOUND || acex 0 card=`head -n 1 $FOUND` if [ "$card" = "legacy" ]; then ac_config_legacy else ac_config_card "$card" fi exit 0 else msg=$(gettext " No supported PnP or PCI card found. Would you like to probe legacy ISA sound cards/chips? ") if $DIALOG --yesno "$msg" 9 60 ; then ac_config_legacy exit 0 fi fi rm -f "$FOUND" "$DUMP" exit 0