您的位置:首页 > 运维架构

platform_driver与file_operations两种方法开发led驱动

2013-01-01 10:49 316 查看
platform_driver与file_operations两种方法开发led驱动 《转》 (2012-02-24 13:48)

标签: led 开发
分类: 内核驱动

转:http://blog.csdn.net/sdustliyang/article/details/6668929

下面是两个LED灯的驱动程序 一个用platform_driver 另一个用file_operations

[cpp] view plaincopy

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/platform_device.h>

#include <linux/leds.h>



#include <mach/hardware.h>

#include <mach/regs-gpio.h>

#include <mach/leds-gpio.h>



/* our context */



struct s3c24xx_gpio_led {

struct led_classdev cdev;

struct s3c24xx_led_platdata *pdata;

};



static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev)

{

return platform_get_drvdata(dev);

}



static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev)

{

return container_of(led_cdev, struct s3c24xx_gpio_led, cdev);

}



static void s3c24xx_led_set(struct led_classdev *led_cdev,

enum led_brightness value)

{

struct s3c24xx_gpio_led *led = to_gpio(led_cdev);

struct s3c24xx_led_platdata *pd = led->pdata;



/* there will be a short delay between setting the output and

* going from output to input when using tristate. */



s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^

(pd->flags & S3C24XX_LEDF_ACTLOW));



if (pd->flags & S3C24XX_LEDF_TRISTATE)

s3c2410_gpio_cfgpin(pd->gpio,

value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);



}



static int s3c24xx_led_remove(struct platform_device *dev)

{

struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);



led_classdev_unregister(&led->cdev);

kfree(led);



return 0;

}



static int s3c24xx_led_probe(struct platform_device *dev)

{

struct s3c24xx_led_platdata *pdata = dev->dev.platform_data;

struct s3c24xx_gpio_led *led;

int ret;



led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL);

if (led == NULL) {

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

return -ENOMEM;

}



platform_set_drvdata(dev, led);



led->cdev.brightness_set = s3c24xx_led_set;

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

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



led->pdata = pdata;



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



if (pdata->flags & S3C24XX_LEDF_TRISTATE) {

s3c2410_gpio_setpin(pdata->gpio, 0);

s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT);

} else {

s3c2410_gpio_pullup(pdata->gpio, 0);

s3c2410_gpio_setpin(pdata->gpio, 0);

s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT);

}



/* register our new led device */



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

if (ret < 0) {

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

goto exit_err1;

}



return 0;



exit_err1:

kfree(led);

return ret;

}





#ifdef CONFIG_PM

static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state)

{

struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);



led_classdev_suspend(&led->cdev);

return 0;

}



static int s3c24xx_led_resume(struct platform_device *dev)

{

struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);



led_classdev_resume(&led->cdev);

return 0;

}

#else

#define s3c24xx_led_suspend NULL

#define s3c24xx_led_resume NULL

#endif



static struct platform_driver s3c24xx_led_driver = {

.probe = s3c24xx_led_probe,

.remove = s3c24xx_led_remove,

.suspend = s3c24xx_led_suspend,

.resume = s3c24xx_led_resume,

.driver = {

.name = "s3c24xx_led",

.owner = THIS_MODULE,

},

};



static int __init s3c24xx_led_init(void)

{

return platform_driver_register(&s3c24xx_led_driver);

}



static void __exit s3c24xx_led_exit(void)

{

platform_driver_unregister(&s3c24xx_led_driver);

}



module_init(s3c24xx_led_init);

module_exit(s3c24xx_led_exit);



MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");

MODULE_DESCRIPTION("S3C24XX LED driver");

MODULE_LICENSE("GPL");

MODULE_ALIAS("platform:s3c24xx_led");









另一个如下:



#include <asm/uaccess.h>

#include <asm/atomic.h>

#include <asm/unistd.h>



#define DEVICE_NAME "leds"



static unsigned long led_table [] = {

S3C2410_GPB5,



S3C2410_GPB6,

S3C2410_GPB7,

S3C2410_GPB8,

};



static unsigned int led_cfg_table [] = {

S3C2410_GPB5_OUTP,



S3C2410_GPB6_OUTP,

S3C2410_GPB7_OUTP,

S3C2410_GPB8_OUTP,

};



static int sbc2440_leds_ioctl(

struct inode *inode,

struct file *file,

unsigned int cmd,

unsigned long arg)

{

switch(cmd) {

case 0:

case 1:

if (arg > 4) {

return -EINVAL;

}

s3c2410_gpio_setpin(led_table[arg], !cmd);

return 0;

default:

return -EINVAL;

}

}



static struct file_operations dev_fops = {

.owner = THIS_MODULE,

.ioctl = sbc2440_leds_ioctl,

};



static struct miscdevice misc = {

.minor = MISC_DYNAMIC_MINOR,

.name = DEVICE_NAME,

.fops = &dev_fops,

};



static int __init dev_init(void)

{

int ret;



int i;



for (i = 0; i < 4; i++) {

s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

s3c2410_gpio_setpin(led_table[i], 0);

}



ret = misc_register(&misc);



printk (DEVICE_NAME"\tinitialized\n");



return ret;

}



static void __exit dev_exit(void)

{

misc_deregister(&misc);

}



module_init(dev_init);

module_exit(dev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("FriendlyARM Inc.");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: