============================================
作者:yuanlulu
http://blog.csdn.net/yuanlulu
版權沒有,但是轉載請保留此段聲明
============================================
LED_OFF = 0,
LED_HALF = 127,
LED_FULL = 255,
};
struct led_classdev {
const char *name; //名字
int brightness; //當前亮度
int flags; //標誌,目前只支持 LED_SUSPENDED
#define LED_SUSPENDED (1 << 0)
/*設置led的亮度,不可以睡眠,有必要的話可以使用工作隊列*/
void (*brightness_set)(struct led_classdev *led_cdev,
enum led_brightness brightness);
/* 獲取亮度 */
enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
/* 激活硬件加速的閃爍 */
int (*blink_set)(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off);
struct device *dev;
struct list_head node; /* 所有已經註冊的led_classdev使用這個節點串聯起來 */
const char *default_trigger; /* 默認觸發器 */
#ifdef CONFIG_LEDS_TRIGGERS //如果配置內核時使能了觸發器功能,纔會編譯下面一段
/* 這個讀寫子軒鎖保護下面的觸發器數據 */
struct rw_semaphore trigger_lock;
struct led_trigger *trigger; //觸發器指針
struct list_head trig_list; //觸發器使用的鏈表節點,用來連接同一觸發器上的所有led_classdev
void *trigger_data; //觸發器使用的私有數據
#endif
};
struct led_trigger {
const char *name; //觸發器名字
void (*activate)(struct led_classdev *led_cdev); //激活ledled。led_classdev和觸發器建立連接時會調用這個方法。
void (*deactivate)(struct led_classdev *led_cdev); //取消激活。led_classdev和觸發器取消連接時會調用這個方法。
/* 本觸發器控制之下的led鏈表 */
rwlock_t leddev_list_lock; //保護鏈表的鎖
struct list_head led_cdevs; //鏈表頭
/* 連接下一個已註冊觸發器的鏈表節點 ,所有已註冊的觸發器都會被加入一個全局鏈表*/
struct list_head next_trig;
};
const char *name;
char *default_trigger;
int flags;
};
struct led_platform_data {
int num_leds;
struct led_info *leds;
};
const char *name;
char *default_trigger;
unsigned gpio;
u8 active_low;
};
struct gpio_led_platform_data {
int num_leds;
struct gpio_led *leds;
int (*gpio_blink_set)(unsigned gpio,
unsigned long *delay_on,
unsigned long *delay_off);
};
led_classdev接口分析/driver/rtc/led-class.c
{
int rc;
"%s", led_cdev->name);
if (IS_ERR(led_cdev->dev))
return PTR_ERR(led_cdev->dev);
/* register the attributes */
rc = device_create_file(led_cdev->dev, &dev_attr_brightness);//在sys/class/rtc/下創建一個led的屬性文件。
if (rc)
goto err_out;
/* add to the list of leds */
down_write(&leds_list_lock);
list_add_tail(&led_cdev->node, &leds_list);//將新的led加入鏈表,全局鏈表是leds_list
up_write(&leds_list_lock);
led_update_brightness(led_cdev);//獲取led當前的亮度更新led_cdev的brightness成員
#ifdef CONFIG_LEDS_TRIGGERS
init_rwsem(&led_cdev->trigger_lock);//初始化led_cdev的觸發器自旋鎖
rc = device_create_file(led_cdev->dev, &dev_attr_trigger);//在sys/class/led中爲觸發器創建屬性文件
if (rc)
goto err_out_led_list;
led_trigger_set_default(led_cdev); //爲led_cdev設置默認的觸發器
#endif
printk(KERN_INFO "Registered led device: %s/n",
led_cdev->name);
return 0;
#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
device_remove_file(led_cdev->dev, &dev_attr_brightness);
list_del(&led_cdev->node);
#endif
err_out:
device_unregister(led_cdev->dev);
return rc;
}
EXPORT_SYMBOL_GPL(led_classdev_register);
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);