#include MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("SM");
MODULE_VERSION("0.0.1");
//MODULE_DEVICE("global memory");
MODULE_DESCRIPTION("led ...");
MODULE_ALIAS("LED");
/*******************************************/
#define NAME "led"
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
#defineLED_GPIO_11
#defineLED_PIN_124
static int major =283;//定义主设备号
staticstruct class *led_class;
/*******************************************/
void led_on(void)
{
gpio_set_value(GPIO_TO_PIN(LED_GPIO_1,LED_PIN_1), 1);
}
EXPORT_SYMBOL(led_on);
void led_off(void)
{
gpio_set_value(GPIO_TO_PIN(LED_GPIO_1,LED_PIN_1), 0);
}
EXPORT_SYMBOL(led_off);
void led_init(void)
{
int result;
/* Allocating GPIOs and setting direction */
gpio_free(GPIO_TO_PIN(LED_GPIO_1,LED_PIN_1));
result = gpio_request(GPIO_TO_PIN(LED_GPIO_1,LED_PIN_1), "Leds");//usr1
if (result != 0)
printk("gpio_request(%d_%d) failed!\n",LED_GPIO_1,LED_PIN_1);
result = gpio_direction_output(GPIO_TO_PIN(LED_GPIO_1,LED_PIN_1), 1);
if (result != 0)
printk("gpio_direction(%d_%d) failed!\n",LED_GPIO_1,LED_PIN_1);
}
struct light_dev
{
struct cdev cdev;
unsigned char value;
};
struct light_dev *light_devp;
// 打开和关闭函数
int light_open(struct inode *inode,struct file *filp)
{
struct light_dev *dev;
// 获得设备结构体指针
dev = container_of(inode->i_cdev,struct light_dev,cdev);
// 让设备结构体作为设备的私有信息
filp->private_data = dev;
return 0;
}
int light_release(struct inode *inode,struct file *filp)
{
return 0;
}
// ioctl
long light_ioctl(struct file *filp,unsigned int cmd,
unsigned long arg)
{
struct light_dev *dev = filp->private_data;
switch(cmd)
{
case 0:
dev->value = 0;
led_off();
break;
case 1:
dev->value = 1;
led_on();
break;
default:
return -ENOTTY;
// break;
}
return 0;
}
//set up the cdev structure for a device
staticvoidled_setup_cdev(struct cdev* dev,int minor,struct file_operations *fops)
{
int err, devno = MKDEV(major,minor);
cdev_init(dev,fops);
dev->owner= THIS_MODULE;
dev->ops= fops;
err= cdev_add(dev,devno,1);
if(err)
printk(KERN_NOTICE"Error %d adding led%d",err,minor);
}
struct file_operations light_fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = light_ioctl,
.open = light_open,
.release = light_release,
};
staticstruct cdev cdev_led;
// 模块加载函数
int light_init(void)
{
int ret;
dev_tdev= MKDEV(major,0);
led_init();
printk(KERN_ALERT "led modules is install\n");
// ret=register_chrdev(major,NAME,&light_fops);
if(major)
ret= register_chrdev_region(dev,1,NAME);
else
{
ret= alloc_chrdev_region(&dev,0,1,NAME);
major= MAJOR(dev);
}
if(ret<0)
{
printk("unable to register myled driver!\n");
return ret;
}
printk(KERN_DEBUG"led device number : %x\n",dev);
led_setup_cdev(&cdev_led,0,&light_fops);
led_class= class_create(THIS_MODULE,"led_class");
if(IS_ERR(led_class))
{
printk(KERN_INFO"create led class error\n");
return -1;
}
device_create(led_class,NULL,dev,NULL,"led" "%d",MINOR(dev));
return 0;
}
// 模块卸载函数
void light_cleanup(void)
{
// unregister_chrdev(major,NAME);
device_destroy(led_class,MKDEV(major,0));
class_destroy(led_class);
cdev_del(&cdev_led);
unregister_chrdev_region(MKDEV(major,0),1);
printk("Goodbye,cruel world!\n");
}
module_init(light_init);
module_exit(light_cleanup);