Merge with /home/wd/git/u-boot/mailing-list/Haavard_Skinnemoen
[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 #if (CONFIG_COMMANDS & CFG_CMD_PORTIO)
34
35 extern int cmd_get_data_size (char *arg, int default_size);
36
37 /* Display values from last command.
38  * Memory modify remembered values are different from display memory.
39  */
40 static uint in_last_addr, in_last_size;
41 static uint out_last_addr, out_last_size, out_last_value;
42
43
44 int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
45 {
46         uint addr = out_last_addr;
47         uint size = out_last_size;
48         uint value = out_last_value;
49
50         if (argc != 3) {
51                 printf ("Usage:\n%s\n", cmdtp->usage);
52                 return 1;
53         }
54
55         if ((flag & CMD_FLAG_REPEAT) == 0) {
56                 /* New command specified.  Check for a size specification.
57                  * Defaults to long if no or incorrect specification.
58                  */
59                 size = cmd_get_data_size (argv[0], 1);
60                 addr = simple_strtoul (argv[1], NULL, 16);
61                 value = simple_strtoul (argv[2], NULL, 16);
62         }
63 #if defined (CONFIG_X86)
64
65         {
66                 unsigned short port = addr;
67
68                 switch (size) {
69                 default:
70                 case 1:
71                     {
72                         unsigned char ch = value;
73                         __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
74                     }
75                         break;
76                 case 2:
77                     {
78                         unsigned short w = value;
79                         __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
80                     }
81                         break;
82                 case 4:
83                         __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
84
85                         break;
86                 }
87         }
88
89 #endif                                                  /* CONFIG_X86 */
90
91         out_last_addr = addr;
92         out_last_size = size;
93         out_last_value = value;
94
95         return 0;
96 }
97
98 U_BOOT_CMD(
99         out,    3,      1,      do_portio_out,
100         "out     - write datum to IO port\n",
101         "[.b, .w, .l] port value\n    - output to IO port\n"
102 );
103
104 int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
105 {
106         uint addr = in_last_addr;
107         uint size = in_last_size;
108
109         if (argc != 2) {
110                 printf ("Usage:\n%s\n", cmdtp->usage);
111                 return 1;
112         }
113
114         if ((flag & CMD_FLAG_REPEAT) == 0) {
115                 /* New command specified.  Check for a size specification.
116                  * Defaults to long if no or incorrect specification.
117                  */
118                 size = cmd_get_data_size (argv[0], 1);
119                 addr = simple_strtoul (argv[1], NULL, 16);
120         }
121 #if defined (CONFIG_X86)
122
123         {
124                 unsigned short port = addr;
125
126                 switch (size) {
127                 default:
128                 case 1:
129                     {
130                         unsigned char ch;
131                         __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
132
133                         printf (" %02x\n", ch);
134                     }
135                         break;
136                 case 2:
137                     {
138                         unsigned short w;
139                         __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
140
141                         printf (" %04x\n", w);
142                     }
143                         break;
144                 case 4:
145                     {
146                         unsigned long l;
147                         __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
148
149                         printf (" %08lx\n", l);
150                     }
151                         break;
152                 }
153         }
154 #endif  /* CONFIG_X86 */
155
156         in_last_addr = addr;
157         in_last_size = size;
158
159         return 0;
160 }
161
162 U_BOOT_CMD(
163         in,     2,      1,      do_portio_in,
164         "in      - read data from an IO port\n",
165         "[.b, .w, .l] port\n"
166         "    - read datum from IO port\n"
167 );
168
169 #endif  /* CFG_CMD_PORTIO */