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