Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
[platform/kernel/u-boot.git] / common / cmd_portio.c
1 /*
2  * (C) Copyright 2003
3  * Marc Singer, elf@buici.com
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Port I/O Functions
26  *
27  * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
28  */
29
30 #include <common.h>
31 #include <command.h>
32
33 /* Display values from last command.
34  * Memory modify remembered values are different from display memory.
35  */
36 static uint in_last_addr, in_last_size;
37 static uint out_last_addr, out_last_size, out_last_value;
38
39
40 int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
41 {
42         uint addr = out_last_addr;
43         uint size = out_last_size;
44         uint value = out_last_value;
45
46         if (argc != 3) {
47                 cmd_usage(cmdtp);
48                 return 1;
49         }
50
51         if ((flag & CMD_FLAG_REPEAT) == 0) {
52                 /* New command specified.  Check for a size specification.
53                  * Defaults to long if no or incorrect specification.
54                  */
55                 size = cmd_get_data_size (argv[0], 1);
56                 addr = simple_strtoul (argv[1], NULL, 16);
57                 value = simple_strtoul (argv[2], NULL, 16);
58         }
59 #if defined (CONFIG_X86)
60
61         {
62                 unsigned short port = addr;
63
64                 switch (size) {
65                 default:
66                 case 1:
67                     {
68                         unsigned char ch = value;
69                         __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
70                     }
71                         break;
72                 case 2:
73                     {
74                         unsigned short w = value;
75                         __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
76                     }
77                         break;
78                 case 4:
79                         __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
80
81                         break;
82                 }
83         }
84
85 #endif                                                  /* CONFIG_X86 */
86
87         out_last_addr = addr;
88         out_last_size = size;
89         out_last_value = value;
90
91         return 0;
92 }
93
94 U_BOOT_CMD(
95         out,    3,      1,      do_portio_out,
96         "write datum to IO port",
97         "[.b, .w, .l] port value\n    - output to IO port\n"
98 );
99
100 int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
101 {
102         uint addr = in_last_addr;
103         uint size = in_last_size;
104
105         if (argc != 2) {
106                 cmd_usage(cmdtp);
107                 return 1;
108         }
109
110         if ((flag & CMD_FLAG_REPEAT) == 0) {
111                 /* New command specified.  Check for a size specification.
112                  * Defaults to long if no or incorrect specification.
113                  */
114                 size = cmd_get_data_size (argv[0], 1);
115                 addr = simple_strtoul (argv[1], NULL, 16);
116         }
117 #if defined (CONFIG_X86)
118
119         {
120                 unsigned short port = addr;
121
122                 switch (size) {
123                 default:
124                 case 1:
125                     {
126                         unsigned char ch;
127                         __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
128
129                         printf (" %02x\n", ch);
130                     }
131                         break;
132                 case 2:
133                     {
134                         unsigned short w;
135                         __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
136
137                         printf (" %04x\n", w);
138                     }
139                         break;
140                 case 4:
141                     {
142                         unsigned long l;
143                         __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
144
145                         printf (" %08lx\n", l);
146                     }
147                         break;
148                 }
149         }
150 #endif  /* CONFIG_X86 */
151
152         in_last_addr = addr;
153         in_last_size = size;
154
155         return 0;
156 }
157
158 U_BOOT_CMD(
159         in,     2,      1,      do_portio_in,
160         "read data from an IO port",
161         "[.b, .w, .l] port\n"
162         "    - read datum from IO port\n"
163 );