您的位置:首页 > 其它

led子系统之实战篇(实际led驱动编写)

2015-10-14 15:52 417 查看
led驱动应该是linux驱动中是最简单的一个,下面实际讲解关于led驱动编写的过程。

早期的led驱动实际上在/dev/led生成文件,当led成为一个单独的子系统时,我们要用到led的子系统以及相关的函数

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spmi.h>

头文件不说了
static struct led_classdev	led_cdev;             //直接定义led_classdev的变量
<pre name="code" class="cpp">static void carl_wang_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
led_cdevbrightness = value;                               //赋值操作,当对led的文件写时会调用这个函数,剩余的操作和平台相关</span>
}
static enum led_brightness carl_wang_led_get(struct led_classdev * led_dev)
{
return led_cdev.brightness; //读取操作,当cat时会调用
}

static int carl_wang_led_probe(struct spmi_device *dev )
{
int ret;
led_cdev.brightness_set = carl_wang_led_set; //函数指针赋值
led_cdev.brightness_get = carl_wang_led_get;
led_cdev.name = "carl_wang_led"; //在sys/class/leds/ 生成carl_wang_led的目录

/* register our new led device */
ret = led_classdev_register(&dev->dev, &led_cdev); //led class 的注册
if (ret < 0) {
dev_err(&dev->dev, "led_classdev_register failed\n");
return ret;
}
return 0;
}

static int carl_wang_led_remove(struct spmi_device * dev)
{
led_classdev_unregister(&led_cdev);
return 0;
}

#ifdef CONFIG_OF
static struct of_device_id spmi_match_table[] = {{ .compatible = "qcom,leds-qpnp",},{ },};
#else#
define spmi_match_table NULL
#endif

static struct spmi_driver carl_wang_led_driver = {
.probe = carl_wang_led_probe, //device和device_driver匹配到后调用的函数
.remove = carl_wang_led_remove,
.driver = { .name = "qcom,leds-qpnp", //spmi总线上一定要有与之对应的相同name(名字)的device
.owner = THIS_MODULE,
.of_match_table = spmi_match_table, //和name的作用一样,用于匹配device和device_driver的凭证},};

static int __init qpnp_led_init(void)
{
return spmi_driver_register(&carl_wang_led_driver); //高通平台专有的spmi的总线注册驱动的函数
}module_init(qpnp_led_init);

static void __exit qpnp_led_exit(void)
{spmi_driver_unregister(&carl_wang_led_driver);}module_exit(qpnp_led_exit);
MODULE_AUTHOR("carl_wang@unicair");
MODULE_DESCRIPTION("carl_wang LED driver");
MODULE_LICENSE("GPL");





每个平台上的注册函数都是不一样的,但是实际上我们的目的嗾使一样的,那就是使用户空间的能够访问到这些device,其实关键有几步需要注意

1. 定义dirver,比如我们是spmi总线上的,一般有spmi_driver,有的平台是挂在paltform总线上的,就是使用platform_driver定义的,并且对内部的元素进行填充或者是初始化;

2.调用总线驱动注册函数,当总线上已经存在相同的name(一般)device已经挂载上,那么当driver注册的时候会遍历所有总线上的device,当找到相同的时,这个相同取决于总线的match函数,一般比较的是name,相同时返回1,然后调用驱动中的probe函数

3.在probe函数中,我们要针对led_classdev 的变量进行初始化,一般初始化的的brightness_set,brightness_get,name,其中name是实际生成的leds下的子目录的名字。

4.调用led_classdev_register(struct device *parent, struct led_classdev *led_cdev)函数,则大功告成。

当然了1,2步骤可以不用的,我们完全可以将led_classdev_register函数的调用放在其他的比如lcd背光的probe函数中,或者是按键的probe函数中,我们要的只是在用户空间能生成对应的访问接口。



可以看到在class/leds下有calr_wang_led的目录,我们仅仅需要访问的是brightness,输入echo 255 > brightness 然后cat brightness ,看看是不是255。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: