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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [pcmcia/] [arm/] [cerfpda/] [v2_0/] [src/] [cerfpda_pcmcia.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
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 Red Hat, 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 version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    gthomas
44
// Contributors: gthomas
45
// Date:         2000-07-06
46
// Purpose:      PCMCIA support
47
// Description: 
48
//
49
//####DESCRIPTIONEND####
50
//
51
//==========================================================================
52
 
53
#include <pkgconf/io_pcmcia.h>
54
 
55
#include <cyg/hal/hal_io.h>             // IO macros
56
#include <cyg/hal/hal_arch.h>           // Register state info
57
#include <cyg/hal/hal_intr.h>           // HAL interrupt macros
58
#include <cyg/hal/drv_api.h>
59
 
60
#ifdef CYGPKG_KERNEL
61
#include <pkgconf/kernel.h>   // Configuration header
62
#include <cyg/kernel/kapi.h>
63
#endif
64
#include <cyg/hal/hal_if.h>
65
 
66
#include <cyg/io/pcmcia.h>
67
#include <cyg/infra/diag.h>
68
 
69
#include <cyg/hal/hal_sa11x0.h>  // Board definitions
70
#include <cyg/hal/cerfpda.h>
71
 
72
#ifdef CYGPKG_KERNEL
73
static cyg_interrupt cf_detect_interrupt;
74
static cyg_handle_t  cf_detect_interrupt_handle;
75
static cyg_interrupt cf_irq_interrupt;
76
static cyg_handle_t  cf_irq_interrupt_handle;
77
 
78
// This ISR is called when a CompactFlash board is inserted
79
static int
80
cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
81
{
82
    cyg_interrupt_mask(SA1110_CF_DETECT);
83
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
84
}
85
 
86
// This DSR handles the board insertion
87
static void
88
cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
89
{
90
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
91
    struct cf_slot *slot = (struct cf_slot *)data;
92
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
93
        slot->state = CF_SLOT_STATE_Inserted;
94
    } else {
95
        slot->state = CF_SLOT_STATE_Removed;  // Implies powered up, etc.
96
    }
97
    cyg_interrupt_acknowledge(SA1110_CF_DETECT);
98
    cyg_interrupt_unmask(SA1110_CF_DETECT);
99
}
100
 
101
// This ISR is called when the card interrupt occurs
102
static int
103
cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
104
{
105
    cyg_drv_interrupt_mask(SA1110_CF_IRQ);
106
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
107
}
108
 
109
// This DSR handles the card interrupt
110
static void
111
cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
112
{
113
    struct cf_slot *slot = (struct cf_slot *)data;
114
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
115
    cyg_bool was_ctrlc_int;
116
#endif
117
 
118
    // Clear interrupt [edge indication]
119
    cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
120
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
121
    was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
122
    if (!was_ctrlc_int) // Fall through and run normal code
123
#endif
124
    // Process interrupt
125
    (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
126
    // Allow interrupts to happen again
127
    cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
128
}
129
#endif
130
 
131
//
132
// Fill in the details of a PCMCIA slot and initialize the device
133
//
134
void
135
cf_hwr_init(struct cf_slot *slot)
136
{
137
    static int int_init = 0;
138
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
139
    if (!int_init) {
140
        int_init = 1;
141
#ifdef CYGPKG_KERNEL
142
        // Set up interrupts
143
        cyg_drv_interrupt_create(SA1110_CF_DETECT,
144
                                 99,                     // Priority - what goes here?
145
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
146
                                 (cyg_ISR_t *)cf_detect_isr,
147
                                 (cyg_DSR_t *)cf_detect_dsr,
148
                                 &cf_detect_interrupt_handle,
149
                                 &cf_detect_interrupt);
150
        cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
151
        cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true);  // Detect either edge
152
        cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
153
        cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
154
        cyg_drv_interrupt_create(SA1110_CF_IRQ,
155
                                 99,                     // Priority - what goes here?
156
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
157
                                 (cyg_ISR_t *)cf_irq_isr,
158
                                 (cyg_DSR_t *)cf_irq_dsr,
159
                                 &cf_irq_interrupt_handle,
160
                                 &cf_irq_interrupt);
161
        cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
162
        cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
163
#endif
164
        cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false);  // Falling edge
165
        cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
166
    }
167
    slot->attr = (unsigned char *)0x38000000;
168
    slot->attr_length = 0x200;
169
    slot->io = (unsigned char *)0x30000000;
170
    slot->io_length = 0x04000000;
171
    slot->mem = (unsigned char *)0x3C000000;
172
    slot->mem_length = 0x04000000;
173
    slot->int_num = SA1110_CF_IRQ;
174
#ifdef CYG_HAL_STARTUP_ROM
175
    // Disable CF bus & power (idle/off)
176
    cerfpda_BCR(SA1110_BCR_CF_POWER |
177
                SA1110_BCR_CF_RESET |
178
                SA1110_BCR_CF_BUS,
179
                SA1110_BCR_CF_POWER_OFF |
180
                SA1110_BCR_CF_RESET_DISABLE |
181
                SA1110_BCR_CF_BUS_OFF);
182
#endif
183
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
184
        if ((_cerfpda_BCR & SA1110_BCR_CF_POWER) == SA1110_BCR_CF_POWER_ON) {
185
            // Assume that the ROM environment has turned the bus on
186
            slot->state = CF_SLOT_STATE_Ready;
187
        } else {
188
            slot->state = CF_SLOT_STATE_Inserted;
189
        }
190
    } else {
191
        slot->state = CF_SLOT_STATE_Empty;
192
    }
193
}
194
 
195
void
196
cf_hwr_poll(struct cf_slot *slot)
197
{
198
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
199
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
200
        slot->state = CF_SLOT_STATE_Inserted;
201
    } else {
202
        slot->state = CF_SLOT_STATE_Empty;
203
    }
204
}
205
 
206
static void
207
do_delay(int ticks)
208
{
209
#ifdef CYGPKG_KERNEL
210
    cyg_thread_delay(ticks);
211
#else
212
    CYGACC_CALL_IF_DELAY_US(10000*ticks);
213
#endif
214
}
215
 
216
//
217
// Transition the card/slot to a new state
218
// note: currently only supports transitions to Ready, Empty
219
//
220
bool
221
cf_hwr_change_state(struct cf_slot *slot, int new_state)
222
{
223
    int i, ptr, len;
224
    unsigned char buf[256];
225
 
226
    if (new_state == CF_SLOT_STATE_Ready) {
227
        if (slot->state == CF_SLOT_STATE_Inserted) {
228
            cerfpda_BCR(SA1110_BCR_CF_POWER |
229
                        SA1110_BCR_CF_RESET |
230
                        SA1110_BCR_CF_BUS,
231
                        SA1110_BCR_CF_POWER_ON |
232
                        SA1110_BCR_CF_RESET_DISABLE |
233
                        SA1110_BCR_CF_BUS_OFF);
234
            do_delay(30);  // At least 300 ms
235
            slot->state = CF_SLOT_STATE_Powered;
236
            cerfpda_BCR(SA1110_BCR_CF_POWER |
237
                        SA1110_BCR_CF_RESET |
238
                        SA1110_BCR_CF_BUS,
239
                        SA1110_BCR_CF_POWER_ON |
240
                        SA1110_BCR_CF_RESET_ENABLE |
241
                        SA1110_BCR_CF_BUS_ON);
242
            do_delay(1);  // At least 10 us
243
            slot->state = CF_SLOT_STATE_Reset;
244
            cerfpda_BCR(SA1110_BCR_CF_POWER |
245
                        SA1110_BCR_CF_RESET |
246
                        SA1110_BCR_CF_BUS,
247
                        SA1110_BCR_CF_POWER_ON |
248
                        SA1110_BCR_CF_RESET_DISABLE |
249
                        SA1110_BCR_CF_BUS_ON);
250
            do_delay(5); // At least 20 ms
251
            // Wait until the card is ready to talk
252
            for (i = 0;  i < 10;  i++) {
253
                ptr = 0;
254
                if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
255
                    slot->state = CF_SLOT_STATE_Ready;
256
                    break;
257
                }
258
                do_delay(10);
259
            }
260
        }
261
    }
262
}
263
 
264
//
265
// Acknowledge interrupt (used in non-kernel environments)
266
//
267
void
268
cf_hwr_clear_interrupt(struct cf_slot *slot)
269
{
270
    // Clear interrupt [edge indication]
271
    cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
272
}

powered by: WebSVN 2.1.0

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