OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [pcmcia/] [current/] [src/] [pcmcia.c] - Blame information for rev 838

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      io/pcmcia/pcmcia.c
4
//
5
//      PCMCIA support (Card Services)
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    gthomas
43
// Contributors: gthomas
44
// Date:         2000-07-06
45
// Purpose:      PCMCIA support
46
// Description: 
47
//
48
//####DESCRIPTIONEND####
49
//
50
//==========================================================================
51
 
52
#include <pkgconf/io_pcmcia.h>
53
 
54
#include <cyg/io/pcmcia.h>
55
#include <cyg/infra/diag.h>
56
 
57
#if CYGHWR_IO_PCMCIA_DEVICE == 0
58
#error Need hardware package for PCMCIA support
59
#endif
60
 
61
#define CF_NUM_SLOTS CYGHWR_IO_PCMCIA_DEVICE
62
static struct cf_slot cf_slots[CF_NUM_SLOTS];
63
 
64
// Implementation routines
65
void cf_hwr_init(struct cf_slot *slot);
66
void cf_hwr_change_state(struct cf_slot *slot, int desired_state);
67
void cf_hwr_clear_interrupt(struct cf_slot *slot);
68
 
69
bool
70
cf_get_CIS(struct cf_slot *slot, unsigned char id,
71
           unsigned char *buf, int *len, int *ptr)
72
{
73
    int i, size;
74
    unsigned char *cis = slot->attr;
75
    unsigned char *cis_end = cis + slot->attr_length;
76
    cis += *ptr;
77
    while (cis < cis_end) {
78
        if (*cis == 0xFF) {
79
            break;
80
        }
81
        if (*cis == id) {
82
            size = *(cis+2) + 2;
83
            for (i = 0;  i < size;  i++) {
84
                *buf++ = *cis;
85
                cis += 2;
86
            }
87
            *len = size;
88
            *ptr = (unsigned long)(cis - slot->attr);
89
            return true;
90
        } else {
91
            // Skip to next entry
92
            cis += (*(cis+2) * 2) + 4;
93
        }
94
    }
95
    return false;
96
}
97
 
98
void
99
cf_set_COR(struct cf_slot *slot, unsigned long cor, unsigned char val)
100
{
101
    volatile unsigned char *cfg = slot->attr;
102
    cfg[cor] = val;
103
}
104
 
105
static void
106
cf_parse_power_structure(unsigned char **buf)
107
{
108
    unsigned char *bp = *buf;
109
    unsigned char tpce_pd = *bp++;
110
    unsigned char settings;
111
    int indx;
112
    for (indx = 6;  indx >= 0;  indx--) {
113
        if (tpce_pd & (1<<indx)) {
114
            settings = *bp++;  // main value
115
            if (settings & 0x80) {
116
                bp++;  // extension byte - FIXME
117
            }
118
        }
119
    }
120
    *buf = bp;
121
}
122
 
123
static void
124
cf_parse_timing_structure(unsigned char **buf)
125
{
126
    unsigned char *bp = *buf;
127
    unsigned char tpce_td = *bp++;
128
    if ((tpce_td & 0x1C) != 0x1C) {
129
//        diag_printf("READY = %x.%x\n",(tpce_td & 0x1C)>>2, *bp); 
130
        bp++;
131
    }
132
    if ((tpce_td & 0x03) != 0x03) {
133
//        diag_printf("WAIT = %x.%x\n",(tpce_td & 0x03)>>0, *bp); 
134
        bp++;
135
    }
136
    *buf = bp;
137
}
138
 
139
static void
140
cf_parse_IO_space_structure(unsigned char **buf, struct cf_io_space *io_space)
141
{
142
    unsigned char *bp = *buf;
143
    unsigned char tpce_io = *bp++;
144
    unsigned char rd;
145
    unsigned long base = 0, length = 0;
146
    int i;
147
    io_space->mode = (tpce_io & 0x60) >> 5;
148
    if (tpce_io & 0x80) {
149
        rd = *bp++;
150
        io_space->num_addrs = (rd & 0x0F) + 1;
151
        for (i = 0;  i < io_space->num_addrs;  i++) {
152
            // Address
153
            switch ((rd & 0x30) >> 4) {
154
            case 0:
155
                break;  // Not present (shouldn't happen)
156
            case 1:
157
                base = *bp++;
158
                break;
159
            case 2:
160
                base = (bp[1] << 8) | bp[0];
161
                bp += 2;
162
                break;
163
            case 3:
164
                base = (bp[3] << 24) | (bp[2] << 16) | (bp[1] << 8) | bp[0];
165
                bp += 4;
166
                break;
167
            }
168
            io_space->base[i] = base;
169
            // Length
170
            switch ((rd & 0xC0) >> 6) {
171
            case 0:
172
                break;  // Not present (shouldn't happen)
173
            case 1:
174
                length = *bp++;
175
                break;
176
            case 2:
177
                length = (bp[1] << 8) | bp[0];
178
                bp += 2;
179
                break;
180
            case 3:
181
                length = (bp[3] << 24) | (bp[2] << 16) | (bp[1] << 8) | bp[0];
182
                bp += 4;
183
                break;
184
            }
185
            length++;
186
            io_space->size[i] = length;
187
//            diag_printf("IO addr %d - base: %x, length: %x\n", i, base, length);
188
        }
189
    }
190
    *buf = bp;
191
}
192
 
193
bool
194
cf_parse_cftable(unsigned char *buf, int len, struct cf_cftable *cftable)
195
{
196
    unsigned char tpce_indx, tpce_fs;
197
    if (*buf++ != CF_CISTPL_CFTABLE_ENTRY) {
198
        diag_printf("%s - called with invalid CIS: %x\n", __FUNCTION__, *--buf);
199
        return false;
200
    }
201
    buf++;  // Skip length/link
202
    tpce_indx = *buf++;
203
    cftable->cor = tpce_indx & 0x3F;
204
    if (tpce_indx & 0x80) {
205
        cftable->interface = *buf++;
206
    }
207
    cftable->feature_select = tpce_fs = *buf++;
208
    if (tpce_fs & 0x01) {
209
        cf_parse_power_structure(&buf);
210
    }
211
    if (tpce_fs & 0x02) {
212
        cf_parse_power_structure(&buf);
213
    }
214
    if (tpce_fs & 0x04) {
215
        cf_parse_timing_structure(&buf);
216
    }
217
    if (tpce_fs & 0x08) {
218
        cf_parse_IO_space_structure(&buf, &cftable->io_space);
219
    }
220
    return true;
221
}
222
 
223
bool
224
cf_parse_config(unsigned char *buf, int len, struct cf_config *config)
225
{
226
    unsigned char tpcc_sz;
227
    int i;
228
    if (*buf++ != CF_CISTPL_CONFIG) {
229
        diag_printf("%s - called with invalid CIS: %x\n", __FUNCTION__, *--buf);
230
        return false;
231
    }
232
    buf++;  // Skip length/link
233
    tpcc_sz = *buf++;
234
    buf++;  // Skip 'last' pointer
235
    config->base = 0;
236
    for (i = (tpcc_sz & 0x03);  i >= 0;  i--) {
237
        config->base = (config->base << 8) | buf[i];
238
    }
239
    buf += (tpcc_sz & 0x03) + 1;
240
    config->mask_length = ((tpcc_sz & 0x3C) >> 2) + 1;
241
    for (i = 0;  i < config->mask_length;  i++) {
242
        config->mask[i] = *buf++;
243
    }
244
    return true;
245
}
246
 
247
//
248
// Return a pointer to the slot descriptor for a given slot
249
//
250
struct cf_slot *
251
cf_get_slot(int indx)
252
{
253
    if ((indx >= 0) && (indx < CF_NUM_SLOTS)) {
254
        return &cf_slots[indx];
255
    } else {
256
        diag_printf("PCMCIA: Invalid slot %d\n", indx);
257
        return (struct cf_slot *)0;
258
    }
259
}
260
 
261
//
262
// Initialize all PCMCIA (Compact Flash) slots
263
//
264
void
265
cf_init(void)
266
{
267
    int i;
268
    for (i = 0;  i < CF_NUM_SLOTS; i++) {
269
        cf_slots[i].index = i;
270
        cf_hwr_init(&cf_slots[i]);
271
    }
272
}
273
 
274
//
275
// Transition a card/slot
276
//
277
void
278
cf_change_state(struct cf_slot *slot, int desired_state)
279
{
280
    cf_hwr_change_state(slot, desired_state);
281
}
282
 
283
//
284
// Register an interrupt handler
285
//
286
void
287
cf_register_handler(struct cf_slot *slot,
288
                    void (*handler)(int, int, void *),
289
                    void *param)
290
{
291
    slot->irq_handler.handler = handler;
292
    slot->irq_handler.param = param;
293
}
294
 
295
//
296
// Allow interrupt function to acknowledge interrupt
297
//
298
void
299
cf_clear_interrupt(struct cf_slot *slot)
300
{
301
    cf_hwr_clear_interrupt(slot);
302
}
303
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.