📄 leds.c
字号:
/* * LED driver for Atmel AT91-based boards. * * Copyright (C) SAN People (Pty) Ltd * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version.*/#include <linux/kernel.h> /*printk()*/#include <linux/module.h> /**/#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/types.h> /*size_t*/#include <linux/slab.h>#include <linux/fs.h> /*everything...*/#include <linux/errno.h> /*error codes*/#include <linux/uaccess.h> /*copy_*_user*/#include <linux/cdev.h>#include <linux/fcntl.h>#include <asm/mach-types.h>#include <asm/leds.h>#include <asm/arch/board.h>#include <asm/arch/gpio.h>#include "leds.h"struct led_dev *led_devices;int led_major = LED_MAJOR;int led_minor = 1;int led_nr_devs = LED_NR_DEVS;module_param(led_major,int,S_IRUGO);module_param(led_minor,int,S_IRUGO);module_param(led_nr_devs,int,S_IRUGO);static void at91_led_on(unsigned int led){ at91_set_gpio_value(led, 0);}static void at91_led_off(unsigned int led){ at91_set_gpio_value(led, 1);}static void at91_led_toggle(unsigned int led){ unsigned long is_off = at91_get_gpio_value(led); if (is_off) at91_led_on(led); else at91_led_off(led);}static int AT91SAM_LED_open(struct inode *inode,struct file *filp){ struct led_dev *dev; dev = container_of(inode->i_cdev,struct led_dev,cdev); filp->private_data = dev; return 0;} static int AT91SAM_LED_release(struct inode *inode,struct file *filp){ printk("Led release.\n"); return 0;} static ssize_t AT91SAM_LED_write(struct file *filp,const char __user *buffer,size_t count,loff_t *f_pos){ at91_led_toggle(AT91_PIN_PB8); return 0; }struct file_operations AT91SAM_LED_fops = { .owner = THIS_MODULE, .write = AT91SAM_LED_write, .open = AT91SAM_LED_open, .release = AT91SAM_LED_release,};static void led_setup_cdev(struct led_dev *dev,int index){ int err,devno = MKDEV(led_major,led_minor+index); cdev_init(&dev->cdev,&AT91SAM_LED_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &AT91SAM_LED_fops; err = cdev_add(&dev->cdev,devno,1); /*Fail gracefully if need be*/ if(err) printk("Error %d adding led%d",err,index);}static int __init AT91SAM_LED_init(void){ int result,i; dev_t dev = 0; if(led_major){ dev = MKDEV(led_major,led_minor); result = register_chrdev_region(dev,led_nr_devs,"LED_DEV"); }else { result = alloc_chrdev_region(&dev,led_minor,led_nr_devs,"LED_DEV"); led_major = MAJOR(dev); } if(result<0){ printk("LED_DEV:Can't get major %d\n",led_major); return result; } /*allocate the devices --we can't have them static,as the number*/ led_devices = kmalloc(led_nr_devs*sizeof(struct led_dev),GFP_KERNEL); if(led_devices){ result = -ENOMEM; goto fail; /*Make this more graceful*/ memset(led_devices,0,led_nr_devs*sizeof(struct led_dev)); } /*Initialize each device*/ for(i=0;i<led_nr_devs;i++){ led_devices[i].led_on = 0; led_devices[i].led_off = 0; led_setup_cdev(&led_devices[i],i); } at91_set_gpio_output(AT91_PIN_PB8,1); at91_set_gpio_output(AT91_PIN_PC29,1);// leds_event(led_start); at91_led_off(AT91_PIN_PC29); at91_led_off(AT91_PIN_PB8); printk("The led on!\n"); return 0;fail: return result;}static void __exit AT91SAM_LED_exit(void) { int i; dev_t devno = MKDEV(led_major,led_minor); /*Get rid of our char dev entries*/ if(led_devices){ for(i=0;i<led_nr_devs;i++); cdev_del(&led_devices[i].cdev); } kfree(led_devices); /*cleanup_module if never called if registering failed*/ unregister_chrdev_region(devno,led_nr_devs); }//__initcall(leds_init);module_init(AT91SAM_LED_init);module_exit(AT91SAM_LED_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Wenzel Cai");MODULE_DESCRIPTION("LED driver for Atmel AT91SAM9263");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -