Linux内核中ideapad-laptop.c文件全解析7

本文深入分析了Linux内核中ideapad-laptop.c文件内的ideapad_kbd_bl_init函数,该函数负责键盘背光设备的初始化工作。文章详细介绍了函数内部的流程,包括亮度获取、设备注册等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接前一篇文章《Linux内核中ideapad-laptop.c文件全解析6》,地址为:

Linux内核中ideapad-laptop.c文件全解析6_蓝天居士的博客-优快云博客

上一篇分析了ideapad_input_init,本篇详细分析ideapad_kbd_bl_init。

  • ideapad_kbd_bl_init

ideapad_kbd_bl_init在同文件(drivers/platform/x86/ideapad-laptop.c)中实现,代码如下: 

static int ideapad_kbd_bl_init(struct ideapad_private *priv)
{
	int brightness, err;

	if (!priv->features.kbd_bl)
		return -ENODEV;

	if (WARN_ON(priv->kbd_bl.initialized))
		return -EEXIST;

	brightness = ideapad_kbd_bl_brightness_get(priv);
	if (brightness < 0)
		return brightness;

	priv->kbd_bl.last_brightness = brightness;

	priv->kbd_bl.led.name                    = "platform::" LED_FUNCTION_KBD_BACKLIGHT;
	priv->kbd_bl.led.max_brightness          = 1;
	priv->kbd_bl.led.brightness_get          = ideapad_kbd_bl_led_cdev_brightness_get;
	priv->kbd_bl.led.brightness_set_blocking = ideapad_kbd_bl_led_cdev_brightness_set;
	priv->kbd_bl.led.flags                   = LED_BRIGHT_HW_CHANGED;

	err = led_classdev_register(&priv->platform_device->dev, &priv->kbd_bl.led);
	if (err)
		return err;

	priv->kbd_bl.initialized = true;

	return 0;
}

static void ideapad_kbd_bl_exit(struct ideapad_private *priv)
{
	if (!priv->kbd_bl.initialized)
		return;

	priv->kbd_bl.initialized = false;

	led_classdev_unregister(&priv->kbd_bl.led);
}

如果kbd_bl.initialized为true,则说明已经做过初始化了,返回-EEXIST。这个逻辑要求系统只能有一个键盘背光设备。

ideapad_kbd_bl_brightness_get函数在同文件中实现,代码如下:

static int ideapad_kbd_bl_brightness_get(struct ideapad_private *priv)
{
	unsigned long hals;
	int err;

	err = eval_hals(priv->adev->handle, &hals);
	if (err)
		return err;

	return !!test_bit(HALS_KBD_BL_STATE_BIT, &hals);
}

eval_hals函数单独在一篇文章中介绍。

test_bit检测读取的hals中是否包含了HALS_KBD_BL_STATE_BIT。

设置kbd_bl.led的name为"platform::kbd_backlight"。LED_FUNCTION_KBD_BACKLIGHT宏定义在include/dt-bindings/leds/common.h中。

设置kbd_bl.led的max_brightness为1。

设置kbd_bl.led的brightness_get函数指针为ideapad_kbd_bl_led_cdev_brightness_get。ideapad_kbd_bl_led_cdev_brightness_get函数在同文件(drivers/platform/x86/ideapad-laptop.c)中定义,代码如下:

static enum led_brightness ideapad_kbd_bl_led_cdev_brightness_get(struct led_classdev *led_cdev)
{
	struct ideapad_private *priv = container_of(led_cdev, struct ideapad_private, kbd_bl.led);

	return ideapad_kbd_bl_brightness_get(priv);
}

设置kbd_bl.led的brightness_set_blocking函数指针为ideapad_kbd_bl_led_cdev_brightness_set。ideapad_kbd_bl_led_cdev_brightness_set函数在同文件(drivers/platform/x86/ideapad-laptop.c)中定义,代码如下:

static int ideapad_kbd_bl_led_cdev_brightness_set(struct led_classdev *led_cdev,
						  enum led_brightness brightness)
{
	struct ideapad_private *priv = container_of(led_cdev, struct ideapad_private, kbd_bl.led);

	return ideapad_kbd_bl_brightness_set(priv, brightness);
}

设置kbd_bl.led的flags为LED_BRIGHT_HW_CHANGED(include/linux/leds.h中定义:BIT(21))。

led_classdev_register函数也在include/linux/leds.h中定义和实现,代码如下:

/**
 * led_classdev_register - register a new object of LED class
 * @parent: LED controller device this LED is driven by
 * @led_cdev: the led_classdev structure for this device
 *
 * Register a new object of LED class, with name derived from the name property
 * of passed led_cdev argument.
 *
 * Returns: 0 on success or negative error value on failure
 */
static inline int led_classdev_register(struct device *parent,
					struct led_classdev *led_cdev)
{
	return led_classdev_register_ext(parent, led_cdev, NULL);
}

led_classdev_register_ext函数在drivers/leds/led-class.c中,代码较长,内容和知识点较多,放到下一篇文章中详述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值