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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [pcmcia/] [arm/] [ipaq/] [v2_0/] [src/] [ipaq_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/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 Red Hat, Inc.
12
// Copyright (C) 2002 Gary Thomas
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// 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 along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38
// at http://sources.redhat.com/ecos/ecos-license/
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//==========================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):    gthomas
45
// Contributors: gthomas
46
//               richard.panton@3glab.com
47
// Date:         2001-02-24
48
// Purpose:      PCMCIA support
49
// Description: 
50
//
51
//####DESCRIPTIONEND####
52
//
53
//==========================================================================
54
 
55
#include <pkgconf/io_pcmcia.h>
56
 
57
#include <cyg/hal/hal_io.h>             // IO macros
58
#include <cyg/hal/hal_arch.h>           // Register state info
59
#include <cyg/hal/hal_intr.h>           // HAL interrupt macros
60
#include <cyg/hal/drv_api.h>
61
 
62
#ifdef CYGPKG_KERNEL
63
#include <pkgconf/kernel.h>   // Configuration header
64
#include <cyg/kernel/kapi.h>
65
#endif
66
#include <cyg/hal/hal_if.h>
67
 
68
#include <cyg/io/pcmcia.h>
69
#include <cyg/infra/diag.h>
70
 
71
#include <cyg/hal/hal_sa11x0.h>  // Board definitions
72
#include <cyg/hal/ipaq.h>
73
 
74
#ifdef CYGPKG_KERNEL
75
static cyg_interrupt cf_detect_interrupt;
76
static cyg_handle_t  cf_detect_interrupt_handle;
77
static cyg_interrupt cf_irq_interrupt;
78
static cyg_handle_t  cf_irq_interrupt_handle;
79
 
80
// This ISR is called when a CompactFlash board is inserted
81
static int
82
cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
83
{
84
    cyg_drv_interrupt_mask(SA1110_CF_DETECT);
85
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
86
}
87
 
88
// This DSR handles the board insertion
89
static void
90
cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
91
{
92
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
93
    struct cf_slot *slot = (struct cf_slot *)data;
94
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
95
        slot->state = CF_SLOT_STATE_Inserted;
96
    } else {
97
        slot->state = CF_SLOT_STATE_Removed;  // Implies powered up, etc.
98
    }
99
    cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
100
    cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
101
}
102
 
103
// This ISR is called when the card interrupt occurs
104
static int
105
cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
106
{
107
    cyg_drv_interrupt_mask(SA1110_CF_IRQ);
108
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
109
}
110
 
111
// This DSR handles the card interrupt
112
static void
113
cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
114
{
115
    struct cf_slot *slot = (struct cf_slot *)data;
116
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
117
    cyg_bool was_ctrlc_int;
118
#endif
119
 
120
    // Clear interrupt [edge indication]
121
    cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
122
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
123
    was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
124
    if (!was_ctrlc_int) // Fall through and run normal code
125
#endif
126
    // Process interrupt
127
    (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
128
    // Allow interrupts to happen again
129
    cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
130
}
131
#endif
132
 
133
static void
134
do_delay(int ticks)
135
{
136
#ifdef CYGPKG_KERNEL
137
    cyg_thread_delay(ticks);
138
#else
139
    CYGACC_CALL_IF_DELAY_US(10000*ticks);
140
#endif
141
}
142
 
143
//
144
// Fill in the details of a PCMCIA slot and initialize the device
145
//
146
void
147
cf_hwr_init(struct cf_slot *slot)
148
{
149
    static int int_init = 0;
150
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
151
 
152
    if (!int_init) {
153
        int_init = 1;
154
#ifdef CYGPKG_KERNEL
155
        // Set up interrupts
156
        cyg_drv_interrupt_create(SA1110_CF_DETECT,
157
                                 99,                     // Priority - what goes here?
158
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
159
                                 (cyg_ISR_t *)cf_detect_isr,
160
                                 (cyg_DSR_t *)cf_detect_dsr,
161
                                 &cf_detect_interrupt_handle,
162
                                 &cf_detect_interrupt);
163
        cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
164
        cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true);  // Detect either edge
165
        cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
166
        cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
167
 
168
        cyg_drv_interrupt_create(SA1110_CF_IRQ,
169
                                 99,                     // Priority - what goes here?
170
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
171
                                 (cyg_ISR_t *)cf_irq_isr,
172
                                 (cyg_DSR_t *)cf_irq_dsr,
173
                                 &cf_irq_interrupt_handle,
174
                                 &cf_irq_interrupt);
175
        cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
176
        cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
177
        cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false);  // Falling edge
178
        cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
179
#endif
180
    }
181
    slot->attr = (unsigned char *)0x28000000;
182
    slot->attr_length = 0x200;
183
    slot->io = (unsigned char *)0x20000000;
184
    slot->io_length = 0x04000000;
185
    slot->mem = (unsigned char *)0x2C000000;
186
    slot->mem_length = 0x04000000;
187
    slot->int_num = SA1110_CF_IRQ;
188
#ifdef CYG_HAL_STARTUP_ROM
189
    // Disable CF bus & power (idle/off)
190
    ipaq_EGPIO( SA1110_EIO_OPT_PWR | SA1110_EIO_OPT | SA1110_EIO_CF_RESET,
191
                SA1110_EIO_OPT_PWR_ON | SA1110_EIO_OPT_ON | SA1110_EIO_CF_RESET_ENABLE );
192
#endif
193
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
194
        if ((_ipaq_EGPIO & SA1110_EIO_OPT_PWR) == SA1110_EIO_OPT_PWR_ON) {
195
            // Assume that the ROM environment has turned the bus on
196
            slot->state = CF_SLOT_STATE_Ready;
197
        } else {
198
            slot->state = CF_SLOT_STATE_Inserted;
199
        }
200
    } else {
201
        slot->state = CF_SLOT_STATE_Empty;
202
    }
203
}
204
 
205
void
206
cf_hwr_poll(struct cf_slot *slot)
207
{
208
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
209
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
210
        slot->state = CF_SLOT_STATE_Inserted;
211
    } else {
212
        slot->state = CF_SLOT_STATE_Empty;
213
    }
214
}
215
 
216
//
217
// Transition the card/slot to a new state
218
// note: currently only supports transitions to Ready, Empty
219
//
220
void
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
            ipaq_EGPIO( SA1110_EIO_OPT_PWR | SA1110_EIO_OPT | SA1110_EIO_CF_RESET,
229
                        SA1110_EIO_OPT_PWR_ON | SA1110_EIO_OPT_ON | SA1110_EIO_CF_RESET_DISABLE);
230
            do_delay(30);  // At least 300 ms
231
            slot->state = CF_SLOT_STATE_Powered;
232
            ipaq_EGPIO( SA1110_EIO_CF_RESET, SA1110_EIO_CF_RESET_ENABLE);
233
            *(volatile unsigned short *)IPAQ_CF_CTRL = IPAQ_CF_CTRL_V5_DISABLE |
234
                                                       IPAQ_CF_CTRL_V3_ENABLE |
235
                                                       IPAQ_CF_CTRL_RESET_ENABLE |
236
                                                       IPAQ_CF_CTRL_APOE_ENABLE |
237
                                                       IPAQ_CF_CTRL_SOE_ENABLE;
238
            do_delay(1);  // At least 10 us
239
            slot->state = CF_SLOT_STATE_Reset;
240
            ipaq_EGPIO( SA1110_EIO_CF_RESET, SA1110_EIO_CF_RESET_DISABLE);
241
            do_delay(5); // At least 20 ms
242
            // This is necessary for the two slot sleeve and doesn't seem to
243
            // hurt on the single slot versions.  Note: only 3.3V is ever used!
244
            *(volatile unsigned short *)IPAQ_CF_CTRL = IPAQ_CF_CTRL_V5_DISABLE |
245
                                                       IPAQ_CF_CTRL_V3_ENABLE |
246
                                                       IPAQ_CF_CTRL_RESET_DISABLE |
247
                                                       IPAQ_CF_CTRL_APOE_ENABLE |
248
                                                       IPAQ_CF_CTRL_SOE_ENABLE;
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-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.