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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [pcmcia/] [arm/] [ipaq/] [current/] [src/] [ipaq_pcmcia.c] - Blame information for rev 810

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      devs/pcmcia/ipaq/ipaq_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
//               richard.panton@3glab.com
45
// Date:         2001-02-24
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/ipaq.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_drv_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_drv_interrupt_acknowledge(SA1110_CF_DETECT);
98
    cyg_drv_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
static void
132
do_delay(int ticks)
133
{
134
#ifdef CYGPKG_KERNEL
135
    cyg_thread_delay(ticks);
136
#else
137
    CYGACC_CALL_IF_DELAY_US(10000*ticks);
138
#endif
139
}
140
 
141
//
142
// Fill in the details of a PCMCIA slot and initialize the device
143
//
144
void
145
cf_hwr_init(struct cf_slot *slot)
146
{
147
    static int int_init = 0;
148
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
149
 
150
    if (!int_init) {
151
        int_init = 1;
152
#ifdef CYGPKG_KERNEL
153
        // Set up interrupts
154
        cyg_drv_interrupt_create(SA1110_CF_DETECT,
155
                                 99,                     // Priority - what goes here?
156
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
157
                                 (cyg_ISR_t *)cf_detect_isr,
158
                                 (cyg_DSR_t *)cf_detect_dsr,
159
                                 &cf_detect_interrupt_handle,
160
                                 &cf_detect_interrupt);
161
        cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
162
        cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true);  // Detect either edge
163
        cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
164
        cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
165
 
166
        cyg_drv_interrupt_create(SA1110_CF_IRQ,
167
                                 99,                     // Priority - what goes here?
168
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
169
                                 (cyg_ISR_t *)cf_irq_isr,
170
                                 (cyg_DSR_t *)cf_irq_dsr,
171
                                 &cf_irq_interrupt_handle,
172
                                 &cf_irq_interrupt);
173
        cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
174
        cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
175
        cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false);  // Falling edge
176
        cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
177
#endif
178
    }
179
    slot->attr = (unsigned char *)0x28000000;
180
    slot->attr_length = 0x200;
181
    slot->io = (unsigned char *)0x20000000;
182
    slot->io_length = 0x04000000;
183
    slot->mem = (unsigned char *)0x2C000000;
184
    slot->mem_length = 0x04000000;
185
    slot->int_num = SA1110_CF_IRQ;
186
#ifdef CYG_HAL_STARTUP_ROM
187
    // Disable CF bus & power (idle/off)
188
    ipaq_EGPIO( SA1110_EIO_OPT_PWR | SA1110_EIO_OPT | SA1110_EIO_CF_RESET,
189
                SA1110_EIO_OPT_PWR_ON | SA1110_EIO_OPT_ON | SA1110_EIO_CF_RESET_ENABLE );
190
#endif
191
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
192
        if ((_ipaq_EGPIO & SA1110_EIO_OPT_PWR) == SA1110_EIO_OPT_PWR_ON) {
193
            // Assume that the ROM environment has turned the bus on
194
            slot->state = CF_SLOT_STATE_Ready;
195
        } else {
196
            slot->state = CF_SLOT_STATE_Inserted;
197
        }
198
    } else {
199
        slot->state = CF_SLOT_STATE_Empty;
200
    }
201
}
202
 
203
void
204
cf_hwr_poll(struct cf_slot *slot)
205
{
206
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
207
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
208
        slot->state = CF_SLOT_STATE_Inserted;
209
    } else {
210
        slot->state = CF_SLOT_STATE_Empty;
211
    }
212
}
213
 
214
//
215
// Transition the card/slot to a new state
216
// note: currently only supports transitions to Ready, Empty
217
//
218
void
219
cf_hwr_change_state(struct cf_slot *slot, int new_state)
220
{
221
    int i, ptr, len;
222
    unsigned char buf[256];
223
 
224
    if (new_state == CF_SLOT_STATE_Ready) {
225
        if (slot->state == CF_SLOT_STATE_Inserted) {
226
            ipaq_EGPIO( SA1110_EIO_OPT_PWR | SA1110_EIO_OPT | SA1110_EIO_CF_RESET,
227
                        SA1110_EIO_OPT_PWR_ON | SA1110_EIO_OPT_ON | SA1110_EIO_CF_RESET_DISABLE);
228
            do_delay(30);  // At least 300 ms
229
            slot->state = CF_SLOT_STATE_Powered;
230
            ipaq_EGPIO( SA1110_EIO_CF_RESET, SA1110_EIO_CF_RESET_ENABLE);
231
            *(volatile unsigned short *)IPAQ_CF_CTRL = IPAQ_CF_CTRL_V5_DISABLE |
232
                                                       IPAQ_CF_CTRL_V3_ENABLE |
233
                                                       IPAQ_CF_CTRL_RESET_ENABLE |
234
                                                       IPAQ_CF_CTRL_APOE_ENABLE |
235
                                                       IPAQ_CF_CTRL_SOE_ENABLE;
236
            do_delay(1);  // At least 10 us
237
            slot->state = CF_SLOT_STATE_Reset;
238
            ipaq_EGPIO( SA1110_EIO_CF_RESET, SA1110_EIO_CF_RESET_DISABLE);
239
            do_delay(5); // At least 20 ms
240
            // This is necessary for the two slot sleeve and doesn't seem to
241
            // hurt on the single slot versions.  Note: only 3.3V is ever used!
242
            *(volatile unsigned short *)IPAQ_CF_CTRL = IPAQ_CF_CTRL_V5_DISABLE |
243
                                                       IPAQ_CF_CTRL_V3_ENABLE |
244
                                                       IPAQ_CF_CTRL_RESET_DISABLE |
245
                                                       IPAQ_CF_CTRL_APOE_ENABLE |
246
                                                       IPAQ_CF_CTRL_SOE_ENABLE;
247
            do_delay(5); // At least 20 ms
248
            // Wait until the card is ready to talk
249
            for (i = 0;  i < 10;  i++) {
250
                ptr = 0;
251
                if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
252
                    slot->state = CF_SLOT_STATE_Ready;
253
                    break;
254
                }
255
                do_delay(10);
256
            }
257
        }
258
    }
259
}
260
 
261
//
262
// Acknowledge interrupt (used in non-kernel environments)
263
//
264
void
265
cf_hwr_clear_interrupt(struct cf_slot *slot)
266
{
267
    // Clear interrupt [edge indication]
268
    cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
269
}

powered by: WebSVN 2.1.0

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