基于TQ2440开发的LED驱动

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <mach/regs-gpio.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/uaccess.h>

#define LIGHT_LEDS_MAJOR 0
#define DEVICE_NAME "TLYYY-LEDS"


#define LIGHT_LEDS_ON 1
#define LIGHT_LEDS_OFF 0


MODULE_AUTHOR("SONG SIR");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("FLASH LEDS Driver");


static unsigned long light_leds_table[] =
{
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};


static unsigned int light_leds_cfg_table[] =
{
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};


static void light_leds_on(unsigned long arg)
{
s3c2410_gpio_setpin(light_leds_table[arg],0);
}


static void light_leds_off(unsigned long arg)
{
s3c2410_gpio_setpin(light_leds_table[arg],1);
}


//device struct
struct light_leds_dev 
{
struct cdev cdev;
unsigned char value;
};


struct light_leds_dev *light_leds_devp;


int light_leds_major = LIGHT_LEDS_MAJOR;


//open func
int light_leds_open(struct inode *inode, struct file *filp)
{
struct light_leds_dev *dev;


dev = container_of(inode->i_cdev, struct light_leds_dev, cdev);
filp->private_data = dev;

return 0;
}


int light_leds_release(struct inode * inode,struct file * filp)
{
return 0;
}


ssize_t light_leds_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
struct light_leds_dev *dev = filp->private_data;


if(copy_to_user(buf, &(dev->value), 1))//succeed return 0
return -EFAULT;

return 1;
}


ssize_t light_leds_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
struct light_leds_dev *dev = filp->private_data;


if(copy_from_user(&(dev->value), buf, 1))
{
return -EFAULT;
}
if(dev->value == 1)
// s3c2410_gpio_setpin(light_leds_table[*f_pos],0);
light_leds_on(*f_pos);
else
// s3c2410_gpio_setpin(light_leds_table[*f_pos],1);
light_leds_off(*f_pos);
return 1;
}


int light_leds_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
struct light_leds_dev *dev = filp->private_data;


switch(cmd)
{
case LIGHT_LEDS_ON:
dev->value = 1;
// s3c2410_gpio_setpin(light_leds_table[arg],0);
light_leds_on(arg);
printk(KERN_ALERT"leds_on arg is %ld\n",arg);
break;
case LIGHT_LEDS_OFF:
dev->value = 0;
// s3c2410_gpio_setpin(light_leds_table[arg],1);
light_leds_off(arg);
printk(KERN_ALERT"leds_off arg is %ld\n",arg);
break;
default:
return - ENOTTY;
}
return 0;
}


struct file_operations light_leds_fops = 
{
.owner = THIS_MODULE,
.read = light_leds_read,
.write = light_leds_write,
.ioctl = light_leds_ioctl,
.open = light_leds_open,
.release= light_leds_release,
};


static struct class *light_leds_class;


static void light_leds_setup_cdev(struct light_leds_dev *dev, int index)
{
int err, devno = MKDEV(light_leds_major, index);


cdev_init(&dev->cdev, &light_leds_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &light_leds_fops;
err = cdev_add(&dev->cdev, devno , 1);
if(err)
printk(KERN_NOTICE"Error %d adding LED %d\n", err, index);
}


static int __init light_leds_init(void)
{


int result;
dev_t dev = MKDEV(light_leds_major, 0);
printk(KERN_ALERT"get dev is %d \n", dev);




if(light_leds_major)
result = register_chrdev(dev, DEVICE_NAME, &light_leds_fops);
else
{
result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
light_leds_major = MAJOR(dev);
}


if(result < 0)
{
printk(KERN_ALERT"unable to get a major %d\n", light_leds_major);
return result;
}

printk(KERN_ALERT"get major is %d\n", light_leds_major);

light_leds_class = class_create(THIS_MODULE, DEVICE_NAME);
device_create(light_leds_class, NULL, MKDEV(light_leds_major,0), NULL, DEVICE_NAME);


if(!light_leds_major)
light_leds_major = result;

light_leds_devp = kmalloc(sizeof(struct light_leds_dev),GFP_KERNEL);
if(light_leds_devp == NULL)
{
result = - ENOMEM;
printk(KERN_ALERT"kmalloc failed!\n");
goto fail_malloc;
}
memset(light_leds_devp , 0, sizeof(struct light_leds_dev));

light_leds_setup_cdev(light_leds_devp, 0);

printk(KERN_ALERT"install module successfully!\n");
return 0;

fail_malloc:
unregister_chrdev_region(dev, 1);
printk(KERN_ALERT"install module unsuccessfully!");
return result;
}


static void __exit light_leds_cleanup(void)
{

cdev_del(&light_leds_devp->cdev);
kfree(light_leds_devp);
unregister_chrdev_region(MKDEV(light_leds_major, 0), 1);
device_destroy(light_leds_class, MKDEV(light_leds_major, 0));
class_destroy(light_leds_class);


printk(KERN_ALERT"\nuninstall module successfully!\n");
}


module_init(light_leds_init);
module_exit(light_leds_cleanup);

简单的应用程序:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/ioctl.h>
  5 
  6 int main(int argc, char* argv[])
  7 {
  8     int on;
  9     int led_on;
 10     int fd;
 11 
 12     if(argc != 3 || sscanf(argv[1], "%d", &led_on) != 1 || sscanf(argv[2], "%d", &on) != 1 || on < 0 || on > 1 || led_on < 1 || led_on > 4)
 13     {
 14         fprintf(stderr,"Usage: leds len_on 0|1\n");
 15         exit(1);
 16     }
 17     fd = open ("/dev/TLYYY-LEDS", 0);
 18     if(fd < 0)
 19     {
 20         perror("open device leds");
 21         fprintf(stdout,"fd = %d, on = %d, led_on = %d, argc = %d\n",fd, on, led_on, argc);
 22         exit(1);
 23     }
 24 
 25     ioctl(fd, on, (led_on-1));
 26     fprintf(stdout,"fd = %d, on = %d, led_on = %d, argc = %d\n",fd, on, led_on, argc);
 27     close(fd);
 28     return 0;
 29 
 30 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值