欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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。。。。。。

相关标签: 驱动