[ltp] Script to manage ACPI Events on T42
Jerome Poggi
linux-thinkpad@linux-thinkpad.org
Mon, 21 Mar 2005 13:14:27 +0100
I work a lot on ACPI event, and what do I must do when event arrive.
With all of this avent I done a single script, and I share it, so
allbody can use some part or all parts.
It's a little personnalised, so you must review the code to see if
somethink don't work correctly.
the module ibm-acpi is loaded with this parameters :
experimental=1 hotkey=enable,0x087c
If some key don't work or don't send ACPI event, try to put hotkey to
0xFFFF, and retry. If it's the same problem, you must need to upgrade
your Bios and Embedded Controller.
Jerome.
--
Jerome POGGI Jerome.Poggi@hsc.fr
Herve Schauer Consultants -=- Network security consultant, CISSP
http://www.hsc.fr/ Tel : +33 141 409 700
----- 8< --- Cut Here --- 8< -----
#!/bin/sh
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-apps/acpid/files/acpid-1.0.4-default.sh,v 1.1 2004/10/19 08:07:45 brix Exp $
# Default acpi script that takes an entry for all actions
#
# JP : Version 1.1 - Initial Version
# JP : Version 1.2 - English Version and more generic
set $*
group=${1/\/*/}
action=${1/*\//}
element=$2
param1=$3
param2=$4
# ONLY FOR DEBUG
#logger "ACPI : group='$group' action='$action' element='$2' param1='$3' param2='$4'"
ALARM_LOW=11
ALARM_VERY_LOW=6
WIFI_MODULE=ipw2200
MY_LOGON=poggi
single_beep()
{
echo 3 > /proc/acpi/ibm/beep
}
high_low_beep()
{
echo 4 > /proc/acpi/ibm/beep
}
high_beep()
{
echo 7 > /proc/acpi/ibm/beep
}
triple_beep()
{
echo 9 > /proc/acpi/ibm/beep
}
low_beep()
{
echo 12 > /proc/acpi/ibm/beep
}
button_sleep()
{
/usr/bin/logger "Fn+F4 Suspending to RAM"
single_beep
/usr/sbin/dodo # Call my script to go to Sleep State
/usr/bin/logger "Resuming from Fn+F4 Suspending to RAM"
}
button_hybernate()
{
logger "Switching to ACPI S4 Mode - Hybernation"
single_beep
/usr/sbin/hybernate # Call my script to go to Hybernate State
}
button_lid()
{
STATE_LIC=`cat /proc/acpi/button/lid/LID/state | sed 's/.* //'`
logger "ACPI : Screen $STATE_LIC"
single_beep
if [ "$STATE_LIC" = "open" ]
then
/usr/bin/radeontool light on
else
/usr/bin/radeontool light off
PID=`pidof /usr/X11R6/bin/X`
AUTH=`perl -ne'/\x00-auth\x00(.*?)\x00.*/&&print$1' /proc/$PID/cmdline`
if [ x"$AUTH" = x ]; then
AUTH=`perl -ne'/(^|\x00)XAUTHORITY=(.*?)\x00/&&print$2' /proc/$PID/environ`
fi
export XAUTHORITY=$AUTH
/usr/X11R6/bin/xset -display :0 dpms force standby
fi
}
button_power()
{
if [ -e /var/run/PowerOFF_wanted ]
then
logger "PowerOFF Canceled"
high_low_beep
#shutdown -c
rm -f /var/run/PowerOFF_wanted
else
touch /var/run/PowerOFF_wanted
chmod 600 /var/run/PowerOFF_wanted
triple_beep
logger "Power OFF !"
#shutdown -hFP -t 15
fi
}
blank_DPMS()
{
PID=`pidof /usr/X11R6/bin/X`
AUTH=`perl -ne'/\x00-auth\x00(.*?)\x00.*/&&print$1' /proc/$PID/cmdline`
if [ x"$AUTH" = x ]; then
AUTH=`perl -ne'/(^|\x00)XAUTHORITY=(.*?)\x00/&&print$2' /proc/$PID/environ`
fi
export XAUTHORITY=$AUTH
/usr/X11R6/bin/xset -display :0 dpms force standby
}
CheckBattery()
{
ACPI_BATTERY=`acpi -b`
logger ${ACPI_BATTERY}
STATE_BATTERY1=`echo ${ACPI_BATTERY} | grep "Battery 1" | cut -d':' -f2 | cut -d',' -f1-2`
STATE_BATTERY2=`echo ${ACPI_BATTERY} | grep "Battery 2" | cut -d':' -f2 | cut -d',' -f1-2`
if [ -z ${STATE_BATTERY2} ]
then
POWER_BAT1=`echo ${STATE_BATTERY1} | cut -d',' -f2 | sed 's/%//;s/ //'`
STATE_BAT1=`echo ${STATE_BATTERY1} | cut -d',' -f1 | sed 's/ //'`
if [ "$STATE_BAT1" = "discharging" ]
then
if [ $POWER_BAT1 -lt $ALARM_LOW ]
then
triple_beep
echo -n "1 blink" > /proc/acpi/ibm/led
echo -n "2 blink" > /proc/acpi/ibm/led
DISPLAY=:0 /usr/X11R6/bin/xmessage -center -nearmouse -timeout 5 "===== URGENT !!! Battery LOW ===="
logger "===== URGENT !!! Battery LOW ===="
echo "===== URGENT !!! Battery LOW ====" | wall
blank_DPMS
fi
if [ $POWER_BAT1 -lt $ALARM_VERY_LOW ]
then
triple_beep
echo -n "0 blink" > /proc/acpi/ibm/led
logger "ACPI : BackLight is OFF"
/usr/bin/radeontool light off
logger "===== URGENT !!! Go to Hybernation ====="
echo "===== URGENT !!! Go to Hybernation =====" | wall
button_hybernate
exit 0
fi
fi
fi
}
battery_battery()
{
cat /proc/acpi/ac_adapter/AC/state | grep "on-line" > /dev/null 2>&1
ret=$?
[[ -e /proc/acpi/battery/BAT0/state ]] && BAT0_PRESENT=1 || BAT0_PRESENT=0
[[ -e /proc/acpi/battery/BAT1/state ]] && BAT1_PRESENT=1 || BAT1_PRESENT=0
# Si on est sur batterie
if [ $BAT0_PRESENT = 1 -a $BAT1_PRESENT = 1 ]
then
[[ $element = BAT1 ]] && logger `acpi`
else
CheckBattery
fi
}
ac_adapter_ac_adapter()
{
ACAD_HD=12
BATT_HD=1
ACAD_DPMS="120 300 1200"
BATT_DPMS="60 120 300"
if [ "$param2" = "00000001" ]
then
logger "On-Line AC"
echo -n "0 on" > /proc/acpi/ibm/led
hdparm -S $ACAD_HD /dev/hda > /dev/null
hdparm -B 255 /dev/hda > /dev/null
/usr/sbin/laptop_mode stop
#/usr/bin/speedfreq -p performance
echo -n "ondemand" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo -n "level 7" > /proc/acpi/ibm/brightness
echo -n $ACAD_THR > /proc/acpi/processor/CPU/throttling
echo -n enable > /proc/acpi/ibm/fan
if [ -e /tmp/.X0-lock ]; then
su - ${MY_LOGON} -c "DISPLAY=:0.0 /usr/X11R6/bin/xmessage -center -nearmouse -timeout 3 'On-Line AC'"
su - ${MY_LOGON} -c "DISPLAY=:0.0 /usr/X11R6/bin/xset -display :0 dpms $ACAD_DPMS"
fi
else
logger "Switching to Battery"
echo -n "0 off" > /proc/acpi/ibm/led
# Alarm at 4100mw of remaining capacity not 2000mw, it's 10% for a 6 cell battery
echo "4100" > /proc/acpi/battery/BAT0/alarm
hdparm -S $BATT_HD /dev/hda > /dev/null
hdparm -B 1 /dev/hda > /dev/null
/usr/sbin/laptop_mode start
echo -n "powersave" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
#/usr/bin/speedfreq -p powersave
echo "level 2" > /proc/acpi/ibm/brightness
echo -n disable > /proc/acpi/ibm/fan
echo -n $BATT_THR > /proc/acpi/processor/CPU/throttling
if [ -e /tmp/.X0-lock ]; then
su - ${MY_LOGON} -c "DISPLAY=:0 /usr/X11R6/bin/xmessage -center -nearmouse -timeout 3 'Switching to Battery'"
su - ${MY_LOGON} -c "DISPLAY=:0.0 /usr/X11R6/bin/xset -display :0 dpms $BATT_DPMS"
fi
fi
}
processor_processor()
{
TRIP_POINT=`grep passive /proc/acpi/thermal_zone/THM0/trip_points | sed 's/passive: *//;s/C:.*/C/'`
TEMPERATURE=`sed 's/.*: *//' /proc/acpi/thermal_zone/THM0/temperature`
case "$param2" in
00000005)
echo enable > /proc/acpi/ibm/fan
triple_beep
logger "ACPI : TEMPERATURE TOO HIGHT > ${TRIP_POINT} (${TEMPERATURE}) - Safety Mode"
triple_beep
;;
00000000)
logger "ACPI : CPU Temperature OK : ${TEMPERATURE}"
single_beep
;;
*)
logger "ACPI : group='$group' action='$action' element='$2' param1='$3' param2='$4'"
;;
esac
}
thermal_zone_thermal_zone()
{
echo enable > /proc/acpi/ibm/fan
# When Critical temperature reached, and go to S5 state : Forced Shutdown
logger "ACPI : group='$group' action='$action' element='$2' param1='$3' param2='$4'"
logger " TripPoints was : `cat /proc/acpi/thermal_zone/THM0/trip_points`"
logger " Temperature was : `sed 's/.*: *//' /proc/acpi/thermal_zone/THM0/temperature`"
logger "The shutdown is a protective procedure and can't STOP"
logger " GoogBye, and put me in the refrigerator :-)"
}
swap_screen()
{
status=`/bin/awk '/^(lcd|crt):/ { ORS=""; print $2 }' /proc/acpi/ibm/video`
if [ "$status" == "enableddisabled" ]; then
/bin/echo lcd_disable,crt_enable >/proc/acpi/ibm/video
MSG="LCD OFF / CRT ON"
elif [ "$status" == "disabledenabled" ]; then
/bin/echo lcd_enable >/proc/acpi/ibm/video
MSG="LCD ON / CRT ON"
elif [ "$status" == "enabledenabled" ]; then
/bin/echo crt_disable >/proc/acpi/ibm/video
MSG="LCD ON / CRT OFF"
fi
logger "ACPI : Switching screen " $MSG
}
ibm_hotkey()
{
case "$param2" in
00001003) # Fn + F3
STATE_SCREEN=`radeontool light | awk '{print $5}'`
if [ "$STATE_SCREEN" = "on" ]
then
logger "ACPI : Turn OFF BackLight"
/usr/bin/radeontool light off
else
logger "ACPI : Turn ON BackLight"
/usr/bin/radeontool light on
fi
;;
00001004) # Fn + F4
logger "ACPI : Go to sleep state"
button_sleep
;;
00001005) # Fn + F5
STATE_BLUETOOTH=`grep status /proc/acpi/ibm/bluetooth | sed 's/.*\t//'`
if [ "$STATE_BLUETOOTH" = "disabled" ]
then
logger "ACPI : Turn ON BlueTooth"
echo "enabled" > /proc/acpi/ibm/bluetooth
single_beep
else
logger "ACPI : Turn OFF BlueTooth"
echo "disabled" > /proc/acpi/ibm/bluetooth
modprobe -r hci_usb
modprobe -r bluetooth
low_beep
fi
;;
00001006) # Fn + F6
STATE_IPW2200=`lsmod | grep "^${WIFI_MODULE}" 2>/dev/null`
if [ "$STATE_IPW2200" = "" ]
then
logger "ACPI : Turn ON Wi-Fi (module+rf)"
modprobe -s ${WIFI_MODULE}
sleep 0.5
echo -n "0" > /sys/bus/pci/devices/0000:00:1e.0/0000:02:02.0/rf_kill
single_beep
else
STATE_RF_WIFI=`cat /sys/bus/pci/devices/0000:00:1e.0/0000:02:02.0/rf_kill`
if [ $STATE_RF_WIFI = 0 ]
then
logger "ACPI : Turn OFF Wi-Fi (module+rf)"
echo -n "1" > /sys/bus/pci/devices/0000:00:1e.0/0000:02:02.0/rf_kill
sleep 0.5
modprobe -s -r ${WIFI_MODULE}
low_beep
else
logger "ACPI : Turn ON Wi-Fi (rf)"
echo -n "0" > /sys/bus/pci/devices/0000:00:1e.0/0000:02:02.0/rf_kill
single_beep
fi
fi
;;
00001007) # Fn + F7
swap_screen
;;
0000100c) # Fn + F12
logger "ACPI : Switching to Hybernate state"
button_hybernate
;;
0000100d) ;; # Fn + BackSpc
0000100e) ;; # Fn + Insert
0000100f) ;; # Fn + Suppr
00001010) ;; # Fn + End
00005001) ;; # Ecran Ferme
00005002) ;; # Ecran Ouvert
*) logger "ACPI hotkey KEY $param2 is not configured";;
esac
}
ibm_bay()
{
case "$param1" in
00000001)
logger "BAY will be inserted"
/bin/sleep 1
/bin/sync
/sbin/idectl 1 rescan
;;
00000003)
logger "BAY will be ejected"
/bin/sync
/sbin/idectl 1 off
/bin/echo eject > /proc/acpi/ibm/bay
;;
*) logger "ACPI ibm/bay $param1 is not configured";;
esac
}
case "$group" in
button)
case "$action" in
power) button_power;;
sleep) button_sleep;;
lid) button_lid;;
*) logger "ACPI action ${group}/${action} is not defined";;
esac
;;
battery)
case "$action" in
battery) battery_battery;;
*) logger "ACPI action ${group}/${action} is not defined";;
esac
;;
ac_adapter)
case "$action" in
ac_adapter) ac_adapter_ac_adapter;;
*) logger "ACPI action ${group}/${action} is not defined";;
esac
;;
ibm)
case "$action" in
hotkey) ibm_hotkey;;
bay) ibm_bay;;
*) logger "ACPI action ${group}/${action} is not defined";;
esac
;;
processor)
case "$action" in
processor) processor_processor;;
*) logger "ACPI action ${group}/${action} is not defined";;
esac
;;
thermal_zone)
case "$action" in
thermal_zone) thermal_zone_thermal_zone;;
*) logger "ACPI action ${group}/${action} is not defined";;
esac
;;
*)
logger "ACPI group $group / action $action is not defined"
;;
esac