Chinaunix首页 | 论坛 | 博客
  • 博客访问: 635735
  • 博文数量: 205
  • 博客积分: 7891
  • 博客等级: 少将
  • 技术积分: 2168
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-29 13:16
文章分类

全部博文(205)

文章存档

2015年(4)

2014年(5)

2013年(1)

2012年(4)

2011年(51)

2010年(86)

2009年(45)

2008年(9)

分类: 嵌入式

2010-05-20 10:47:44

/
1:有两个主要结构:
struct led_classdev,
struct led_trigger,(其实就是sysfs,class文件中的一个属性?)

2:全局结构: (系统核心结构)
LIST_HEAD(leds_list); 所有的led设备。
static LIST_HEAD(trigger_list); 所有的trigger成员链表。
DECLARE_RWSEM(leds_list_lock);

3: 
led 子系统实现(class):
生成系统全局类变 量:
static struct class *leds_class;
提供 led_classdev注册,注销函数
设置 led的设备属性文件:(brightness与 trigger)
static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
#ifdef CONFIG_LEDS_TRIGGERS
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif
led子系统实现(trigger)
提供注册,注销trigger函数,即在全局变量(trigger_list) 上的操作。及属性操作函数:led_trigger_show, led_trigger_store

4:led_trigger 注册过程:
添加到全局链表中,同时遍历全局leds_list,设置以这个trigger为trigger的led.

5:led_classdev 注册过程:
生成sysfs文件,(关联trigger)设置trigger,添加到leds_list中
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
int rc;

led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
     "%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);
if (rc)
goto err_out;

#ifdef CONFIG_LEDS_TRIGGERS
init_rwsem(&led_cdev->trigger_lock);
#endif
/* add to the list of leds */
down_write(&leds_list_lock);
list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock);

led_update_brightness(led_cdev);

#ifdef CONFIG_LEDS_TRIGGERS
rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
if (rc)
goto err_out_led_list;

led_trigger_set_default(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;
}


6: led_classdev与 led_trigger的关联。
在设置led platformdata时,就设置好对应的 led_trigger。(char * name)
向系统注册led_trigger:
在另外的包含这个 trigger的模块的 module_init中向系统注册。 led_trigger_register_simple("nand-disk", &nand_led_trigger);














//******************** 控制led
struct led_trigger {
/* Trigger Properties */
const char *name;
void (*activate)(struct led_classdev *led_cdev);
void (*deactivate)(struct led_classdev *led_cdev);

/* LEDs under control by this trigger (for simple triggers) */
rwlock_t  leddev_list_lock;
struct list_head  led_cdevs;

/* Link to next registered trigger */
struct list_head  next_trig;
};

//************************ 表示led的class:
struct led_classdev {
const char *name;
int brightness;
int flags;

/* Lower 16 bits reflect status */
#define LED_SUSPENDED (1 << 0)
/* Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME (1 << 16)

/* Set LED brightness level */
/* Must not sleep, use a workqueue if needed */
void (*brightness_set)(struct led_classdev *led_cdev,
 enum led_brightness brightness);
/* Get LED brightness level */
enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);

/* Activate hardware accelerated blink */
int (*blink_set)(struct led_classdev *led_cdev,
    unsigned long *delay_on,
    unsigned long *delay_off);

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

#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;
#endif
};

转自:http://lhsblog01.blog.163.com/blog/static/1020045192010221103155591/

阅读(1388) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~