led_classdev 结构体

Linux version: 4.14

Code link: Linux source code (v4.14) - Bootlin


struct led_classdev {
	const char		*name;                       // 设备名字
	enum led_brightness	 brightness;             // LED 默认亮度
	enum led_brightness	 max_brightness;         // LED 的最大亮度
	int			 flags;

	/* Lower 16 bits reflect status */
#define LED_SUSPENDED		(1 << 0)
#define LED_UNREGISTERING	(1 << 1)
	/* Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME	(1 << 16)
#define LED_SYSFS_DISABLE	(1 << 17)
#define LED_DEV_CAP_FLASH	(1 << 18)
#define LED_HW_PLUGGABLE	(1 << 19)
#define LED_PANIC_INDICATOR	(1 << 20)
#define LED_BRIGHT_HW_CHANGED	(1 << 21)
#define LED_RETAIN_AT_SHUTDOWN	(1 << 22)

	/* set_brightness_work / blink_timer flags, atomic, private. */
	unsigned long		work_flags;

#define LED_BLINK_SW			0
#define LED_BLINK_ONESHOT		1
#define LED_BLINK_ONESHOT_STOP		2
#define LED_BLINK_INVERT		3
#define LED_BLINK_BRIGHTNESS_CHANGE 	4
#define LED_BLINK_DISABLE		5

	/* Set LED brightness level
	 * Must not sleep. Use brightness_set_blocking for drivers
	 * that can sleep while setting brightness.
	 */
    // 用于设置 LED 亮度的函数指针,不可休眠
	void		(*brightness_set)(struct led_classdev *led_cdev,
					  enum led_brightness brightness);
	/*
	 * Set LED brightness level immediately - it can block the caller for
	 * the time required for accessing a LED device register.
	 */
    // 用于设置 LED 亮度的函数指针,可以休眠
	int (*brightness_set_blocking)(struct led_classdev *led_cdev,
				       enum led_brightness brightness);
	/* Get LED brightness level */
    // 获取 LED 亮度
	enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);

	/*
	 * Activate hardware accelerated blink, delays are in milliseconds
	 * and if both are zero then a sensible default should be chosen.
	 * The call should adjust the timings in that case and if it can't
	 * match the values specified exactly.
	 * Deactivate blinking again when the brightness is set to LED_OFF
	 * via the brightness_set() callback.
	 */
	int		(*blink_set)(struct led_classdev *led_cdev,
				     unsigned long *delay_on,
				     unsigned long *delay_off);

	struct device		*dev;
	const struct attribute_group	**groups;

	struct list_head	 node;			/* LED Device list */
	const char		*default_trigger;	/* Trigger to use */

	unsigned long		 blink_delay_on, blink_delay_off;
	struct timer_list	 blink_timer;
	int			 blink_brightness;
	int			 new_blink_brightness;
	void			(*flash_resume)(struct led_classdev *led_cdev);

	struct work_struct	set_brightness_work;
	int			delayed_set_value;

#ifdef CONFIG_LEDS_TRIGGERS
	/* Protects the trigger data below */
	struct rw_semaphore	 trigger_lock;

	struct led_trigger	*trigger;
	struct list_head	 trig_list;           
	void			*trigger_data;           
	/* true if activated - deactivate routine uses it to do cleanup */
	bool			activated;
#endif

#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
	int			 brightness_hw_changed;
	struct kernfs_node	*brightness_hw_changed_kn;
#endif

	/* Ensures consistent access to the LED Flash Class device */
	struct mutex		led_access;
};

这个结构体成员变量比较多,但其实是使用过程中,我们需要填充的数据比较少,这里我 们来看几个比较重要的成员:

1 name

name 表示设备名字

2 brightness 和 max_brightness

这两个成员都是枚举类型 enum led_brightness 的变量,一个表示 LED 的初始化亮度,一个表示 LED 的最大亮度,这个枚举 类型定义了 LED 的亮度等级,来看看这个枚举类型:

enum led_brightness {
	LED_OFF		= 0,
	LED_ON		= 1,
	LED_HALF	= 127,
	LED_FULL	= 255,
};

LED_OFF 表示最低亮度为 0,也就是 LED 等熄灭;对于普通的 LED 来说,通过控制 LED 对 应的 GPIO 来实现亮和灭,所以只有两种情况,要么最亮,要么熄灭;但如果我们是通过 PWM 来控制 GPIO 的,那么对应 LED 的亮度就是可调的。

3 default_trigger

该属性从设备树的 "linux,default-trigger" 属性中读取,该属性设置LED灯的默认动作,可以查阅Documentation/devicetree/bindings/leds/common.txt这个文档。比如:

① backlight:LED灯作为背光。

② default-on:LED灯打开

③ heartbeat:LED灯作为心跳指示灯,可以作为系统运行提示灯。

④ ide-disk:LED灯作为硬盘活动指示灯。

⑤ timer:LED灯周期性闪烁,由定时器驱动,闪烁频率可以修改

4 brightness_set

绑定 LED 亮度设置函数(不可休眠)

static void gpio_led_set(struct led_classdev *led_cdev,
	enum led_brightness value)
{
	struct gpio_led_data *led_dat = cdev_to_gpio_led_data(led_cdev);
	int level;

	if (value == LED_OFF)
		level = 0;
	else
		level = 1;

	if (led_dat->blinking) {
		led_dat->platform_gpio_blink_set(led_dat->gpiod, level,
						 NULL, NULL);
		led_dat->blinking = 0;
	} else {
		if (led_dat->can_sleep)
			gpiod_set_value_cansleep(led_dat->gpiod, level);
		else
			gpiod_set_value(led_dat->gpiod, level);
	}
}

5 brightness_set_blocking

绑定 LED 亮度设置函数(可以休眠)

static int gpio_led_set_blocking(struct led_classdev *led_cdev,
	enum led_brightness value)
{
	gpio_led_set(led_cdev, value);
	return 0;
}

6 blink_set

绑定 LED 闪烁函数

// 函数功能: 控制led灯的闪烁 (不能在中断上下文中使用)
// 参数led_cdev, 用于表示led灯的设备对象
// 参数delay_on, 亮多长时间(单位为 ms)
// 参数delay_off, 灭多长时间(单位为 ms)
// 使用到了内核定时器 led_cdev->blink_timer,来完成定时亮灭的功能

static int gpio_blink_set(struct led_classdev *led_cdev,
	unsigned long *delay_on, unsigned long *delay_off)
{
	struct gpio_led_data *led_dat = cdev_to_gpio_led_data(led_cdev);

	led_dat->blinking = 1;
	return led_dat->platform_gpio_blink_set(led_dat->gpiod, GPIO_LED_BLINK,
						delay_on, delay_off);
}

// 补充: platform_gpio_blink_set 是 gpio_blink_set_t 类型的函数指针

7 default_state

可以设置“default-state”属性值,可以设置为on、off或keep,为on的时候LED灯默认打开,为off的话LED灯默认关闭,为keep的话LED灯保持当前模式。

#define LEDS_GPIO_DEFSTATE_OFF		0
#define LEDS_GPIO_DEFSTATE_ON		1
#define LEDS_GPIO_DEFSTATE_KEEP		2

8 flags

保存 led 相关的状态信息和控制信息

9 参考

Linux 驱动:LED子系统 - schips - 博客园 (cnblogs.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Vane Zhang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值