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

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

#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 <[email protected]>");  
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.");    

 

 

 

 

 

----------

你可能感兴趣的:(driver)