987b9f680db207e34acfb0de0f674fe3060800e7
[linux-flexiantxendom0-3.2.10.git] / arch / h8300 / kernel / gpio.c
1 /*
2  *  linux/arch/h8300/kernel/gpio.c
3  *
4  *  Yoshinori Sato <ysato@users.sourceforge.jp>
5  *
6  */
7
8 /*
9  * H8/300H Internal I/O Port Management
10  */
11
12 #include <linux/config.h>
13 #include <linux/stddef.h>
14 #include <linux/proc_fs.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/fs.h>
18
19 #if defined(CONFIG_H83007) || defined(CONFIG_H83068)
20 #define P1DDR (unsigned char *)0xfee000
21 #define P2DDR (unsigned char *)0xfee001
22 #define P3DDR (unsigned char *)0xfee002
23 #define P4DDR (unsigned char *)0xfee003
24 #define P5DDR (unsigned char *)0xfee004
25 #define P6DDR (unsigned char *)0xfee005
26 #define P8DDR (unsigned char *)0xfee007
27 #define P9DDR (unsigned char *)0xfee008
28 #define PADDR (unsigned char *)0xfee009
29 #define PBDDR (unsigned char *)0xfee00A
30 #endif
31 #if defined(CONFIG_H83002) || defined(CONFIG_H8048)
32 #define P1DDR (unsigned char *)0xffffc0
33 #define P2DDR (unsigned char *)0xffffc1
34 #define P3DDR (unsigned char *)0xffffc4
35 #define P4DDR (unsigned char *)0xffffc5
36 #define P5DDR (unsigned char *)0xffffc8
37 #define P6DDR (unsigned char *)0xffffc9
38 #define P8DDR (unsigned char *)0xffffcd
39 #define P9DDR (unsigned char *)0xffffd0
40 #define PADDR (unsigned char *)0xffffd1
41 #define PBDDR (unsigned char *)0xffffd4
42 #endif
43
44 #if defined(P1DDR)
45
46 #define MAX_PORT 11
47
48 static struct {
49         unsigned char used;
50         unsigned char ddr;
51 } gpio_regs[MAX_PORT];
52
53 static volatile unsigned char *ddrs[] = {
54         P1DDR,P2DDR,P3DDR,P4DDR,P5DDR,P6DDR,NULL,P8DDR,P9DDR,PADDR,PBDDR,
55 };
56
57 extern char *_platform_gpio_table(int length);
58
59 int h8300_reserved_gpio(int port, unsigned int bits)
60 {
61         unsigned char *used;
62         if (port < 0 || port >= MAX_PORT)
63                 return -1;
64         used = &(gpio_regs[port].used);
65         if ((*used & bits) != 0)
66                 return 0;
67         *used |= bits;
68         return 1;
69 }
70
71 int h8300_free_gpio(int port, unsigned int bits)
72 {
73         unsigned char *used;
74         if (port < 0 || port >= MAX_PORT)
75                 return -1;
76         used = &(gpio_regs[port].used);
77         if ((*used & bits) != bits)
78                 return 0;
79         *used &= (~bits);
80         return 1;
81 }
82
83 int h8300_set_gpio_dir(int port_bit,int dir)
84 {
85         const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
86         int port = (port_bit >> 8) & 0xff;
87         int bit  = port_bit & 0x07;
88         if (ddrs[port] == NULL)
89                 return 0;
90         if (gpio_regs[port].used & mask[bit]) {
91                 if (dir)
92                         gpio_regs[port].ddr |= mask[bit];
93                 else
94                         gpio_regs[port].ddr &= ~mask[bit];
95                 *ddrs[port] = gpio_regs[port].ddr;
96                 return 1;
97         } else
98                 return 0;
99 }
100
101 int h8300_get_gpio_dir(int port_bit)
102 {
103         const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
104         int port = (port_bit >> 8) & 0xff;
105         int bit  = port_bit & 0x07;
106         if (ddrs[port] == NULL)
107                 return 0;
108         if (gpio_regs[port].used & mask[bit]) {
109                 return (gpio_regs[port].ddr & mask[bit]) != 0;
110         } else
111                 return -1;
112 }
113
114 #if defined(CONFIG_PROC_FS)
115 static char *port_status(int portno)
116 {
117         static char result[10];
118         const static char io[2]={'I','O'};
119         char *rp;
120         int c;
121         unsigned char used,ddr;
122         
123         used = gpio_regs[portno].used;
124         ddr  = gpio_regs[portno].ddr;
125         result[8]='\0';
126         rp = result + 7;
127         for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1)
128                 if (used & 0x01)
129                         *rp = io[ ddr & 0x01];
130                 else    
131                         *rp = '-';
132         return result;
133 }
134
135 static int gpio_proc_read(char *buf, char **start, off_t offset, int len, int unused)
136 {
137         int c,outlen;
138         const static char port_name[]="123456789AB";
139         outlen = 0;
140         for (c = 0; c < MAX_PORT; c++) {
141                 if (ddrs[c] == NULL)
142                         continue ;
143                 len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c));
144                 buf += len;
145                 outlen += len;
146         }
147         return outlen;
148 }
149
150 static const struct proc_dir_entry proc_gpio = {
151         0, 4,"gpio",S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL, gpio_proc_read,
152 };
153 #endif
154
155 int h8300_gpio_init(void)
156 {
157         memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
158 #if 0 && defined(CONFIG_PROC_FS)
159         proc_register(&proc_root,&proc_gpio);
160 #endif
161         return 0;
162 }
163
164 #else
165 #error Unsuppoted CPU Selection
166 #endif