Lenovo ThinkPad X1 Carbon (Gen 2)
| 硬件 | PCI/USB ID | 工作? |
|---|---|---|
| GPU | 8086:0a16 |
是 |
| 音频 | 8086:9c20 |
是 |
| Wi-Fi | 8086:08b2 |
是 |
| 以太网 | 8086:155a |
是 |
| WWAN | 1199:a001 |
是 |
| GPS | 未测试 | |
| 蓝牙 | 8087:07dc |
是 |
| 摄像头 | 04ca:7036 |
是 |
| 指纹识别器 | 138a:0017 |
是 |
| 触控板 | 是 | |
| 触摸屏 | 是 |
几乎所有功能开箱即用。大多数硬件基于 Intel Lynx Point 参考设计。
电源管理
内核模块 thinkpad_acpi 拾取大多数传感器。当前不支持内核模块 tp_smapi。PCIe ASPM 当前无法工作。
Udev 不会在电池电量减少 1% 时发出通知,但会在 80%、20%、5%、4% 和 0% 时发出通知。要利用这一点,请参阅(低电量时挂起 Laptop#Hibernate on low battery level)
从挂起唤醒
从挂起唤醒在早期版本的 bios 中可能存在错误,请参阅:[1]
这可以通过将 bios 刷新到 >=1.13 版本来解决。在此处查找联想的 bios 版本:[2]
有关如何制作可引导 BIOS 密钥驱动器的指南,请参见此处:[3]
以及联想在此处提供的一些相当旧的帮助:[4]
如果功能键在挂起后无法唤醒,请确保您的内核版本 >=3.15。
如果您构建自己的内核,请确保启用 TPM(可信平台模块)驱动程序或在 BIOS 中禁用安全芯片。
键盘
在内核 3.14 及更低版本中,键盘顶部的自适应面板锁定为功能模式。
从内核 3.15 开始,主页模式也可用,允许访问屏幕亮度和其它控件。
如果您希望重新映射按键以恢复到合理的键盘布局,您可以使用 xmodmap 或其它 输入重映射工具。
打字时自动打开键盘背光
键盘背光开箱即用,软键盘上有一个按钮可以在关闭、低亮度和高亮度之间切换。使用持续检查键盘输入的 C 程序,可以仅在特定时间激活背光。
程序源代码如下
kbdbacklight.c
/* Original Author: Howard Chu <hyc@symas.com> 2013-01-15
*
* compile as "gcc -O2 -o kbdbacklight kbdbacklight.c" and run it in the background, or arrange to have it run at bootup.
*
* adapted by gabtub@gmail.com 2017-01-22
* using https://gist.github.com/hadess/6847281
* based on http://askubuntu.com/questions/383501/enable-the-keyboard-backlights-on-supported-lenovo-e-g-carbon-x1-with-command
* original code found at http://forum.notebookreview.com/threads/asus-keyboard-backlight-controller.703985/
* sigterm catching done as shown in https://airtower.wordpress.com/2010/06/16/catch-sigterm-exit-gracefully/
*
* fixed by sva 2022-10-08
* refactored the whole code out of boredom. keyboard should now be detected automatically using libudev.h 2023-06-25
* uses /sys/class/leds/, s.t. ec_sys is not necessary
*
* monitor keyboard activity and toggle keyboard backlight
*/
#include <stdio.h> // fprintf(), snprintf(), stderr
#include <unistd.h> // write(), close(), read()
#include <string.h> // strlen(), strncpy()
#include <fcntl.h> // open(), O_RDONLY, O_WRONLY
#include <limits.h> // PATH_MAX
#include <poll.h> // poll()
#include <linux/input.h> // struct input_event, EV_KEY
#include <libudev.h> // udev stuff
#define IDLE_MSEC 1000
#define BRGHT_OFF 0
#define BRGHT_MED 128
#define BRGHT_HI 255
static volatile int running = 1;
static int find_keyboard(char* devnode, size_t size) {
struct udev* udev = udev_new();
if (!udev) {
fprintf(stderr, "Failed to create udev context\n");
return -1;
}
struct udev_enumerate* enumerate = udev_enumerate_new(udev);
if (!enumerate) {
fprintf(stderr, "Failed to create udev enumerate\n");
udev_unref(udev);
return -1;
}
udev_enumerate_add_match_subsystem(enumerate, "input");
udev_enumerate_add_match_property(enumerate, "ID_INPUT_KEYBOARD", "1");
udev_enumerate_scan_devices(enumerate);
struct udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate);
struct udev_list_entry* entry;
int found = 0;
udev_list_entry_foreach(entry, devices) {
const char* path = udev_list_entry_get_name(entry);
struct udev_device* dev = udev_device_new_from_syspath(udev, path);
if (!dev) {
fprintf(stderr, "Failed to create udev device\n");
continue;
}
const char* devnode_path = udev_device_get_devnode(dev);
if (devnode_path) {
if (strlen(devnode_path) < size) {
strncpy(devnode, devnode_path, size);
found = 1;
break;
} else {
fprintf(stderr, "Device node path is too long\n");
}
}
udev_device_unref(dev);
}
udev_enumerate_unref(enumerate);
udev_unref(udev);
return found ? 0 : -1;
}
static int set_backlight(int brightness) {
char buf[16];
snprintf(buf, sizeof(buf), "%d", brightness);
int fd = open("/sys/class/leds/tpacpi::kbd_backlight/brightness", O_WRONLY);
if (fd < 0) {
fprintf(stderr, "Failed to open keyboard backlight file\n");
return -1;
}
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
fprintf(stderr, "Failed to set keyboard backlight\n");
close(fd);
return -1;
}
close(fd);
return 0;
}
static void handle_input(int fd, int* brightness) {
struct input_event ev;
int rc = read(fd, &ev, sizeof(ev));
if (rc > 0) {
if (ev.type == EV_KEY && ev.value == 1) {
set_backlight(BRGHT_HI);
*brightness = BRGHT_HI;
}
}
}
static void handle_timeout(int fd, int* brightness) {
set_backlight(BRGHT_OFF);
*brightness = BRGHT_OFF;
}
static void handle_poll(int fd, int* brightness) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
int timeout = IDLE_MSEC;
while (running) {
int rc = poll(&pfd, 1, timeout);
if (rc > 0) {
handle_input(fd, brightness);
timeout = IDLE_MSEC;
} else if (rc == 0) {
handle_timeout(fd, brightness);
timeout = -1;
}
}
}
int main(int argc, char** argv) {
char devnode[PATH_MAX];
if (find_keyboard(devnode, sizeof(devnode)) < 0) {
fprintf(stderr, "Failed to find keyboard device\n");
return 1;
}
int fd = open(devnode, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Failed to open keyboard device\n");
return 1;
}
int brightness = BRGHT_OFF;
set_backlight(brightness);
handle_poll(fd, &brightness);
close(fd);
return 0;
}
此文件可以使用以下命令编译
$ gcc -O2 -o kbdbacklight kbdbacklight.c -ludev
并且必须以 root 身份执行。
可以通过创建 systemd 服务来自动启动它,如下所示
- 创建一个文件夹 /usr/local/customscripts/kbdbacklight/
- 将编译后的 c 程序保存到 /usr/local/customscripts/kbdbacklight/kbdbacklight
- 在同一文件夹中创建以下 bash 脚本
/usr/local/customscripts/kbdbacklight/kbdbacklight.sh
#!/bin/bash # must be executed as root ./kbdbacklight & RETVAL=$? PID=$! [ $RETVAL -eq 0 ] && echo $PID > /usr/local/customscripts/kbdbacklight/pid
- 创建以下 systemd 服务并将其放置在 /etc/systemd/system/kbdbacklight.service 中
/etc/systemd/system/kbdbacklight.service
[Unit] Description=starts a daemon monitoring keyboard usage. will turn on keyboard backlight until no key is pressed for a TIMEOUT period Requires= After= [Service] Type=forking User=root WorkingDirectory=/usr/local/customscripts/kbdbacklight/ ExecStart=/usr/local/customscripts/kbdbacklight/kbdbacklight.sh & PIDFile=/usr/local/customscripts/kbdbacklight/pid [Install] WantedBy=multi-user.target
- 启动/启用
kbdbacklight.service
触控板
要启用触控板支持,您需要安装 xf86-input-synaptics。
点击时锁定
触控板在点击时锁定存在重大问题。这是由于触控板在有缺陷的 PS/2 模式下运行。
一种替代方法是完全放弃触控板并使用指点杆。确保未安装 xf86-input-synaptics - 触控板仍会注册鼠标左键单击。使用 xbindkeys Xbindkeys 和 xdotool,可以将右键单击映射到其它事件。例如
~/.xbindkeysrc
# Emit a right click on Alt + trackpad click "xdotool click 3" Mod1 + b:1 + Release
调整触控板行为
默认情况下,触控板的行为可能与您的期望相反,特别是如果您来自 OS X 风格的触控板。以下设置可以显著帮助
/etc/X11/xorg.conf.d/99-x1carbon.conf
# Copy this to /etc/X11/xorg.conf.d/99-x1carbon.conf
Section "InputClass"
Identifier "X1 carbon stuff"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "synaptics"
# Enable two finger scrolling vertically, disable horizontally
Option "VertTwoFingerScroll" "1"
Option "HorizTwoFingerScroll" "0"
# No scrolling along the edge
Option "VertEdgeScroll" "0"
Option "HorizEdgeScroll" "0"
Option "LockedDrags" "0"
Option "FingerPress" "1"
# Turn off the blasted corners as buttons
Option "RTCornerButton" "0"
Option "RBCornerButton" "0"
Option "LTCornerButton" "0"
Option "LBCornerButton" "0"
# Ignore "taps" and listen for "clicks"
Option "TapButton1" "0"
Option "TapButton2" "0"
Option "TapButton3" "0"
Option "ClickFinger1" "1" # Left click one finger
Option "ClickFinger2" "3" # Right click two fingers
Option "ClickFinger3" "0" # Three finger click disabled
Option "TapAndDragGesture" "0"
# No circular scrolling
Option "CircularScrolling" "0"
EndSection
如果您使用 gnome-shell,您可能需要告知设置应用不要覆盖我们的更改
$ gsettings set org.gnome.settings-daemon.plugins.mouse active false
从睡眠唤醒后触控板无法工作
参见 Touchpad Synaptics#从休眠/挂起恢复后触控板无法工作。
音频
您可能需要在其 内核模块参数 中添加默认声卡选项
/etc/modprobe.d/alsa-base.conf
options snd_hda_intel index=1
ALSA 前置放大器
在运行 Linux 的笔记本电脑上,一个常见的问题是声音即使调到最大也不够大。这可以通过添加 ALSA 前置放大器来解决。
安装 alsa-utils。
将 /etc/asound.conf 中的配置更改为以下内容(您可能必须调整卡号)
# Set your DEFAULT device to the softvol plug-in
# NOT to a hardware card device
#
# The "!" means completely override the previous default
# Not just changing/adding to it.
pcm.!default {
type plug
slave.pcm "softvol"
}
# Configure softvol
pcm.softvol {
type softvol
# Send softvol's output to dmix
slave {
pcm "dmix"
# If you wanted to you could send the output to a card directly
# But in most cases it's better to send it to dmix and let
# dmix handle where to send it. You can add a whole extra section
# to configure dmix and where it sends output, but I'm
# not covering that here.
## Use Card 0 Device 0 instead of dmix
# pcm "hw:0,0"
## Use Card 2 Device 0 instead of dmix
# pcm "hw:2,0"
}
# Add a control slider in your mixer interfaces
# i.e. KMix and alsamixer
control {
name "Pre-Amp"
card 0 #<CardNumberYouWantControlToShowOn> i.e. card 0 or card 2
}
# Minimum dB when slider is at 0%
min_dB -5.0
# Maximum DB when slider is at 100%
max_dB 40.0
# How many levels the slider should go through
# i.e. how granular do you want your control to be
resolution 12
}
摘自 此处。
处理器
参见 微码 了解如何更新到处理器的微码。
BIOS 更新
要从 Linux 安装 BIOS 更新,请从此处下载可引导 iso
由于没有光驱,因此可以使用此方法(德语)。
网络
有线
右侧有一个用于以太网的小端口。需要一个适配器。如果适配器丢失,订购的零件编号为 04X6435。
无线
开箱即用。模块 iwlwifi 应该由 udev 自动加载。
$ lspci
Network controller: Intel Corporation Wireless 7260 (rev 83)
显示
触摸屏
开箱即用,支持单点触控。硬件是多点触控,但当前稳定的驱动程序仅支持鼠标左键单击模拟。似乎可以使用 Touchegg。
HiDPI
由于显示器具有如此高的像素密度,您可能会遇到问题。请参阅此处:HiDPI