linux leds
【源碼:linux-3.2-rc7】
關於led,前兩天被問道一個問題,這裡順便總結下吧。
led,對於我們所有的人來說這是一個比較簡單的模組,當然也是學習時比較好入口的一個模組。
分析驅動,都瞭解先看Makefile &Kconfig
# LED Core
obj-$(CONFIG_NEW_LEDS) += led-core.o
obj-$(CONFIG_LEDS_CLASS) += led-class.o
obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
............
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
.........
再來看看Kconfig對這些宏的定義
先看看NEW_LEDS
bool"LED Support"
help
Say Y to enable Linux LED support. This allows control of supported
LEDs from both userspace and optionally, bykernel events (triggers).
This is not related to standard keyboard LEDswhich are controlled
via the input system.
configLEDS_CLASS
bool"LED Class Support"
help
This option enables the led sysfs class in/sys/class/leds. You'll
need this to do anything useful withLEDs. If unsure, say N.
configLEDS_TRIGGERS
bool"LED Trigger support"
dependson LEDS_CLASS
help
This option enables trigger support for theleds class.
These triggers allow kernel events to drivethe LEDs and can
be configured via sysfs. If unsure, say Y.
看了上面的解釋,大家也都有一個基本的瞭解了,這裡我們拿2410的例子來解釋。
makefile中定義
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
Kconfig中定義
config LEDS_S3C24XX
tristate"LED Support for Samsung S3C24XX GPIO LEDs"
dependson LEDS_CLASS
dependson ARCH_S3C2410
help
This option enables support for LEDsconnected to GPIO lines
on Samsung S3C24XX series CPUs, such as theS3C2410 and S3C2440.
在Kconfig中,我們注意到使用leds-s3c24xx.c需要開啟LEDS_CLASS,並且依賴於ARCH S3C2410。
下面我們分析具體的代碼
代碼路徑linux-3.2-rc7/drivers/leds/leds-s3c24xx.c
static inline struct s3c24xx_gpio_led*pdev_to_gpio(struct platform_device *dev)
static inline struct s3c24xx_gpio_led*to_gpio(struct led_classdev *led_cdev)
static void s3c24xx_led_set(structled_classdev *led_cdev,
enum led_brightness value)
static int s3c24xx_led_remove(structplatform_device *dev)
static int s3c24xx_led_probe(structplatform_device *dev)
{
structs3c24xx_led_platdata *pdata = dev->dev.platform_data;
structs3c24xx_gpio_led *led;
intret;
led= kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL);
if(led == NULL) {
dev_err(&dev->dev,"No memory for device\n");
return-ENOMEM;
}
platform_set_drvdata(dev,led);
led->cdev.brightness_set= s3c24xx_led_set;
led->cdev.default_trigger= pdata->def_trigger;
led->cdev.name= pdata->name;
led->cdev.flags|= LED_CORE_SUSPENDRESUME;
led->pdata= pdata;
/*no point in having a pull-up if we are always driving */
if(pdata->flags & S3C24XX_LEDF_TRISTATE) {
s3c2410_gpio_setpin(pdata->gpio,0);
s3c2410_gpio_cfgpin(pdata->gpio,S3C2410_GPIO_INPUT);
}else {
s3c2410_gpio_pullup(pdata->gpio,0);
s3c2410_gpio_setpin(pdata->gpio,0);
s3c2410_gpio_cfgpin(pdata->gpio,S3C2410_GPIO_OUTPUT);
}
/*register our new led device */
ret= led_classdev_register(&dev->dev, &led->cdev);
if(ret < 0) {
dev_err(&dev->dev,"led_classdev_register failed\n");
kfree(led);
returnret;
}
return0;
}
static struct platform_drivers3c24xx_led_driver = {
.probe = s3c24xx_led_probe,
.remove = s3c24xx_led_remove,
.driver = {
.name = "s3c24xx_led",
.owner = THIS_MODULE,
},
};
static int __init s3c24xx_led_init(void)
{
returnplatform_driver_register(&s3c24xx_led_driver);
}
static void __exit s3c24xx_led_exit(void)
{
platform_driver_unregister(&s3c24xx_led_driver);
}
這裡可以看到整個的驅動是一個簡單的裝置註冊的過程,只不過這裡對led的註冊的時候出現了led_classdev_register這樣的註冊的方式。
在leds-class.txt中找到的對其的簡單的描述如下:
In its simplest form, the LED class justallows control of LEDs from
userspace. LEDs appear in /sys/class/leds/.
在Android中的基本的架構圖是:
在android的手機中可以看到如上的分布
R,G,B三色LED,button-backlight,keyboard-backlight,lcd-backlight,torch-flash。而這裡的spotlight則要根據你具體的外設看有沒有了。
Have Fun!