转自:http://blog.sina.com.cn/s/blog_b73b0cf10102vis2.html
有些设备需要有灯的闪烁来表达一些含义,比如电池电量。利用GPIO实现灯的灭、亮、慢闪、快闪需要配合内核定时器来实现。
首先我们找到高通内核自带的LED相关的文件,
/kernel/drivers/leds/leds-msm-pmic.c
利用这个文件来实现灯的灭、亮、慢闪、快闪。
一.注册这个设备
1.添加编译选项
修改
kernel\drivers\leds\Makefile
添加
obj-y += leds-msm-pmic.o
2.修改配置文件
修改
kernel\arch\arm\configs\xxxx_defconfig
打开或添加
CONFIG_LEDS_MSM_PMIC=y
3.注册平台驱动
修改
kernel\arch\arm\mach-msm\board-xxxx.c
(1)添加
static struct platform_devicemsm_device_pmic_leds = {
.name = "pmic-leds",
.id =-1,
};
(2)添加
static struct platform_device*devices[] __initdata = {
&msm_device_pmic_leds
}
这样就可以在/sys/class/leds/下注册设备节点了。
二.实现灯的闪烁。
有两种方式实现灯的闪烁,一是在modem端实现灯的逻辑控制,二是在Android端实现等的控制。
modem端是利用宏的传递:
#definePCOM_CUSTOMER_CMD_LED_POWER_ON 1
(void)msm_led_proc_comm(PCOM_CUSTOMER_CMD_LED_POWER_ON,LED_COLOR_RED);
我们这里只讲android端:
1.首先注册一个内核定时器
struct timer_listled_test_timer;
然后在设备初始化的时候初始化定时器
init_timer(&led_test_timer);
led_test_timer.data=(unsignedlong)0x00;
led_test_timer.expires =jiffies + 0xFFFFFFFF*HZ;
led_test_timer.function =led_test_timer_function; //该函数按照自己的需要进行修改
add_timer(&led_test_timer);
调用的时候修改定时器的时间
mod_timer(&reset_button_timer, jiffies +xx*HZ);
调用完成了再修改回去
mod_timer(&reset_button_timer,jiffies + 0xFFFFFFFF*HZ);
2.然后注册一个新设备
static intmsm_pmic_led_probe(struct platform_device*pdev)
{
......
rc= led_classdev_register(&pdev->dev,&led_test);//添加
if(rc) {
dev_err(&pdev->dev,"unable to registerled_test driver\n");
returnrc;
}
......
}
static int __devexitmsm_pmic_led_remove(struct platform_device *pdev)
{
......
led_classdev_unregister(&led_test);//添加
......
}
//添加
static struct led_classdevmsm_led_test = {
.name= "led_test",
.brightness_set= msm_led_test_set,
.brightness= 0,
};
//添加,灯的控制就在如下函数里面实现
static void msm_led_test_set(structled_classdev *led_cdev,
enum led_brightness value)
{
if(value == 0)//灭
{
mod_timer(&reset_button_timer,jiffies + 0xFFFFFFFF*HZ);
value_now = 0;
}
else if (value ==1)//亮
{
mod_timer(&reset_button_timer,jiffies + 0xFFFFFFFF*HZ);
value_now = 1;
}
elseif (value == 2)//慢闪
{
mod_timer(&reset_button_timer,jiffies+ 0x1*HZ);//时间自己设定
value_now = 2;
}
elseif (value == 3)//快闪
{
mod_timer(&reset_button_timer,jiffies+ 0x2*HZ);//时间自己设定
value_now = 3;
}
}
我的 led_test_timer_function函数实现如下
intvalue_now;//全局变量
led_test_timer_function()
{
int i =1;
if(value_now == 0)
{
led_set_gpio_value(10,0);//这里是把GPIO10拉低(看硬件的定义), 这个函数看自己的系统是怎么定义的,名称不固定
}
if(value_now == 1)
{
led_set_gpio_value(10,0);//这里把GPIO10la'gao1,灯亮
}
if(value_now ==2)
{
if(i == 1)
{
led_set_gpio_value(10,1);
i =0;
}
else
{
led_set_gpio_value(10,0);
}
}
if(value_now == 3)
{
if(i == 1)
{
led_set_gpio_value(10,1);
i =0;
}
else
{
led_set_gpio_value(10,0);
}
}
}
这样,向/sys/class/leds/led_test/brightness写入0,1,2,3,一个灯的各种灭、亮、慢闪、快闪就实现了。