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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [pcmcia/] [arm/] [cerfpda/] [current/] [src/] [cerfpda_pcmcia.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      devs/pcmcia/cerfpda/cerfpda_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/hal/hal_io.h>             // IO macros
55
#include <cyg/hal/hal_arch.h>           // Register state info
56
#include <cyg/hal/hal_intr.h>           // HAL interrupt macros
57
#include <cyg/hal/drv_api.h>
58
 
59
#ifdef CYGPKG_KERNEL
60
#include <pkgconf/kernel.h>   // Configuration header
61
#include <cyg/kernel/kapi.h>
62
#endif
63
#include <cyg/hal/hal_if.h>
64
 
65
#include <cyg/io/pcmcia.h>
66
#include <cyg/infra/diag.h>
67
 
68
#include <cyg/hal/hal_sa11x0.h>  // Board definitions
69
#include <cyg/hal/cerfpda.h>
70
 
71
#ifdef CYGPKG_KERNEL
72
static cyg_interrupt cf_detect_interrupt;
73
static cyg_handle_t  cf_detect_interrupt_handle;
74
static cyg_interrupt cf_irq_interrupt;
75
static cyg_handle_t  cf_irq_interrupt_handle;
76
 
77
// This ISR is called when a CompactFlash board is inserted
78
static int
79
cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
80
{
81
    cyg_interrupt_mask(SA1110_CF_DETECT);
82
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
83
}
84
 
85
// This DSR handles the board insertion
86
static void
87
cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
88
{
89
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
90
    struct cf_slot *slot = (struct cf_slot *)data;
91
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
92
        slot->state = CF_SLOT_STATE_Inserted;
93
    } else {
94
        slot->state = CF_SLOT_STATE_Removed;  // Implies powered up, etc.
95
    }
96
    cyg_interrupt_acknowledge(SA1110_CF_DETECT);
97
    cyg_interrupt_unmask(SA1110_CF_DETECT);
98
}
99
 
100
// This ISR is called when the card interrupt occurs
101
static int
102
cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
103
{
104
    cyg_drv_interrupt_mask(SA1110_CF_IRQ);
105
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
106
}
107
 
108
// This DSR handles the card interrupt
109
static void
110
cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
111
{
112
    struct cf_slot *slot = (struct cf_slot *)data;
113
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
114
    cyg_bool was_ctrlc_int;
115
#endif
116
 
117
    // Clear interrupt [edge indication]
118
    cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
119
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
120
    was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
121
    if (!was_ctrlc_int) // Fall through and run normal code
122
#endif
123
    // Process interrupt
124
    (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
125
    // Allow interrupts to happen again
126
    cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
127
}
128
#endif
129
 
130
//
131
// Fill in the details of a PCMCIA slot and initialize the device
132
//
133
void
134
cf_hwr_init(struct cf_slot *slot)
135
{
136
    static int int_init = 0;
137
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
138
    if (!int_init) {
139
        int_init = 1;
140
#ifdef CYGPKG_KERNEL
141
        // Set up interrupts
142
        cyg_drv_interrupt_create(SA1110_CF_DETECT,
143
                                 99,                     // Priority - what goes here?
144
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
145
                                 (cyg_ISR_t *)cf_detect_isr,
146
                                 (cyg_DSR_t *)cf_detect_dsr,
147
                                 &cf_detect_interrupt_handle,
148
                                 &cf_detect_interrupt);
149
        cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
150
        cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true);  // Detect either edge
151
        cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
152
        cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
153
        cyg_drv_interrupt_create(SA1110_CF_IRQ,
154
                                 99,                     // Priority - what goes here?
155
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
156
                                 (cyg_ISR_t *)cf_irq_isr,
157
                                 (cyg_DSR_t *)cf_irq_dsr,
158
                                 &cf_irq_interrupt_handle,
159
                                 &cf_irq_interrupt);
160
        cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
161
        cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
162
#endif
163
        cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false);  // Falling edge
164
        cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
165
    }
166
    slot->attr = (unsigned char *)0x38000000;
167
    slot->attr_length = 0x200;
168
    slot->io = (unsigned char *)0x30000000;
169
    slot->io_length = 0x04000000;
170
    slot->mem = (unsigned char *)0x3C000000;
171
    slot->mem_length = 0x04000000;
172
    slot->int_num = SA1110_CF_IRQ;
173
#ifdef CYG_HAL_STARTUP_ROM
174
    // Disable CF bus & power (idle/off)
175
    cerfpda_BCR(SA1110_BCR_CF_POWER |
176
                SA1110_BCR_CF_RESET |
177
                SA1110_BCR_CF_BUS,
178
                SA1110_BCR_CF_POWER_OFF |
179
                SA1110_BCR_CF_RESET_DISABLE |
180
                SA1110_BCR_CF_BUS_OFF);
181
#endif
182
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
183
        if ((_cerfpda_BCR & SA1110_BCR_CF_POWER) == SA1110_BCR_CF_POWER_ON) {
184
            // Assume that the ROM environment has turned the bus on
185
            slot->state = CF_SLOT_STATE_Ready;
186
        } else {
187
            slot->state = CF_SLOT_STATE_Inserted;
188
        }
189
    } else {
190
        slot->state = CF_SLOT_STATE_Empty;
191
    }
192
}
193
 
194
void
195
cf_hwr_poll(struct cf_slot *slot)
196
{
197
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
198
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
199
        slot->state = CF_SLOT_STATE_Inserted;
200
    } else {
201
        slot->state = CF_SLOT_STATE_Empty;
202
    }
203
}
204
 
205
static void
206
do_delay(int ticks)
207
{
208
#ifdef CYGPKG_KERNEL
209
    cyg_thread_delay(ticks);
210
#else
211
    CYGACC_CALL_IF_DELAY_US(10000*ticks);
212
#endif
213
}
214
 
215
//
216
// Transition the card/slot to a new state
217
// note: currently only supports transitions to Ready, Empty
218
//
219
bool
220
cf_hwr_change_state(struct cf_slot *slot, int new_state)
221
{
222
    int i, ptr, len;
223
    unsigned char buf[256];
224
 
225
    if (new_state == CF_SLOT_STATE_Ready) {
226
        if (slot->state == CF_SLOT_STATE_Inserted) {
227
            cerfpda_BCR(SA1110_BCR_CF_POWER |
228
                        SA1110_BCR_CF_RESET |
229
                        SA1110_BCR_CF_BUS,
230
                        SA1110_BCR_CF_POWER_ON |
231
                        SA1110_BCR_CF_RESET_DISABLE |
232
                        SA1110_BCR_CF_BUS_OFF);
233
            do_delay(30);  // At least 300 ms
234
            slot->state = CF_SLOT_STATE_Powered;
235
            cerfpda_BCR(SA1110_BCR_CF_POWER |
236
                        SA1110_BCR_CF_RESET |
237
                        SA1110_BCR_CF_BUS,
238
                        SA1110_BCR_CF_POWER_ON |
239
                        SA1110_BCR_CF_RESET_ENABLE |
240
                        SA1110_BCR_CF_BUS_ON);
241
            do_delay(1);  // At least 10 us
242
            slot->state = CF_SLOT_STATE_Reset;
243
            cerfpda_BCR(SA1110_BCR_CF_POWER |
244
                        SA1110_BCR_CF_RESET |
245
                        SA1110_BCR_CF_BUS,
246
                        SA1110_BCR_CF_POWER_ON |
247
                        SA1110_BCR_CF_RESET_DISABLE |
248
                        SA1110_BCR_CF_BUS_ON);
249
            do_delay(5); // At least 20 ms
250
            // Wait until the card is ready to talk
251
            for (i = 0;  i < 10;  i++) {
252
                ptr = 0;
253
                if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
254
                    slot->state = CF_SLOT_STATE_Ready;
255
                    break;
256
                }
257
                do_delay(10);
258
            }
259
        }
260
    }
261
}
262
 
263
//
264
// Acknowledge interrupt (used in non-kernel environments)
265
//
266
void
267
cf_hwr_clear_interrupt(struct cf_slot *slot)
268
{
269
    // Clear interrupt [edge indication]
270
    cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
271
}

powered by: WebSVN 2.1.0

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