source: SVN/rincon/u-boot/common/cmd_pcmcia.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 2 years ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 7.9 KB
Line 
1/*
2 * (C) Copyright 2000-2006
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 * Lots of code copied from:
26 *
27 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
28 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
29 *
30 * "The ExCA standard specifies that socket controllers should provide
31 * two IO and five memory windows per socket, which can be independently
32 * configured and positioned in the host address space and mapped to
33 * arbitrary segments of card address space. " - David A Hinds. 1999
34 *
35 * This controller does _not_ meet the ExCA standard.
36 *
37 * m8xx pcmcia controller brief info:
38 * + 8 windows (attrib, mem, i/o)
39 * + up to two slots (SLOT_A and SLOT_B)
40 * + inputpins, outputpins, event and mask registers.
41 * - no offset register. sigh.
42 *
43 * Because of the lacking offset register we must map the whole card.
44 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
45 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
46 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
47 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
48 * They are maximum 64KByte each...
49 */
50
51/* #define DEBUG        1       */
52
53/*
54 * PCMCIA support
55 */
56#include <common.h>
57#include <command.h>
58#include <config.h>
59#include <pcmcia.h>
60#include <asm/io.h>
61
62/* -------------------------------------------------------------------- */
63
64#if defined(CONFIG_CMD_PCMCIA)
65
66extern int pcmcia_on (void);
67extern int pcmcia_off (void);
68
69int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
70{
71        int rcode = 0;
72
73        if (argc != 2) {
74                printf ("Usage: pinit {on | off}\n");
75                return 1;
76        }
77        if (strcmp(argv[1],"on") == 0) {
78                rcode = pcmcia_on ();
79        } else if (strcmp(argv[1],"off") == 0) {
80                rcode = pcmcia_off ();
81        } else {
82                printf ("Usage: pinit {on | off}\n");
83                return 1;
84        }
85
86        return rcode;
87}
88
89U_BOOT_CMD(
90        pinit,  2,      0,      do_pinit,
91        "pinit   - PCMCIA sub-system\n",
92        "on  - power on PCMCIA socket\n"
93                        "pinit off - power off PCMCIA socket\n"
94          );
95
96#endif
97
98/* -------------------------------------------------------------------- */
99
100#undef  CHECK_IDE_DEVICE
101
102#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
103#define CHECK_IDE_DEVICE
104#endif
105
106#if     defined(CONFIG_PXA_PCMCIA)
107#define CHECK_IDE_DEVICE
108#endif
109
110#ifdef  CHECK_IDE_DEVICE
111
112int             ide_devices_found;
113static uchar    *known_cards[] = {
114        (uchar *)"ARGOSY PnPIDE D5",
115        NULL
116};
117
118#define MAX_TUPEL_SZ    512
119#define MAX_FEATURES    4
120
121#define MAX_IDENT_CHARS         64
122#define MAX_IDENT_FIELDS        4
123
124#define indent  "\t   "
125
126static void print_funcid (int func)
127{
128        puts (indent);
129        switch (func) {
130                case CISTPL_FUNCID_MULTI:
131                        puts (" Multi-Function");
132                        break;
133                case CISTPL_FUNCID_MEMORY:
134                        puts (" Memory");
135                        break;
136                case CISTPL_FUNCID_SERIAL:
137                        puts (" Serial Port");
138                        break;
139                case CISTPL_FUNCID_PARALLEL:
140                        puts (" Parallel Port");
141                        break;
142                case CISTPL_FUNCID_FIXED:
143                        puts (" Fixed Disk");
144                        break;
145                case CISTPL_FUNCID_VIDEO:
146                        puts (" Video Adapter");
147                        break;
148                case CISTPL_FUNCID_NETWORK:
149                        puts (" Network Adapter");
150                        break;
151                case CISTPL_FUNCID_AIMS:
152                        puts (" AIMS Card");
153                        break;
154                case CISTPL_FUNCID_SCSI:
155                        puts (" SCSI Adapter");
156                        break;
157                default:
158                        puts (" Unknown");
159                        break;
160        }
161        puts (" Card\n");
162}
163
164static void print_fixed (volatile uchar *p)
165{
166        if (p == NULL)
167                return;
168
169        puts(indent);
170
171        switch (*p) {
172                case CISTPL_FUNCE_IDE_IFACE:
173                {   uchar iface = *(p+2);
174
175                puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
176                puts (" interface ");
177                break;
178                }
179                case CISTPL_FUNCE_IDE_MASTER:
180                case CISTPL_FUNCE_IDE_SLAVE:
181                {   uchar f1 = *(p+2);
182                uchar f2 = *(p+4);
183
184                puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
185
186                if (f1 & CISTPL_IDE_UNIQUE)
187                        puts (" [unique]");
188
189                puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
190
191                if (f2 & CISTPL_IDE_HAS_SLEEP)
192                        puts (" [sleep]");
193
194                if (f2 & CISTPL_IDE_HAS_STANDBY)
195                        puts (" [standby]");
196
197                if (f2 & CISTPL_IDE_HAS_IDLE)
198                        puts (" [idle]");
199
200                if (f2 & CISTPL_IDE_LOW_POWER)
201                        puts (" [low power]");
202
203                if (f2 & CISTPL_IDE_REG_INHIBIT)
204                        puts (" [reg inhibit]");
205
206                if (f2 & CISTPL_IDE_HAS_INDEX)
207                        puts (" [index]");
208
209                if (f2 & CISTPL_IDE_IOIS16)
210                        puts (" [IOis16]");
211
212                break;
213                }
214        }
215        putc ('\n');
216}
217
218static int identify  (volatile uchar *p)
219{
220        uchar id_str[MAX_IDENT_CHARS];
221        uchar data;
222        uchar *t;
223        uchar **card;
224        int i, done;
225
226        if (p == NULL)
227                return (0);     /* Don't know */
228
229        t = id_str;
230        done =0;
231
232        for (i=0; i<=4 && !done; ++i, p+=2) {
233                while ((data = *p) != '\0') {
234                        if (data == 0xFF) {
235                                done = 1;
236                                break;
237                        }
238                        *t++ = data;
239                        if (t == &id_str[MAX_IDENT_CHARS-1]) {
240                                done = 1;
241                                break;
242                        }
243                        p += 2;
244                }
245                if (!done)
246                        *t++ = ' ';
247        }
248        *t = '\0';
249        while (--t > id_str) {
250                if (*t == ' ')
251                        *t = '\0';
252                else
253                        break;
254        }
255        puts ((char *)id_str);
256        putc ('\n');
257
258        for (card=known_cards; *card; ++card) {
259                debug ("## Compare against \"%s\"\n", *card);
260                if (strcmp((char *)*card, (char *)id_str) == 0) {       /* found! */
261                        debug ("## CARD FOUND ##\n");
262                        return (1);
263                }
264        }
265
266        return (0);     /* don't know */
267}
268
269int check_ide_device (int slot)
270{
271        volatile uchar *ident = NULL;
272        volatile uchar *feature_p[MAX_FEATURES];
273        volatile uchar *p, *start, *addr;
274        int n_features = 0;
275        uchar func_id = ~0;
276        uchar code, len;
277        ushort config_base = 0;
278        int found = 0;
279        int i;
280
281        addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
282                                  CFG_PCMCIA_MEM_SIZE * (slot * 4));
283        debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
284
285        start = p = (volatile uchar *) addr;
286
287        while ((p - start) < MAX_TUPEL_SZ) {
288
289                code = *p; p += 2;
290
291                if (code == 0xFF) { /* End of chain */
292                        break;
293                }
294
295                len = *p; p += 2;
296#if defined(DEBUG) && (DEBUG > 1)
297                { volatile uchar *q = p;
298                        printf ("\nTuple code %02x  length %d\n\tData:",
299                                code, len);
300
301                        for (i = 0; i < len; ++i) {
302                                printf (" %02x", *q);
303                                q+= 2;
304                        }
305                }
306#endif  /* DEBUG */
307                switch (code) {
308                case CISTPL_VERS_1:
309                        ident = p + 4;
310                        break;
311                case CISTPL_FUNCID:
312                        /* Fix for broken SanDisk which may have 0x80 bit set */
313                        func_id = *p & 0x7F;
314                        break;
315                case CISTPL_FUNCE:
316                        if (n_features < MAX_FEATURES)
317                                feature_p[n_features++] = p;
318                        break;
319                case CISTPL_CONFIG:
320                        config_base = (*(p+6) << 8) + (*(p+4));
321                        debug ("\n## Config_base = %04x ###\n", config_base);
322                default:
323                        break;
324                }
325                p += 2 * len;
326        }
327
328        found = identify (ident);
329
330        if (func_id != ((uchar)~0)) {
331                print_funcid (func_id);
332
333                if (func_id == CISTPL_FUNCID_FIXED)
334                        found = 1;
335                else
336                        return (1);     /* no disk drive */
337        }
338
339        for (i=0; i<n_features; ++i) {
340                print_fixed (feature_p[i]);
341        }
342
343        if (!found) {
344                printf ("unknown card type\n");
345                return (1);
346        }
347
348        ide_devices_found |= (1 << slot);
349
350#if CONFIG_CPC45
351#else
352        /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
353        *((uchar *)(addr + config_base)) = 1;
354#endif
355#if 0
356        printf("\n## Config_base = %04x ###\n", config_base);
357        printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
358        printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
359        printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
360        printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
361#endif
362        return (0);
363}
364
365#endif  /* CHECK_IDE_DEVICE */
Note: See TracBrowser for help on using the repository browser.