1123626Snjl#!/bin/sh
2123626Snjl#
3123626Snjl# Modify the power profile based on AC line state.  This script is
4123626Snjl# usually called from devd(8).
5123626Snjl#
6123626Snjl# Arguments: 0x00 (AC offline, economy) or 0x01 (AC online, performance)
7123626Snjl#
8123626Snjl# $FreeBSD$
9123626Snjl#
10123626Snjl
11123626Snjl# PROVIDE: power_profile
12168283Sdes# REQUIRE: FILESYSTEMS syslogd
13136224Smtm# KEYWORD: nojail nostart
14123626Snjl
15123626Snjl. /etc/rc.subr
16123626Snjl
17123626Snjlname="power_profile"
18298514Slmedesc="Modify the power profile based on AC line state"
19174464Sdougbstop_cmd=':'
20123626SnjlLOGGER="logger -t power_profile -p daemon.notice"
21123626Snjl
22123626Snjl# Set a given sysctl node to a value.
23123626Snjl#
24123626Snjl# Variables:
25123626Snjl# $node: sysctl node to set with the new value
26123626Snjl# $value: HIGH for the highest performance value, LOW for the best
27123626Snjl#	  economy value, or the value itself.
28123626Snjl# $highest_value: maximum value for this sysctl, when $value is "HIGH"
29123626Snjl# $lowest_value: minimum value for this sysctl, when $value is "LOW"
30123626Snjl#
31238416Skevlosysctl_set()
32123626Snjl{
33123626Snjl	# Check if the node exists
34123626Snjl	if [ -z "$(sysctl -n ${node} 2> /dev/null)" ]; then
35123626Snjl		return
36123626Snjl	fi
37123626Snjl
38123626Snjl	# Get the new value, checking for special types HIGH or LOW
39123626Snjl	case ${value} in
40123626Snjl	[Hh][Ii][Gg][Hh])
41123626Snjl		value=${highest_value}
42123626Snjl		;;
43123626Snjl	[Ll][Oo][Ww])
44123626Snjl		value=${lowest_value}
45123626Snjl		;;
46142572Snjl	[Nn][Oo][Nn][Ee])
47142572Snjl		return
48142572Snjl		;;
49123626Snjl	*)
50123626Snjl		;;
51123626Snjl	esac
52123626Snjl
53123626Snjl	# Set the desired value
54179965Smtm	if [ -n "${value}" ]; then
55179965Smtm		if ! sysctl ${node}=${value} > /dev/null 2>&1; then
56179965Smtm			warn "unable to set ${node}=${value}"
57179965Smtm		fi
58179965Smtm	fi
59123626Snjl}
60123626Snjl
61123626Snjlif [ $# -ne 1 ]; then
62123626Snjl	err 1 "Usage: $0 [0x00|0x01]"
63123626Snjlfi
64123626Snjlload_rc_config $name
65123626Snjl
66123626Snjl# Find the next state (performance or economy).
67123626Snjlstate=$1
68123626Snjlcase ${state} in
69123626Snjl0x01 | '')
70123626Snjl	${LOGGER} "changed to 'performance'"
71123626Snjl	profile="performance"
72123626Snjl	;;
73123626Snjl0x00)
74123626Snjl	${LOGGER} "changed to 'economy'"
75123626Snjl	profile="economy"
76123626Snjl	;;
77123626Snjl*)
78123626Snjl	echo "Usage: $0 [0x00|0x01]"
79123626Snjl	exit 1
80123626Snjlesac
81123626Snjl
82123626Snjl# Set the various sysctls based on the profile's values.
83123626Snjlnode="hw.acpi.cpu.cx_lowest"
84129021Snjlhighest_value="C1"
85240343Savglowest_value="Cmax"
86123626Snjleval value=\$${profile}_cx_lowest
87123626Snjlsysctl_set
88123626Snjl
89141417Snjlnode="dev.cpu.0.freq"
90142523Snjlhighest_value="`(sysctl -n dev.cpu.0.freq_levels | \
91142523Snjl	awk '{ split($0, a, "[/ ]"); print a[1] }' -) 2> /dev/null`"
92142523Snjllowest_value="`(sysctl -n dev.cpu.0.freq_levels | \
93238009Ssbruno	awk '{ split($0, a, "[/ ]"); print a[length(a) - 1] }' -) 2> /dev/null`"
94141417Snjleval value=\$${profile}_cpu_freq
95123626Snjlsysctl_set
96123626Snjl
97123626Snjlexit 0
98