Как стать автором
Обновить
0
WestComp
WestComp — Вы нас нашли!

Тонкая настройка ACPI на примере Thinkpad X220

Время на прочтение 6 мин
Количество просмотров 27K

Лирика


За прошедшие пару месяцев мне довольно часто приходилось вступать в дискуссии о всевозможных портативных компьютерах: ломать копья в спорах какой производитель лучше и почему, обсуждать совместимость с GNU/Linux и то, как в этой системе настроить ту или иную функцию и, периодически, меня таки просят поделиться конфигами. Под влиянием этих самых обсуждений и родилась данная статья.

Большую часть своего компьютерного стажа я пользуюсь лаптопами так называемой «бизнес серии»: IBM ThinkPad 600, HP-Compaq nc2400, Lenovo ThinkPad X61T, Lenovo ThinkPad X220.



Были кратковременные перерывы, когда приходилось перебиваться абы-чем, то бишь компьютерами потребительского сегмента: Apple ibook G4 и Acer aspire 5112 и именно в эти моменты приходило понимание того, как сильно не хватает таких очевидных и привычных вещей, как трекпоинт и док-станция.



Что это такое? Подставка для лаптопа с разъемом питания и всевозможными дополнительными портами. В некоторые модели можно установить дополнительный жесткий диск или аккумулятор. Док-станция избавляет от необходимости каждый раз подключать весь набор кабелей, приходя на рабочее место и отсоединять, уходя.

Особенно удобна такая конфигурация под управлением GNU/Linux (в моем случае, Debian stable), где несколькими скриптами можно детально описать поведение компьютера.

Описание сценария работы


На работе я использую конфигурацию с внешним монитором и bluetooth клавиатурой Lenovo ThinkPad kt1255. Лаптоп практически никогда не выключается, вместо этого используется suspend to ram. Опишу сценарии обработчиков:

— Пробуждение в доке с закрытой крышкой: включить внешний монитор, активировать bluetooth и подключить клавиатуру, cpu performance
— Открытие крышки в доке: погасить внешний монитор и перевести изображение на внутренний
— Извлечение с открытой крышкой: дополнительно отключит клавиатуру и bt, cpu on-demand
— Извлечении с закрытой крышкой: залочить экран, перевести изображение на внутренний экран отключив внешний, вырубить клавиатуру и bt-модуль, cpu в on-demand, перейти в pm-suspend
— Закрытие крышки не в доке: блокировка экрана, pm-suspend

Непосредственно настройка


Какими-либо DE я не пользуюсь, да и не вижу смысла возлагать на них функцию управления питанием. Потому, настраивать будем средствами acpid.

Настройку начинаем, как обычно, с установки нужных программ:
#apt-get install acpid acpi-support cpufrequtils


Далее, смотрим какие события у нас генерятся при отстыковке лаптопа:
#acpi_listen
ac_adapter ACPI0003:00 00000080 00000000
ibm/hotkey LEN0068:00 00000080 00006030
thermal_zone LNXTHERM:00 00000081 00000000
battery PNP0C0A:00 00000080 00000001
ibm/hotkey LEN0068:00 00000080 00004011


При стыковке:
#acpi_listen
ibm/hotkey LEN0068:00 00000080 00004010
ac_adapter ACPI0003:00 00000080 00000001
ibm/hotkey LEN0068:00 00000080 00006030
thermal_zone LNXTHERM:00 00000081 00000000
battery PNP0C0A:00 00000080 00000001
button/lid LID close


Стоит отметить, что ThinkPad Mini Dock Series 3 не предоставляет proc интерфейса.

Напишем правила для событий:
#vim /etc/acpi/events/thinkpad-dock
event=ibm/hotkey LEN0068:00 00000080 00004010
action=/etc/acpi/thinkpad-dock.sh

#vim /etc/acpi/events/thinkpad-undock
event=ibm/hotkey LEN0068:00 00000080 00004011
action=/etc/acpi/thinkpad-undock.sh


Правило на закрытие крышки идет в комплекте с пакетом acpi-support. Приведем его к надлежащему виду, указав путь к скрипту-обработчику:
#vim /etc/acpi/events/lidbtn
event=button[ /]lid
action=/etc/acpi/lid.sh


А теперь перейдем к самому интересному: скриптам, описывающим реакцию на события при описанных выше условиях.

#vim /etc/acpi/lid.sh

#!/bin/bash

#проверяем, подключен ли лаптоп к док-станции
grep -q on /etc/tp_dock_state;
if [ $? = 0 ] 
	then
		#если да, проверяем открыта ли крышка
		grep -q open /proc/acpi/button/lid/*/state
		if [ $? = 0 ] 
		then
			#если да, включаем встроенный монитор, гасим внешний
			DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto'
			DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --off'
		else
			#если нет, включаем внешний, гасим встороенный
			DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --auto'
			DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --off'
			#включаем bluetooth-модуль и запускаем сервис
			echo enabled> /proc/acpi/ibm/bluetooth
			/etc/init.d/bluetooth start
			#подключаем bluetooth клавиатуру. 
			echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl
			#выставляем переключение раскладки по alt_gr, подгружаем кастомные биндинги
			DISPLAY=:0.0 su user -c 'setxkbmap -option grp:toggle us,ru'
			DISPLAY=:0.0 su user -c 'xmodmap ~/.xmodmaprc'
		fi
	else
		#если не подключен
		grep -q closed /proc/acpi/button/lid/*/state
		if [ $? = 0 ] 
		then
			#отключаем отключаем клавиатуру, останавливаем сервис и отключаем bt-модуль
			echo 'disconnect 90:7F:61:10:A3:BC'|bluetoothctl
			/etc/init.d/bluetooth stop
			echo disabled> /proc/acpi/ibm/bluetooth
			#вызываем с правами пользователя user блокировщик экрана
			DISPLAY=:0.0 su user -c /home/user/bin/lock
			#переводим изоражение на встроенный экран
			DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto'
			#отключаем внешний
			DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --off'
			#отправляем лаптоп спать
			pm-suspend
			#при пробуждении проверяем, в доке ли thinkpad:
			grep -q closed /proc/acpi/button/lid/*/state
			if [ $? = 0 ] 
			then
				#если да, то, сообщаем об этом:
				echo on >/etc/tp_dock_state
				#включаем внешний монитор и гасим встроенный
				DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --auto'
				DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --off'
				#включаем bt-модуль, запускаем сервис, подключаем bt-клавиатуру
				echo enabled> /proc/acpi/ibm/bluetooth
				/etc/init.d/bluetooth start
				echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl
				#подгружаем раскладку и биндинги
				DISPLAY=:0.0 su user -c 'setxkbmap -option grp:toggle us,ru'
				DISPLAY=:0.0 su user -c 'xmodmap ~/.xmodmaprc &'
			fi
	else
		#если нет, то просто включаем встроенный экран
		DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto'
	fi 


Поясню, на всякий случай, что 90:7F:61:10:A3:BC — это адрес моей клавиатуры. Настраиваются bluetooth устройства достаточно просто:
#apt-get install bluez
#bluetoothctl
[NEW] Controller 40:2C:F4:BB:3C:FC nethack [default]
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent 
Default agent request successful
[bluetooth]# scan on
Discovery started
[CHG] Controller 40:2C:F4:BB:3C:FC nethack [default]
[NEW] Device 90:7F:61:10:A3:BC ThinkPad Compact Bluetooth Keyboard with TrackPoint
[bluetooth]# pair 90:7F:61:10:A3:BC
Attempting to pair with 90:7F:61:10:A3:BC
[CHG] Device 90:7F:61:10:A3:BC Connected: yes
[agent] PIN code: 12345 #вводим с клавиатуры PIN
[bluetooth]# connect 90:7F:61:10:A3:BC
Attempting to connect to 90:7F:61:10:A3:BC
Connection successful


В дальнейшем, когда устройства связаны, достаточно передать
#echo 'connect 90:7F:61:10:A3:BC'| bluetoothctl

Чем мы в скриптах и пользуемся.

Опишем обработчик стыковки:
#vim /etc/acpi/thinkpad-dock.sh
#!/bin/sh

#сообщаем о стыковке
echo on >/etc/tp_dock_state

#переводим процессор в режим performance
cpufreq-set -c 0 -g performance
cpufreq-set -c 1 -g performance 
cpufreq-set -c 2 -g performance
cpufreq-set -c 3 -g performance 

#подключаем клавиатуру, на случай, если мы куда-нибудь уносили лаптоп
echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl


И отстыковки:
#vim /etc/acpi/thinkpad-undock.sh

#!/bin/bash

#сообщаем об отстыковке
echo off >/etc/tp_dock_state

#переводим процессор в экономичный режим
cpufreq-set -c 0 -g powersave
cpufreq-set -c 1 -g powersave 
cpufreq-set -c 2 -g powersave
cpufreq-set -c 3 -g powersave 

#проверяем, закрыта ли крышка:
grep -q closed /proc/acpi/button/lid/*/state
if [ $? = 0 ] 
then
		#если да, то вызываем локскрин
		DISPLAY=:0.0 su user -c /home/user/bin/lock
		#отключаем bt-клавиатуру, останавливаем сервис, отключаем модуль
		echo 'disconnect 90:7F:61:10:A3:BC'|bluetoothctl
		/etc/init.d/bluetooth stop
		echo disabled> /proc/acpi/ibm/bluetooth
		#переклюочаем изображение на встроенный экран
		DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto'
		DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --off'
		#усыпляем лаптоп
		pm-suspend
		#после пробуждения вновь проверяем, закрыта ли крышка
		grep -q closed /proc/acpi/button/lid/*/state
		if [ $? = 0 ] 
		then 
			#если да, то включаем внешний монитор и выключаем внутренний
			DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --auto'
			DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --off'
			#включаем bt-модуль, запускаем сервис, подключаем клавиатуру
			echo enabled> /proc/acpi/ibm/bluetooth
			/etc/init.d/bluetooth start
			echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl
			#сообщаем о стыковке
			echo on >/etc/tp_dock_state
fi
fi


Подводные камни


После обновления до debian 8, где в системе появился systemd, я столкнулся со следующей проблемой: при закрытии крышки, pm-suspend почему-то отрабатывал два раза. То есть выполнялся скрипт lid.sh, но параллельно с ним производилось действие pm-suspend без всяких скриптовых обвязок.

Главным подозреваемым, конечно же, стал новый инициализационный комбайн. И не зря: после десяти минут гугления выяснилось, что, оказывается, systemd пытается, до кучи, брать на себя и функцию по управлению событиями acpi, но делает это покамест не слишком хорошо: на данный момент не может обрабатывать события подключения адаптера питания и батареи.

Переписывать скрипты под новые веяния моды желание также не возникло, потому было проделано следующее:
#sed -i 's/HandleLidSwitch=yes/HandleLidSwitch=ignore/' /etc/systemd/logind.conf

Тем самым мы отучили systemd делать то, о чем не просят и все встало на круги своя. В принципе, то же самое стоит сделать с HandleSuspendKey, HandleHibernateKey и HandlePowerKey, если есть желание обрабатывать нажатия через acpid.

Заключение


Таким образом, получаем удобную конфигурацию, не требующую каких-то лишних рутинных манипуляций. Приходя утром на работу, я достаю лаптоп из рюкзака, вставляю его в док-станцию и нажимаю кнопку питания на этой самой док-станции, после чего работаю как со стационарным компьютером. Уходя, просто жму кнопку отстыковки и убираю компьютер в рюкзак.

Недостаток у такого подхода ровно один: вызывает сильное привыкание.
Теги:
Хабы:
+22
Комментарии 24
Комментарии Комментарии 24

Публикации

Информация

Сайт
westcomp.ru
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия

Истории