A8_led_drv A8LED的驱动程序

来源:互联网 发布:ls plc编程软件 编辑:程序博客网 时间:2024/05/15 17:55
/* * Simple - REALLY simple memory mapping demonstration.  */#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/kernel.h>   /* printk() */#include <linux/slab.h>   /* kmalloc() */#include <linux/fs.h>       /* everything... */#include <linux/errno.h>    /* error codes */#include <linux/types.h>    /* size_t */#include <linux/mm.h>#include <linux/kdev_t.h>#include <linux/cdev.h>#include <linux/delay.h>#include <linux/device.h>#include <asm/io.h>#include <asm/uaccess.h>#define pGPG3CON 0xE03001C0#define pGPG3DAT 0xE03001C4static void *vGPG3CON , *vGPG3DAT;#define GPG3CON (*(volatile unsigned int *) vGPG3CON)#define GPG3DAT (*(volatile unsigned int *) vGPG3DAT)#define LED_ON 0x4800#define LED_OFF 0x4801static int simple_major = 250;module_param(simple_major, int, 0);MODULE_AUTHOR("farsight");MODULE_LICENSE("Dual BSD/GPL");//static int flag = 0;/* * Open the device; in fact, there's nothing to do here. */int simple_open (struct inode *inode, struct file *filp){    vGPG3CON=ioremap(pGPG3CON,0x10);    vGPG3DAT=vGPG3CON+0x04;    GPG3CON=0x1111;    GPG3DAT &= ~0xf;    printk(KERN_INFO "led device opened  *****************8\n");    return 0;}ssize_t simple_read(struct file *file, char __user *buff, size_t count, loff_t *offp){    return 0;}ssize_t simple_write(struct file *file, const char __user *buff, size_t count, loff_t *offp){    return 0;}void led_off( void ){    printk(KERN_INFO "led off *****************\n");    GPG3DAT=GPG3DAT|(1<<2);    //printk("stop led\n");}void led_on( void ){    printk(KERN_INFO "led on ****************88\n");    GPG3DAT=GPG3DAT&(~(1<<2));    //printk("start led\n");}static int simple_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){    switch ( cmd )     {        case LED_ON:            {                led_on();                break;            }        case LED_OFF:            {                led_off();                break;            }        default:            {                break;            }    }    return 0;}static int simple_release(struct inode *node, struct file *file){    printk(KERN_INFO "led device release *****************8\n");    return 0;}/* * Set up the cdev structure for a device. */static void simple_setup_cdev(struct cdev *dev, int minor,        struct file_operations *fops){    int err, devno = MKDEV(simple_major, minor);    cdev_init(dev, fops);    dev->owner = THIS_MODULE;    dev->ops = fops;    err = cdev_add (dev, devno, 1);    /* Fail gracefully if need be */    if (err)        printk (KERN_NOTICE "Error %d adding simple%d", err, minor);}/* * Our various sub-devices. *//* Device 0 uses remap_pfn_range */static struct file_operations simple_remap_ops = {    .owner   = THIS_MODULE,    .open    = simple_open,    .release = simple_release,    .read    = simple_read,    .write   = simple_write,    .ioctl   = simple_ioctl,};/* * We export two simple devices.  There's no need for us to maintain any * special housekeeping info, so we just deal with raw cdevs. */static struct cdev SimpleDevs;/* * Module housekeeping. */static struct class *my_class;static int simple_init(void){    int result;    dev_t dev = MKDEV(simple_major, 0);    /* Figure out our device number. */    if (simple_major)        result = register_chrdev_region(dev, 1, "led");    else {        result = alloc_chrdev_region(&dev, 0, 1, "led");        simple_major = MAJOR(dev);    }    if (result < 0) {        printk(KERN_WARNING "simple: unable to get major %d\n", simple_major);        return result;    }    if (simple_major == 0)        simple_major = result;    /* Now set up two cdevs. */    simple_setup_cdev(&SimpleDevs, 0, &simple_remap_ops);    printk("simple device installed, with major %d\n", simple_major);    my_class= class_create(THIS_MODULE, "led");    device_create(my_class, NULL, MKDEV(simple_major, 0),            NULL, "led");    return 0;}static void simple_cleanup(void){    cdev_del(&SimpleDevs);    unregister_chrdev_region(MKDEV(simple_major, 0), 1);    device_destroy(my_class,MKDEV(simple_major,0));    class_destroy(my_class);    printk("simple device uninstalled\n");}module_init(simple_init);module_exit(simple_cleanup);
/* * main.c : test demo driver */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#define LED_ON 0x4800#define LED_OFF 0x4801int main(){int i = 0;int dev_fd;dev_fd = open("/dev/led",O_RDWR | O_NONBLOCK);if ( dev_fd == -1 ) {printf("Cann't open file /dev/led\n");exit(1);}while(1){ioctl(dev_fd,LED_ON,0);    printf("LED ON ___________________\n");sleep(1);ioctl(dev_fd,LED_OFF,0);    printf("LED OFF ___________-\n");sleep(1);}return 0;}
ifeq ($(KERNELRELEASE),)KERNELDIR ?= /source/android-2.6.29-samsungPWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions.PHONY: modules modules_install cleanelse    obj-m := led_drv.oendif


原创粉丝点击