Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3125128
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: 嵌入式

2014-11-04 14:52:55

原文地址:http://blog.csdn.net/zhaocj/article/details/8273406

现在就来说一下s3c24xx_led_probe函数:

static int s3c24xx_led_probe(struct platform_device *dev)

{

structs3c24xx_led_platdata*pdata = dev->dev.platform_data;------------->获取gpio口编号

structs3c24xx_gpio_led *led;

intret;


/*用于给LED分配内存空间*/

led =devm_kzalloc(&dev->dev, sizeof(struct s3c24xx_gpio_led),

GFP_KERNEL);

if(led == NULL) {

dev_err(&dev->dev,"No memory for device\n");

return-ENOMEM;

}


/*保存LED设备结构*/

platform_set_drvdata(dev,led);


/*给LED结构体赋值,其中s3c24xx_led_set就是具体负责操作LED的函数*/

led->cdev.brightness_set= s3c24xx_led_set;------->s3c2410_gpio_setpin(定义在drivers/gpio/gpio_samsung.c中,最终调用gpio_request())

led->cdev.default_trigger= pdata->def_trigger;

led->cdev.name= pdata->name;

led->cdev.flags|= LED_CORE_SUSPENDRESUME;


led->pdata = pdata;


/*为LED分配io引脚*/

ret =devm_gpio_request(&dev->dev, pdata->gpio, "S3C24XX_LED");

if(ret < 0)

returnret;


/*no point in having a pull-up if we are always driving */


/*无需上拉*/

s3c_gpio_setpull(pdata->gpio, S3C_GPIO_PULL_NONE);


/*设置io引脚为输入*/

if(pdata->flags & S3C24XX_LEDF_TRISTATE)

gpio_direction_input(pdata->gpio);

else

gpio_direction_output(pdata->gpio,

pdata->flags& S3C24XX_LEDF_ACTLOW ? 1 :0);


/*register our new led device */


/*注册一个新的LED设备类对象

该函数是在drivers/leds目录下的Led-class.c文件内定义的*/

ret= led_classdev_register(&dev->dev, &led->cdev);

if(ret < 0)

dev_err(&dev->dev,"led_classdev_register failed\n");


return ret;

}


从以上分析可以看出,s3c24xx_led_probe函数主要就是完成LED设备的一些初始化工作。而负责开、关LED任务的是s3c24xx_led_set函数,在该函数内,gpio_set_value(pd->gpio, state);是具体完成为相应引脚置1或清零的任务。


drivers/leds目录下的Led-class.c文件是LED子系统的底层核心文件,它主要负责创建LED类,以及创建设备节点,上面提到的led_classdev_register函数就是在这个文件中定义的。为了更好的理解LED子系统,我们再简单分析一下该文件。


在子系统初始化时,会调用leds_init函数,它的第一段代码:

leds_class = class_create(THIS_MODULE,"leds");

就是创建leds类,也就是我们在sys/class目录下看到的leds目录。另外

leds_class->dev_attrs = led_class_attrs;

是赋予该类的属性。那么我们再来看看led_class_attrs结构的第一句代码:

__ATTR(brightness, 0644, led_brightness_show,led_brightness_store)

其中brightness就是我们对LED具体操作的设备文件名,0644是该文件的权限,led_brightness_show是读文件所调用的函数,led_brightness_store是写文件所调用的函数。读文件也就是读取LED的状态(是关还是开),写文件也就是完成打开LED或关闭LED操作。


最后再分析一下前面提到的led_classdev_register函数。在该函数内首先利用device_create函数创建设备节点,也就是在leds目录下,生成led1~led4这四个目录。另一项重要的任务就是把设备节点添加到leds的链表中。


对linux自带的LED子系统的分析就到这里。我想只要理解了该子系统,那么自己完全可以写出关于GPIO读写操作的任何驱动程序来。



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