platform平台总线驱动2:实例分析
程序员文章站
2022-06-05 17:26:33
...
上一篇博文介绍了platform平台总线的一些基础知识,以及驱动框架的实现,这篇博文将从一个实际led驱动为例。从驱动角度出发分析如何使用platform平台总线驱动框架进行驱动的注册:
1.驱动的入口:
module_init(s5pv210_led_init);
static int __init s5pv210_led_init(void)
{
return platform_driver_register(&s5pv210_led_driver);
}
2.驱动结构体platform_driver:
static struct platform_driver s5pv210_led_driver = {
.probe = s5pv210_led_probe,
.remove = s5pv210_led_remove,
.driver = {
.name = "s5pv210_led",
.owner = THIS_MODULE,
},
};
(1)驱动探测函数prob
static int s5pv210_led_probe(struct platform_device *dev)
{
int ret = -1;
struct s5pv210_led_platdata *pdata = dev->dev.platform_data;
struct s5pv210_gpio_led *led;
printk(KERN_INFO "----s5pv210_led_probe---\n");
led = kzalloc(sizeof(struct s5pv210_gpio_led), GFP_KERNEL);
if (led == NULL) {
dev_err(&dev->dev, "No memory for device\n");
return -ENOMEM;
}
platform_set_drvdata(dev, led);
if (gpio_request(pdata->gpio, pdata->name))
{
printk(KERN_ERR "gpio_request failed\n");
}
else
{
gpio_direction_output(pdata->gpio, 1);
}
// led1
led->cdev.name = pdata->name;
led->cdev.brightness = 0;
led->cdev.brightness_set = s5pv210_led_set;
led->pdata = pdata;
ret = led_classdev_register(&dev->dev, &led->cdev);
if (ret < 0) {
printk(KERN_ERR "led_classdev_register failed\n");
return ret;
}
return 0;
}
定义一个结构体变量,存放类相关的数据和平台总线相关的数据:
struct s5pv210_led_platdata *pdata = dev->dev.platform_data;
struct s5pv210_gpio_led *led;
struct s5pv210_gpio_led {
struct led_classdev cdev;
struct s5pv210_led_platdata *pdata;
};
同样的,进行实例化:
led = kzalloc(sizeof(struct s5pv210_gpio_led), GFP_KERNEL);
申请gpio口:
if (gpio_request(pdata->gpio, pdata->name))
进行结构体内容的填充:
led->cdev.name = pdata->name;
led->cdev.brightness = 0;
led->cdev.brightness_set = s5pv210_led_set;
led->pdata = pdata;
创建一个led类的设备:
ret = led_classdev_register(&dev->dev, &led->cdev);
总的来说:prob函数内进行设备注册的一些初始化工作,将这些凌乱而又很必要的操作整合在此函数内。
(2)remove卸载函数:
static struct platform_driver s5pv210_led_driver = {
.probe = s5pv210_led_probe,
.remove = s5pv210_led_remove,
.driver = {
.name = "s5pv210_led",
.owner = THIS_MODULE,
},
};
注销申请的led类设备,释放申请的gpio口,释放为结构体申请的内存空间。
(3)驱动所共有的部分:
.driver = {
.name = "s5pv210_led",
.owner = THIS_MODULE,
名字和驱动的所属者。
3.驱动的出口:
static void __exit s5pv210_led_exit(void)
{
platform_driver_unregister(&s5pv210_led_driver);
}
注销申请的platform平台设备驱动即可。
End。。。。。。
上一篇: C语言笔记 09_共用体&typedef&输入|输出
下一篇: js加密(十)csti.cn md5
推荐阅读