linux-old/drivers/char/scx200_gpio.c
<<
>>
Prefs
   1/* linux/drivers/char/scx200_gpio.c 
   2
   3   National Semiconductor SCx200 GPIO driver.  Allows a user space
   4   process to play with the GPIO pins.
   5
   6   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */
   7
   8#include <linux/config.h>
   9#include <linux/module.h>
  10#include <linux/errno.h>
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <asm/uaccess.h>
  14#include <asm/io.h>
  15
  16#include <linux/scx200_gpio.h>
  17
  18#define NAME "scx200_gpio"
  19
  20MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
  21MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver");
  22MODULE_LICENSE("GPL");
  23
  24static int major = 0;           /* default to dynamic major */
  25MODULE_PARM(major, "i");
  26MODULE_PARM_DESC(major, "Major device number");
  27
  28static ssize_t scx200_gpio_write(struct file *file, const char *data, 
  29                                 size_t len, loff_t *ppos)
  30{
  31        unsigned m = minor(file->f_dentry->d_inode->i_rdev);
  32        size_t i;
  33
  34        if (ppos != &file->f_pos)
  35                return -ESPIPE;
  36
  37        for (i = 0; i < len; ++i) {
  38                char c;
  39                if (get_user(c, data+i))
  40                        return -EFAULT;
  41                switch (c)
  42                {
  43                case '0': 
  44                        scx200_gpio_set(m, 0); 
  45                        break;
  46                case '1': 
  47                        scx200_gpio_set(m, 1); 
  48                        break;
  49                case 'O':
  50                        printk(KERN_INFO NAME ": GPIO%d output enabled\n", m);
  51                        scx200_gpio_configure(m, ~1, 1);
  52                        break;
  53                case 'o':
  54                        printk(KERN_INFO NAME ": GPIO%d output disabled\n", m);
  55                        scx200_gpio_configure(m, ~1, 0);
  56                        break;
  57                case 'T':
  58                        printk(KERN_INFO NAME ": GPIO%d output is push pull\n", m);
  59                        scx200_gpio_configure(m, ~2, 2);
  60                        break;
  61                case 't':
  62                        printk(KERN_INFO NAME ": GPIO%d output is open drain\n", m);
  63                        scx200_gpio_configure(m, ~2, 0);
  64                        break;
  65                case 'P':
  66                        printk(KERN_INFO NAME ": GPIO%d pull up enabled\n", m);
  67                        scx200_gpio_configure(m, ~4, 4);
  68                        break;
  69                case 'p':
  70                        printk(KERN_INFO NAME ": GPIO%d pull up disabled\n", m);
  71                        scx200_gpio_configure(m, ~4, 0);
  72                        break;
  73                }
  74        }
  75
  76        return len;
  77}
  78
  79static ssize_t scx200_gpio_read(struct file *file, char *buf,
  80                                size_t len, loff_t *ppos)
  81{
  82        unsigned m = minor(file->f_dentry->d_inode->i_rdev);
  83        int value;
  84
  85        if (ppos != &file->f_pos)
  86                return -ESPIPE;
  87
  88        value = scx200_gpio_get(m);
  89        if (put_user(value ? '1' : '0', buf))
  90                return -EFAULT;
  91        
  92        return 1;
  93}
  94
  95static int scx200_gpio_open(struct inode *inode, struct file *file)
  96{
  97        unsigned m = minor(inode->i_rdev);
  98        if (m > 63)
  99                return -EINVAL;
 100        return 0;
 101}
 102
 103static int scx200_gpio_release(struct inode *inode, struct file *file)
 104{
 105        return 0;
 106}
 107
 108
 109static struct file_operations scx200_gpio_fops = {
 110        .owner   = THIS_MODULE,
 111        .write   = scx200_gpio_write,
 112        .read    = scx200_gpio_read,
 113        .open    = scx200_gpio_open,
 114        .release = scx200_gpio_release,
 115};
 116
 117static int __init scx200_gpio_init(void)
 118{
 119        int r;
 120
 121        printk(KERN_DEBUG NAME ": NatSemi SCx200 GPIO Driver\n");
 122
 123        if (!scx200_gpio_present()) {
 124                printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
 125                return -ENODEV;
 126        }
 127
 128        r = register_chrdev(major, NAME, &scx200_gpio_fops);
 129        if (r < 0) {
 130                printk(KERN_ERR NAME ": unable to register character device\n");
 131                return r;
 132        }
 133        if (!major) {
 134                major = r;
 135                printk(KERN_DEBUG NAME ": got dynamic major %d\n", major);
 136        }
 137
 138        return 0;
 139}
 140
 141static void __exit scx200_gpio_cleanup(void)
 142{
 143        unregister_chrdev(major, NAME);
 144}
 145
 146module_init(scx200_gpio_init);
 147module_exit(scx200_gpio_cleanup);
 148
 149/*
 150    Local variables:
 151        compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules"
 152        c-basic-offset: 8
 153    End:
 154*/
 155
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.