/*----------------------------------------------------------------- ---------------------/include/linux/Leds.h------------------------ -----------------------------------------------------------------*/ * Generic LED platform data for describing LED names and default triggers. */ struct led_info { const char *name; const char *default_trigger; int flags; };
struct led_platform_data { int num_leds; struct led_info *leds; };
struct gpio_led_platform_data { int num_leds; /*led灯的个数*/ struct gpio_led *leds; /*leds指针*/ int (*gpio_blink_set)(unsigned gpio, unsigned long *delay_on, unsigned long *delay_off); };
struct led_classdev { const char *name; /*设备名称*/ int brightness; /*亮度*/ int flags;
#define LED_SUSPENDED (1 << 0)
/* 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 */ char *default_trigger; /* Trigger to use */
#ifdef CONFIG_LEDS_TRIGGERS /* Protects the trigger data below */ struct rw_semaphore trigger_lock;
/*----------------------------------------------------------------- ------------------------/drivers/leds/Led-gpio.c------------------- -----------------------------------------------------------------*/ /* * LEDs driver for GPIOs * * Copyright (C) 2007 8D Technologies inc. * Raphael Assenat <raph@8d.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/workqueue.h>
/* Setting GPIOs with I2C/etc requires a task context, and we don't * seem to have a reliable way to know if we're already in one; so * let's just assume the worst. */ if (led_dat->can_sleep) { led_dat->new_level = level; schedule_work(&led_dat->work); } else gpio_set_value(led_dat->gpio, level); /*设置IO口电平*/ }
static int gpio_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { struct gpio_led_data *led_dat = container_of(led_cdev, struct gpio_led_data, cdev);
err: if (i > 0) { for (i = i - 1; i >= 0; i--) { led_classdev_unregister(&leds_data.cdev); cancel_work_sync(&leds_data.work); gpio_free(leds_data.gpio); } }
kfree(leds_data);
return ret; }
/** * led_classdev_register - register a new object of led_classdev class. * @dev: The device to register. * @led_cdev: the led_classdev structure for this device. */ /* /drivers/leds/Led_class.c */ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { int rc;
/* 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队列中*/
文章评论(0条评论)
登录后参与讨论