linux/arch/h8300/kernel/gpio.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/h8300/kernel/gpio.c
   3 *
   4 *  Yoshinori Sato <ysato@users.sourceforge.jp>
   5 *
   6 */
   7
   8/*
   9 * Internal I/O Port Management
  10 */
  11
  12#include <linux/stddef.h>
  13#include <linux/proc_fs.h>
  14#include <linux/seq_file.h>
  15#include <linux/kernel.h>
  16#include <linux/string.h>
  17#include <linux/fs.h>
  18#include <linux/init.h>
  19
  20#define _(addr) (volatile unsigned char *)(addr)
  21#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
  22#include <asm/regs306x.h>
  23static volatile unsigned char *ddrs[] = {
  24        _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
  25        NULL,    _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
  26};
  27#define MAX_PORT 11
  28#endif
  29
  30 #if defined(CONFIG_H83002) || defined(CONFIG_H8048)
  31/* Fix me!! */
  32#include <asm/regs306x.h>
  33static volatile unsigned char *ddrs[] = {
  34        _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
  35        NULL,    _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
  36};
  37#define MAX_PORT 11
  38#endif
  39
  40#if defined(CONFIG_H8S2678)
  41#include <asm/regs267x.h>
  42static volatile unsigned char *ddrs[] = {
  43        _(P1DDR),_(P2DDR),_(P3DDR),NULL    ,_(P5DDR),_(P6DDR),
  44        _(P7DDR),_(P8DDR),NULL,    _(PADDR),_(PBDDR),_(PCDDR),
  45        _(PDDDR),_(PEDDR),_(PFDDR),_(PGDDR),_(PHDDR),
  46        _(PADDR),_(PBDDR),_(PCDDR),_(PDDDR),_(PEDDR),_(PFDDR),
  47        _(PGDDR),_(PHDDR)
  48};
  49#define MAX_PORT 17
  50#endif
  51#undef _
  52 
  53#if !defined(P1DDR)
  54#error Unsuppoted CPU Selection
  55#endif
  56
  57static struct {
  58        unsigned char used;
  59        unsigned char ddr;
  60} gpio_regs[MAX_PORT];
  61
  62extern char *_platform_gpio_table(int length);
  63
  64int h8300_reserved_gpio(int port, unsigned int bits)
  65{
  66        unsigned char *used;
  67
  68        if (port < 0 || port >= MAX_PORT)
  69                return -1;
  70        used = &(gpio_regs[port].used);
  71        if ((*used & bits) != 0)
  72                return 0;
  73        *used |= bits;
  74        return 1;
  75}
  76
  77int h8300_free_gpio(int port, unsigned int bits)
  78{
  79        unsigned char *used;
  80
  81        if (port < 0 || port >= MAX_PORT)
  82                return -1;
  83        used = &(gpio_regs[port].used);
  84        if ((*used & bits) != bits)
  85                return 0;
  86        *used &= (~bits);
  87        return 1;
  88}
  89
  90int h8300_set_gpio_dir(int port_bit,int dir)
  91{
  92        int port = (port_bit >> 8) & 0xff;
  93        int bit  = port_bit & 0xff;
  94
  95        if (ddrs[port] == NULL)
  96                return 0;
  97        if (gpio_regs[port].used & bit) {
  98                if (dir)
  99                        gpio_regs[port].ddr |= bit;
 100                else
 101                        gpio_regs[port].ddr &= ~bit;
 102                *ddrs[port] = gpio_regs[port].ddr;
 103                return 1;
 104        } else
 105                return 0;
 106}
 107
 108int h8300_get_gpio_dir(int port_bit)
 109{
 110        int port = (port_bit >> 8) & 0xff;
 111        int bit  = port_bit & 0xff;
 112
 113        if (ddrs[port] == NULL)
 114                return 0;
 115        if (gpio_regs[port].used & bit) {
 116                return (gpio_regs[port].ddr & bit) != 0;
 117        } else
 118                return -1;
 119}
 120
 121#if defined(CONFIG_PROC_FS)
 122static char *port_status(int portno)
 123{
 124        static char result[10];
 125        static const char io[2]={'I','O'};
 126        char *rp;
 127        int c;
 128        unsigned char used,ddr;
 129        
 130        used = gpio_regs[portno].used;
 131        ddr  = gpio_regs[portno].ddr;
 132        result[8]='\0';
 133        rp = result + 7;
 134        for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1)
 135                if (used & 0x01)
 136                        *rp = io[ ddr & 0x01];
 137                else    
 138                        *rp = '-';
 139        return result;
 140}
 141
 142static int gpio_proc_show(struct seq_file *m, void *v)
 143{
 144        static const char port_name[]="123456789ABCDEFGH";
 145        int c;
 146
 147        for (c = 0; c < MAX_PORT; c++) {
 148                if (ddrs[c] == NULL)
 149                        continue;
 150                seq_printf(m, "P%c: %s\n", port_name[c], port_status(c));
 151        }
 152        return 0;
 153}
 154
 155static int gpio_proc_open(struct inode *inode, struct file *file)
 156{
 157        return single_open(file, gpio_proc_show, PDE_DATA(inode));
 158}
 159
 160static const struct file_operations gpio_proc_fops = {
 161        .open           = gpio_proc_open,
 162        .read           = seq_read,
 163        .llseek         = seq_lseek,
 164        .release        = single_release,
 165};
 166
 167static __init int register_proc(void)
 168{
 169        return proc_create("gpio", S_IRUGO, NULL, &gpio_proc_fops) != NULL;
 170}
 171
 172__initcall(register_proc);
 173#endif
 174
 175void __init h8300_gpio_init(void)
 176{
 177        memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
 178}
 179