2012年11月26日 星期一

很簡單的驅動

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <asm/arch/gpio.h>

#include <asm/arch/at91_pio.h>
#include <asm/arch/hardware.h>
#define GPIO_MAJOR 220

#undef DEBUG_GPIO

/* ......................................................................... */

/*
* GPIO read .
*/
static ssize_t gpio_rd (struct file *file, char *buf, size_t count, loff_t *offset)
{


        return count;
}

/*
* GPIO Write .
*/
static ssize_t gpio_wr(struct file *file, char *buf, size_t count, loff_t *offset)
{

        return count;
}

static int gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
        int io_status;

        switch (cmd)
                {
                         case 0:
                                *(long *)(AT91_PIOC+PIO_CODR)         |= (1<<13);
                                break;
                        case 1:
                                *(long *)(AT91_PIOC+PIO_SODR) |= (1<<13);
                                break;                              
                        case 2:
                                io_status = *(long *)(AT91_PIOC+PIO_PDSR);
                                break;
                        default:
                                break;
                }
        return io_status;
                              
}

/*
* Open the GPIO device
*/
static int gpio_open(struct inode *inode, struct file *file)
{


        //AT91_PMC |= 1<<AT91RM9200_ID_PIOC;
        *(long *)(AT91_PIOC+PIO_OER)|= (1<<13);
        *(long *)(AT91_PIOC+PIO_PUDR) |= (1<<13);


        return 0;
}

/*
* Close the GPIO device
*/
static int gpio_close(struct inode *inode, struct file *file)
{
      
        return 0;
}

/* ......................................................................... */

static struct file_operations gpio_fops = {
        .owner                = THIS_MODULE,
        .llseek                = no_llseek,
        .read                = gpio_rd,
        .write                = gpio_wr,
        .ioctl                = gpio_ioctl,
        .open                = gpio_open,
        .release        = gpio_close,
};

/*
* Install the gpio /dev interface driver
*/
static int __init at91_gpio_init(void)
{
      
        printk(KERN_INFO "gpio /dev entries driver\n");
        if (register_chrdev(GPIO_MAJOR, "gpio", &gpio_fops)) {
                printk(KERN_ERR "at91_spidev: Unable to get major %d for gpio\n", GPIO_MAJOR);
                return -EIO;
        }


        printk(KERN_INFO "AT91 GPIO driver loaded\n");

        return 0;
}

/*
* Remove the gpio /dev interface driver
*/
static void __exit at91_gpio_exit(void)
{


        if (unregister_chrdev(GPIO_MAJOR, "gpio")) {
                printk(KERN_ERR "at91_gpio: Unable to release major %d for gpio\n", GPIO_MAJOR);
                return;
        }
}

module_init(at91_gpio_init);
module_exit(at91_gpio_exit);

MODULE_LICENSE("GPL")
MODULE_AUTHOR("Guo Shuqiang")
MODULE_DESCRIPTION("GPIO /dev interface for Atmel AT91RM9200")

/*end of at91_gpioctl.c */


MKDEV(int major, int minor);  //可以註冊裝置 major,minor...


可以在cat /proc/devices 看到你的字元裝置. 但是此時你的/dev/gpio是還沒有的.透過GPIO_MAJOR方式做掛載到/dev下的動作.

mknod /dev/gpio c 220 0

這樣子,在/dev/下看到 gpio這個點了

也可以透過在kernel EXPORT_SYMBOL(haha_vfs_count);
將kernel的變數取值出來給driver用
記得加入#include <linux/module.h>


檔案
https://docs.google.com/open?id=0B8hm-I2M8BD7NEE2RWp4dHhoa3c

沒有留言:

張貼留言