This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC MPC8xx PCMCIA driver


Hi,

Here's an eCos patch file for a PowerPC MPC8xx PCMCIA driver. The driver was developed using the MPC866 series of PowerPC processors. It depends on a few minor changes to the io-pcmcia interface, which I've already supplied a patch for.

Shaun Louie
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/cdl/pcmcia_mpc8xx.cdl ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/cdl/pcmcia_mpc8xx.cdl
--- ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/cdl/pcmcia_mpc8xx.cdl 1969-12-31 18:00:00.000000000 -0600
+++ ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/cdl/pcmcia_mpc8xx.cdl  2008-03-17 14:21:32.000000000 -0600
@@ -0,0 +1,154 @@
+# ====================================================================
+#
+#      PowerPC MPC8XX PCMCIA support
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):        Shaun Louie
+# Contributors:
+# Date:             2008-03-17
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_PCMCIA_MPC8XX {
+    display         "PowerPC MPC8XX PCMCIA support"
+    implements      CYGHWR_IO_PCMCIA_DEVICE
+    parent          CYGPKG_IO_PCMCIA
+    active_if       CYGPKG_IO_PCMCIA
+    active_if       CYGPKG_HAL_POWERPC_MPC8xx
+    include_dir     .
+    include_files   ; # none _exported_ whatsoever
+    description     "PCMCIA (Compact Flash) device support for owerPC MPC8XX"
+    compile         pcmcia_mpc8xx.c \
+                    pcmcia_mpc8xx_custom.c
+
+    cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_DETECT {
+        display         "Enable Detect Card Interrupt"
+        flavor          bool
+        calculated      0
+        description     "This option is currently not supported by the driver."
+    }
+
+    cdl_component CYGPKG_DEVS_PCMCIA_MPC8XX_MEMORY_MAP {
+        display       "PCMCIA Memory Mapping"
+        flavor        none
+        no_define
+        description   "
+            Memory mapping consts (Remember to change MMU table).
+            In eCos, if we want to have two slots we will have a problem with the
+            MMU because its memory-map table is too small (8M x 32).
+            For the M302, we just make it work with one slot (64M x 3).
+            See hal/powerpc/h302/current/src/hal_aux.c."
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_MEMORY_START {
+            display         "Start of PCMCIA space"
+            flavor          data
+            default_value   0xE0000000
+            description     ""
+        }
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_COMMON_SZ {
+            display         "Common memory size"
+            flavor          data
+            legal_values    {"64M"}
+            default_value   {"64M"}
+            description     ""
+        }
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_ATTR_SZ {
+            display         "Attribute memory size"
+            flavor          data
+            legal_values    {"64M"}
+            default_value   {"64M"}
+            description     ""
+        }
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_IO_SZ {
+            display         "IO memory size"
+            flavor          data
+            legal_values    {"64M"}
+            default_value   {"64M"}
+            description     ""
+        }
+    }
+
+    cdl_component CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO {
+        display       "GPIO Pin Settings"
+        flavor        none
+        no_define
+        description   "The following GPIO pins control a PCMCIA VCC
+            and VPP switch, such as a Linear Technology LTC1472CS.
+            If your board layout does not use Port C to connect to
+            the voltage switch or if the control of the switch is
+            completely different, then you'll need to make changes
+            to this configuration and related driver code."
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVCC_A0 {
+            display         "VCC Select 0 Pin (GPIO Port C)"
+            flavor          data
+            legal_values    0 to 15
+            default_value   4
+            description     ""
+        }
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVCC_A1 {
+            display         "VCC Select 1 Pin (GPIO Port C)"
+            flavor          data
+            legal_values    0 to 15
+            default_value   5
+            description     ""
+        }
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVPP_A0 {
+            display         "VPP Select 0 Pin (GPIO Port C)"
+            flavor          data
+            legal_values    0 to 15
+            default_value   6
+            description     ""
+        }
+
+        cdl_option CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVPP_A1 {
+            display         "VPP Select 1 Pin (GPIO Port C)"
+            flavor          data
+            legal_values    0 to 15
+            default_value   7
+            description     ""
+        }
+    }
+}
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/ChangeLog ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/ChangeLog
--- ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/ChangeLog 1969-12-31 18:00:00.000000000 -0600
+++ ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/ChangeLog  2008-03-13 12:18:44.000000000 -0600
@@ -0,0 +1,42 @@
+2008-03-13  Shaun Louie  <sal@microplex.com>
+
+    * cdl/pcmcia_mpc8xx.cdl:
+    * src/pcmcia_mpc8xx.c:
+    * src/pcmcia_mpc8xx.h:
+    * src/pcmcia_mpc8xx_custom.c:
+    Initial check-in of PowerPC PCMCIA device driver.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.c ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.c
--- ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.c   1969-12-31 18:00:00.000000000 -0600
+++ ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.c    2008-03-17 14:51:41.000000000 -0600
@@ -0,0 +1,835 @@
+//==========================================================================
+//
+//      PowerPC MPC8XX PCMCIA support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):       Shaun Louie
+// Contributors:    Shaun Louie
+// Date:            2008-03-17
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <string.h>
+
+#include <pkgconf/io_pcmcia.h>
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_arch.h>           // Register state info
+#include <cyg/hal/hal_intr.h>           // HAL interrupt macros
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>   // Configuration header
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/io/pcmcia.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/ppc8xx.h>
+#include "pcmcia_mpc8xx.h"
+
+#ifdef CYGPKG_KERNEL
+# ifdef CYGPKG_DEVS_PCMCIA_MPC8XX_DETECT
+static cyg_interrupt cf_detect_interrupt;
+static cyg_handle_t cf_detect_interrupt_handle;
+static int cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs);
+static void cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+# endif
+static cyg_interrupt cf_irq_interrupt;
+static cyg_handle_t cf_irq_interrupt_handle;
+static int cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs);
+static void cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_init
+ *  DESCRIPTION
+ *      Fill in the details of a PCMCIA slot and initialize the device
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+void
+cf_hwr_init(struct cf_slot * slot)
+{
+    static int                  int_init = 0;
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+    int                         i;
+
+    _pcmcia_custom_init();
+    HAL_DELAY_US(PCMCIA_POWER_OFF_DELAY);
+
+    /* Disable all PCMCIA interrupts. */
+    pcmciaRegPtr->per.reg = 0;
+    /* Clear all PCMCIA interrupt flags. */
+    pcmciaRegPtr->pscr.reg = 0xffffffff;
+    /* Invalidate all PCMCIA address spaces. */
+    for (i = 0; i < 8; i++) {
+        pcmciaRegPtr->pir.array[i].por = 0;
+    }
+    /*
+     * Configure the CPM interrupt level, and disable the output
+     * enable pin.  Note, both slots will use the same interrupt
+     * level.
+     */
+    pcmciaRegPtr->pgcr.reg.A = PCMCIA_PGCR_INTR_LVL(PCMCIA_INTERRUPT) | PCMCIA_PGCR_OE;
+    pcmciaRegPtr->pgcr.reg.B = PCMCIA_PGCR_INTR_LVL(PCMCIA_INTERRUPT) | PCMCIA_PGCR_OE;
+
+    /* Do a hard reset */
+    if ( ! cf_hwr_reset_hard(slot) ) {
+        slot->state = CF_SLOT_STATE_Empty;
+        return;
+    }
+
+    /* Initialiaze the interrupt service routine. */
+    if (!int_init) {
+        int_init = 1;
+#ifdef CYGPKG_KERNEL
+        // Set up interrupts
+# ifdef CYGPKG_DEVS_PCMCIA_MPC8XX_DETECT
+        cyg_drv_interrupt_create(SA1110_CF_DETECT,
+                                 CYGARC_SIU_PRIORITY_HIGH,
+                                 (cyg_addrword_t)slot, /* Data item passed to interrupt handler */
+                                 (cyg_ISR_t *)cf_detect_isr,
+                                 (cyg_DSR_t *)cf_detect_dsr,
+                                 &cf_detect_interrupt_handle,
+                                 &cf_detect_interrupt);
+        cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
+        cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true); /* Detect either edge */
+        cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
+        cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
+# endif /* CYGPKG_DEVS_PCMCIA_MPC8XX_DETECT */
+
+        cyg_drv_interrupt_create(PCMCIA_SIU_INTR,
+                                 CYGARC_SIU_PRIORITY_HIGH,
+                                 (cyg_addrword_t)slot, /* Data item passed to interrupt handler */
+                                 (cyg_ISR_t *)cf_irq_isr,
+                                 (cyg_DSR_t *)cf_irq_dsr,
+                                 &cf_irq_interrupt_handle,
+                                 &cf_irq_interrupt);
+        //cyg_drv_interrupt_configure(PCMCIA_SIU_INTR, false, false); /* Falling edge */
+        cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
+        cyg_drv_interrupt_acknowledge(PCMCIA_SIU_INTR);
+        cyg_drv_interrupt_unmask(PCMCIA_SIU_INTR);
+#endif /* CYGPKG_KERNEL */
+    }
+    slot->int_num = PCMCIA_SIU_INTR;
+
+    /* Attempt to switch to the ready state */
+    if ( ! cf_hwr_change_state(slot, CF_SLOT_STATE_Ready) ) {
+        slot->state = CF_SLOT_STATE_Empty;
+        return;
+    }
+} /* cf_hwr_init */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_poll
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+void
+cf_hwr_poll(struct cf_slot *slot)
+{
+    if (cf_hwr_card_inserted(slot)) {
+        if (1) {
+            slot->state = CF_SLOT_STATE_Ready;
+        }
+        else {
+            slot->state = CF_SLOT_STATE_Inserted;
+        }
+    }
+    else {
+        slot->state = CF_SLOT_STATE_Empty;
+    }
+} /* cf_hwr_poll */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_change_state
+ *  DESCRIPTION
+ *      Transition the card/slot to a new state
+ *      Currently only supports transition from Inserted to Ready
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *      new_state               ; new device state
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+cf_hwr_change_state(struct cf_slot *slot, int new_state)
+{
+    switch (slot->state) {
+        case CF_SLOT_STATE_Inserted:
+            if (new_state == CF_SLOT_STATE_Ready) {
+                /* Transition from Inserted to Ready */
+                /* Do a soft reset */
+                if ( ! cf_hwr_reset_soft(slot) ) {
+                    return false;
+                }
+                slot->state = CF_SLOT_STATE_Ready;
+                return true;
+            }
+            else {
+                return false;
+            }
+
+        default:
+            return false;
+    } /* switch */
+} /* cf_hwr_change_state */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_reset_hard
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+cf_hwr_reset_hard(struct cf_slot * slot)
+{
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+    unsigned char               tupleBuf[MAX_TUPLE_SZ];
+    unsigned char *             tupleBufPtr;
+    unsigned char               cardType;
+
+#if 0 /* Disabled, since it's not required for now. */
+    /* Disable slot's interrupts. */
+    pcmciaRegPtr->per.slot[slot->index] = 0x0000;
+    /* Clear slot's interrupt flags. */
+    pcmciaRegPtr->pscr.slot[slot->index] = 0xffff;
+    /* Invalidate slot's address spaces. */
+    pcmciaRegPtr->pir.slot[slot->index].comm.por = 0x00000000;
+    pcmciaRegPtr->pir.slot[slot->index].attr.por = 0x00000000;
+    pcmciaRegPtr->pir.slot[slot->index].io.por = 0x00000000;
+#endif
+    /* Disable card's output enable pin */
+    pcmciaRegPtr->pgcr.slot[slot->index] |= PCMCIA_PGCR_OE;
+
+    _pcmcia_custom_off(slot);
+    HAL_DELAY_US(PCMCIA_POWER_OFF_DELAY);
+
+    /* Enable card's output enable pin */
+    pcmciaRegPtr->pgcr.slot[slot->index] &= ~PCMCIA_PGCR_OE;
+    /* Is a card inserted. */
+    if ( ! cf_hwr_card_inserted(slot) ) {
+        /* No card, so disable card's output enable pin */
+        pcmciaRegPtr->pgcr.slot[slot->index] |= PCMCIA_PGCR_OE;
+        slot->state = CF_SLOT_STATE_Empty;
+        return false;
+    }
+    slot->state = CF_SLOT_STATE_Inserted;
+
+    /* Power-up card to a voltage determind by the voltage-select pins. */
+    _pcmcia_custom_on(slot, pcmciaRegPtr->pipr.slot[slot->index]);
+    HAL_DELAY_US(PCMCIA_POWER_ON_DELAY);
+
+    /* Give card a hard reset to make sure it fires-up. */
+    pcmciaRegPtr->pgcr.slot[slot->index] |= PCMCIA_PGCR_RESET;
+    HAL_DELAY_US(PCMCIA_HARD_RESET_PULSE);
+    pcmciaRegPtr->pgcr.slot[slot->index] &= ~PCMCIA_PGCR_RESET;
+    HAL_DELAY_US(PCMCIA_HARD_RESET_DELAY);
+
+    /* Initialize memory mapping for the PCMCIA channel. */
+    if ( ! _pcmcia_memmap_init(slot) ) {
+        _pcmcia_custom_off(slot);
+        HAL_DELAY_US(PCMCIA_POWER_OFF_DELAY);
+        return false;
+    }
+
+    /* Find out what card is at this PCMCIA channel */
+    tupleBufPtr = tupleBuf;
+    if ( ! _pcmcia_get_cis_tuple(slot, CF_CISTPL_FUNCID, tupleBufPtr) ) {
+        _pcmcia_custom_off(slot);
+        HAL_DELAY_US(PCMCIA_POWER_OFF_DELAY);
+        return false;
+    }
+    cardType = *(tupleBufPtr + 2);
+    if (cardType == CF_SLOT_TYPE_UNKNOWN) {
+        _pcmcia_custom_off(slot);
+        HAL_DELAY_US(PCMCIA_POWER_OFF_DELAY);
+        return false;
+    }
+    return true;
+} /* cf_hwr_reset_hard */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_reset_soft
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+cf_hwr_reset_soft(struct cf_slot * slot)
+{
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+    unsigned int                confBaseAddr;
+
+    if ( ! _pcmcia_conf_baseaddr(slot, &confBaseAddr) ) {
+        _pcmcia_custom_off(slot);
+        HAL_DELAY_US(PCMCIA_POWER_OFF_DELAY);
+        return false;
+    }
+    cf_set_COR(slot, confBaseAddr, CF_COR_SOFT_RESET);
+    HAL_DELAY_US(PCMCIA_SOFT_RESET_PULSE);
+    cf_set_COR(slot, confBaseAddr, (unsigned char)~CF_COR_SOFT_RESET);
+    HAL_DELAY_US(PCMCIA_SOFT_RESET_DELAY);
+    /* Clear all slot's interrupt flags. */
+    pcmciaRegPtr->pscr.slot[slot->index] = 0xffff;
+    return true;
+} /* cf_hwr_reset_soft */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_interrupt_enable
+ *  DESCRIPTION
+ *      Enable Pcmcia IRQ interrupt for a given slot.
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      none
+ *---------------------------------------------------------------
+ */
+void
+cf_hwr_interrupt_enable(struct cf_slot * slot)
+{
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+
+    if (slot->int_disable_nest_lvl) {
+        slot->int_disable_nest_lvl--;
+    }
+    if (slot->int_disable_nest_lvl == 0) {
+        /* Enable falling edge IRQ interrupt. */
+        pcmciaRegPtr->per.slot[slot->index] |= PCMCIA_IRQ_F;
+    }
+} /* cf_hwr_interrupt_enable */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_interrupt_disable
+ *  DESCRIPTION
+ *      Disable Pcmcia IRQ interrupt for a given slot.
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      none
+ *---------------------------------------------------------------
+ */
+void
+cf_hwr_interrupt_disable(struct cf_slot * slot)
+{
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+
+    if (slot->int_disable_nest_lvl == 0) {
+        /* Disable falling edge IRQ interrupt. */
+        pcmciaRegPtr->per.slot[slot->index] &= ~PCMCIA_IRQ_F;
+    }
+    slot->int_disable_nest_lvl++;
+} /* cf_hwr_interrupt_disable */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_clear_interrupt
+ *  DESCRIPTION
+ *      Acknowledge interrupt (used in non-kernel environments)
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+void
+cf_hwr_clear_interrupt(struct cf_slot *slot)
+{
+    cyg_drv_interrupt_acknowledge(PCMCIA_SIU_INTR);
+} /* cf_hwr_clear_interrupt */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_hwr_card_inserted
+ *  DESCRIPTION
+ *      Tests the harware to determine if a card is inserted
+ *      into a given slot.
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+cf_hwr_card_inserted(struct cf_slot *slot)
+{
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+
+    return ( (pcmciaRegPtr->pipr.slot[slot->index] & (PCMCIA_CD1 | PCMCIA_CD2)) == 0 );
+} /* cf_hwr_card_inserted */
+
+#ifdef CYGPKG_KERNEL
+# ifdef CYGPKG_DEVS_PCMCIA_MPC8XX_DETECT
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_detect_isr
+ *  DESCRIPTION
+ *      This ISR is called when a CompactFlash board is inserted
+ *  PARAMETERS
+ *      vector
+ *      data
+ *      regs
+ *  RETURNS
+ *      int
+ *---------------------------------------------------------------
+ */
+static int
+cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters * regs)
+{
+    cyg_interrupt_mask(SA1110_CF_DETECT);
+    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
+} /* cf_detect_isr */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_detect_dsr
+ *  DESCRIPTION
+ *      This DSR handles the board insertion
+ *  PARAMETERS
+ *      vector
+ *      count
+ *      data
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+static void
+cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    unsigned long               new_state = *SA11X0_GPIO_PIN_LEVEL;
+    struct cf_slot *            slot = (struct cf_slot *)data;
+
+    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+        slot->state = CF_SLOT_STATE_Inserted;
+    }
+    else {
+        slot->state = CF_SLOT_STATE_Removed;  // Implies powered up, etc.
+    }
+    cyg_interrupt_acknowledge(SA1110_CF_DETECT);
+    cyg_interrupt_unmask(SA1110_CF_DETECT);
+} /* cf_detect_dsr */
+# endif /* CYGPKG_DEVS_PCMCIA_MPC8XX_DETECT */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_irq_isr
+ *  DESCRIPTION
+ *      This ISR is called when the card interrupt occurs
+ *  PARAMETERS
+ *      vector
+ *      data
+ *      regs
+ *  RETURNS
+ *      int
+ *---------------------------------------------------------------
+ */
+static int
+cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters * regs)
+{
+    cyg_drv_interrupt_mask(PCMCIA_SIU_INTR);
+    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
+} /* cf_irq_isr */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      cf_irq_dsr
+ *  DESCRIPTION
+ *      This DSR handles the card interrupt
+ *  PARAMETERS
+ *      vector
+ *      count
+ *      data
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+static void
+cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    struct cf_slot *            slot = (struct cf_slot *)data;
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+
+    /* Test for falling edge on IRQ. */
+    if ( ! (pcmciaRegPtr->pscr.slot[slot->index] & PCMCIA_IRQ_F) ) {
+        goto Exit;
+    }
+    /* Clear interrupt flag (write '1' to clear). */
+    pcmciaRegPtr->pscr.slot[slot->index] = PCMCIA_IRQ_F;
+    /* Check for an interrupt handler function */
+    if (slot->irq_handler.handler) {
+        slot->irq_handler.handler(vector, count, slot->irq_handler.param);
+    }
+  Exit:
+    cyg_drv_interrupt_acknowledge(vector);
+    cyg_drv_interrupt_unmask(vector);
+} /* cf_irq_dsr */
+#endif /* CYGPKG_KERNEL */
+
+/*=========================================================================
+ * PCMCIA HELPER FUNCTIONS
+ *=======================================================================*/
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_memmap_init
+ *  DESCRIPTION
+ *      Initialize PCMCIA memory/IO address space.
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+_pcmcia_memmap_init(struct cf_slot * slot)
+{
+    unsigned int                ioStartAddr; /* io space start address. */
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+    unsigned int                offset = 0;
+
+    if (slot->index != 0) {
+        /* The starting addresses are only defined for the first slot */
+        return false;
+    }
+
+    /* PCMCIA_A_COMM_MEM */
+    slot->mem = (unsigned char *)(CYGPKG_DEVS_PCMCIA_MPC8XX_MEMORY_START + offset);
+    slot->mem_length = PCMCIA_MEM_COMMON_SZ;
+    offset += PCMCIA_MEM_COMMON_SZ;
+    pcmciaRegPtr->pir.slot[slot->index].comm.por = PCMCIA_POR_SLOT_A;
+    pcmciaRegPtr->pir.slot[slot->index].comm.pbr = (unsigned int)slot->mem;
+    pcmciaRegPtr->pir.slot[slot->index].comm.por |=
+        PCMCIA_POR_COMM_MEM |
+        PCMCIA_POR_PV |
+        PCMCIA_POR_PSHT(PCMCIA_DFLT_HOLD_TIME) |
+        PCMCIA_POR_PSST(PCMCIA_DFLT_SETUP_TIME) |
+        PCMCIA_POR_PSL(PCMCIA_DFLT_LEN_TIME) |
+        PCMCIA_MEM_COMMON_BSIZE;
+
+    /* PCMCIA_A_ATTR_MEM */
+    slot->attr = (unsigned char *)(CYGPKG_DEVS_PCMCIA_MPC8XX_MEMORY_START + offset);
+    slot->attr_length = PCMCIA_MEM_ATTR_SZ;
+    offset += PCMCIA_MEM_ATTR_SZ;
+    pcmciaRegPtr->pir.slot[slot->index].attr.por = PCMCIA_POR_SLOT_A;
+    pcmciaRegPtr->pir.slot[slot->index].attr.pbr = (unsigned int)slot->attr;
+    pcmciaRegPtr->pir.slot[slot->index].attr.por |=
+        PCMCIA_POR_ATTR_MEM |
+        PCMCIA_POR_PV |
+        PCMCIA_POR_PSHT(PCMCIA_DFLT_HOLD_TIME) |
+        PCMCIA_POR_PSST(PCMCIA_DFLT_SETUP_TIME) |
+        PCMCIA_POR_PSL(PCMCIA_DFLT_LEN_TIME) |
+        PCMCIA_MEM_ATTR_BSIZE;
+
+    /* PCMCIA_A_IO_SPACE */
+    slot->io = (unsigned char *)(CYGPKG_DEVS_PCMCIA_MPC8XX_MEMORY_START + offset);
+    slot->io_length = PCMCIA_MEM_IO_SZ;
+    offset += PCMCIA_MEM_IO_SZ;
+    pcmciaRegPtr->pir.slot[slot->index].io.por = PCMCIA_POR_SLOT_A;
+    pcmciaRegPtr->pir.slot[slot->index].io.pbr = (unsigned int)slot->io;
+    pcmciaRegPtr->pir.slot[slot->index].io.por |=
+        PCMCIA_POR_IO_SPACE |
+        PCMCIA_POR_PV |
+        PCMCIA_POR_PSHT(PCMCIA_DFLT_HOLD_TIME) |
+        PCMCIA_POR_PSST(PCMCIA_DFLT_SETUP_TIME) |
+        PCMCIA_POR_PSL(PCMCIA_DFLT_LEN_TIME) |
+        PCMCIA_MEM_IO_BSIZE;
+
+    /* Do some funny stuff with the IO space */
+    if ( ! _pcmcia_get_startioaddr(slot, &ioStartAddr) ) {
+        return false;
+    }
+    slot->io = (unsigned char *)(ioStartAddr + (unsigned int)slot->io);
+    return true;
+} /* _pcmcia_memmap_init */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_conf_baseaddr
+ *  DESCRIPTION
+ *      Find PCMCIA configuration base address from
+ *      Card Information Structure.
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *      confBaseAddrPtr         ; pointer to configuration base address.
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+_pcmcia_conf_baseaddr(struct cf_slot * slot, unsigned int * confBaseAddrPtr)
+{
+    unsigned char               tpccRasz; /* size of fields type */
+    unsigned short              byteCnt; /* remain address byte count */
+    /* local buffer to store tuple content */
+    unsigned char               tupleBuf[MAX_TUPLE_SZ];
+    unsigned char *             tupleBufPtr;
+
+    /* First, find the CISTPL_CONFIG tuple. */
+    tupleBufPtr = tupleBuf;
+    if ( ! _pcmcia_get_cis_tuple(slot, CF_CISTPL_CONFIG, tupleBuf) ) {
+        return 0;
+    }
+    tupleBufPtr = tupleBuf;
+    tupleBufPtr += 2;
+    tpccRasz = (*tupleBufPtr & TPCC_RASZ_MASK) + 1;
+    tpccRasz = (tpccRasz > 4) ? 4 : tpccRasz;
+    tupleBufPtr += 2;
+    /* Read confBaseAddr starting from tupleBufPtr */
+    *confBaseAddrPtr = 0;
+    byteCnt = tpccRasz;
+    while ( byteCnt-- ) {
+        *confBaseAddrPtr |= (unsigned int)(*tupleBufPtr++ << (8 * (tpccRasz - byteCnt - 1)));
+    }
+    return 1;
+} /* _pcmcia_conf_baseaddr */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_get_startioaddr
+ *  DESCRIPTION
+ *      Obtain start I/O address from PCMCIA card.
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *      startIoAddrPtr          ; pointer to start of I/O address block.
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+_pcmcia_get_startioaddr(struct cf_slot * slot, unsigned int * startIoAddrPtr)
+{
+    unsigned char               tmpCisByte;         /* temperary CIS byte */
+    unsigned char               byteCnt;            /* byte counter */
+    unsigned char               ioAddrSz;           /* I/O address size */
+    unsigned char               fsByte;             /* feature selection byte */
+    /* local buffer to store tuple content */
+    unsigned char               tupleBuf[MAX_TUPLE_SZ];
+    unsigned char *             tupleBufPtr;        /* ptr to tuple buffer pointer */
+    unsigned char               bitMask;
+    unsigned char               ioAddrLines;
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+
+    /*
+     * Since the tuple has been copied to local memory, the content of the
+     * the tuple is continuous.
+     */
+    tupleBufPtr = (unsigned char *)tupleBuf;
+    if ( ! _pcmcia_get_cis_tuple(slot, CF_CISTPL_CFTABLE_ENTRY, (unsigned char *)tupleBuf) ) {
+        return 0;
+    }
+    tupleBufPtr += 2;
+    /* Check to see if an interface configuration byte follows. */
+    if ( *tupleBufPtr++ & TPCE_IF_MASK ) {
+        tupleBufPtr++;
+    }
+    /* Get the feature selection byte */
+    fsByte = *tupleBufPtr;
+    /* Return error if I/O space description structure is not present. */
+    if ( !(fsByte & TPCE_FS_IO_MASK) ) {
+        return 0;
+    }
+    byteCnt = fsByte & TPCE_FS_PD_MASK;
+    /* Parsing the TPCE_FS_PD if it exists */
+    tupleBufPtr++;
+    while ( byteCnt-- ) {
+        tmpCisByte = *tupleBufPtr++;
+
+#if 0 /* only for debugging */
+        if ( byteCnt == 0) {
+            int                 vcc;
+
+            if ( tmpCisByte & TPCE_VC_NOM ) {
+                if ( *tupleBufPtr & 0x35 ) {
+                    /* 3V */
+                    vcc = 3;
+                }
+                else {
+                    /* 5V */
+                    vcc = 5;
+                }
+            }
+            else {
+                vcc = 5;
+            }
+        }
+#endif
+
+        for ( bitMask = 1 ; bitMask < 0x80; bitMask <<= 1 ) {
+            if ( tmpCisByte & bitMask ) {
+                if ( *tupleBufPtr++ & TPCE_FS_PD_EXT ) {
+                    tupleBufPtr++;
+                }
+            }
+        } /* for */
+    } /* while */
+
+    tmpCisByte = *tupleBufPtr;
+    /* Check to see if timing structure is present. */
+    if ( fsByte & TPCE_FS_TI_MASK ) {
+        tupleBufPtr++;
+        if ( (tmpCisByte & TPCE_TD_WAITSCALE_MASK )
+            != TPCE_TD_WAITSCALE_UNUSED ) {
+            tupleBufPtr++;
+        }
+        if ( (tmpCisByte & TPCE_TD_REBU_MASK )
+            != TPCE_TD_REBU_UNUSED ) {
+            tupleBufPtr++;
+        }
+        if ( (tmpCisByte & TPCE_TD_RESERVED_MASK )
+            != TPCE_TD_RESERVED_UNUSED ) {
+            tupleBufPtr++;
+        }
+        tmpCisByte = *tupleBufPtr;
+    }
+    /* Determine I/O bus size needed by card. */
+    if ( tmpCisByte & TPCE_IO_BUS16 ){
+        /*
+         * Card wants 16 bit I/O cycles, so set the PCMCIA interface
+         * to 16 bit I/O.
+         */
+        pcmciaRegPtr->pir.slot[slot->index].io.por |= PCMCIA_POR_PS16;
+    }
+    if ( !(tmpCisByte & TPCE_IO_RANGE ) ){
+        ioAddrLines = (tmpCisByte & IO_ADDR_LINES_MASK);
+        /* Make sure *startIoAddrPtr > 0x100 */
+        ioAddrLines = (ioAddrLines > 10)? ioAddrLines : 10;
+        /* I/O addr lines 27-31 are reserved. Some Agere (Orinoco,Lucent) cards
+           are using them nevertheless. Tests show the following to fix that. */
+        if ( ioAddrLines < 27) {
+            *startIoAddrPtr = 1 << ioAddrLines;
+        }
+        else {
+            *startIoAddrPtr = 0;
+        }
+        return 1;
+    }
+    /* Assuming 1 range, so one start I/O address for now. */
+    tupleBufPtr++;
+    /* Obtain length and size fields byte */
+    tmpCisByte = *tupleBufPtr;
+    ioAddrSz = (tmpCisByte & 0x30) >> 4;
+    if ( ioAddrSz == 0 ) {
+        return 0;
+    }
+    if (ioAddrSz == 3 ) {
+        ioAddrSz = 4;
+    }
+    byteCnt = ioAddrSz;
+    *startIoAddrPtr = 0;
+    tupleBufPtr++;
+    while ( byteCnt-- ) {
+        *startIoAddrPtr |= (unsigned int)*tupleBufPtr++ << (8 * (ioAddrSz - byteCnt -  1));
+    }
+    return 1;
+} /* _pcmcia_get_startioaddr */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_get_cis_tuple
+ *  DESCRIPTION
+ *      Find the specified tuple in the CIS of the PCMCIA channel
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *      tplCode                 ; tuple code
+ *      tupleBufPtr             ; pointer to tuple buffer
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+_pcmcia_get_cis_tuple(struct cf_slot * slot, unsigned char tplCode, unsigned char * tupleBufPtr)
+{
+    int                         offset;
+    int                         len;
+
+    offset = 0;
+    return cf_get_CIS(slot, tplCode, tupleBufPtr, &len, &offset);
+} /* _pcmcia_get_cis_tuple */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      pcmcia_poll_irq
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      slot                    ; pointer to pcmcia object
+ *  RETURNS
+ *      bool
+ *---------------------------------------------------------------
+ */
+bool
+pcmcia_poll_irq(struct cf_slot * slot)
+{
+    PcmciaRegisterT *           pcmciaRegPtr = (PcmciaRegisterT *)PPC_PCMCIA_BASE;
+
+    /* Test for falling edge on IRQ. */
+    if (pcmciaRegPtr->pscr.slot[slot->index] & PCMCIA_IRQ_F) {
+        pcmciaRegPtr->pscr.slot[slot->index] = PCMCIA_IRQ_F;
+        return 1;
+    }
+    return 0;
+} /* pcmcia_poll_irq */
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx_custom.c ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx_custom.c
--- ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx_custom.c    1969-12-31 18:00:00.000000000 -0600
+++ ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx_custom.c 2008-03-17 14:51:41.000000000 -0600
@@ -0,0 +1,153 @@
+//==========================================================================
+//
+//      PowerPC MPC8XX PCMCIA support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):       Shaun Louie
+// Contributors:    Shaun Louie
+// Date:            2008-03-17
+// Description:     Custom board support - controls PCMCIA VCC and VPP
+//                  switching matrix (e.g. LTC1472 or TPS2211).  Currently,
+//                  only Port C GPIO pins are supported.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <string.h>
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_arch.h>           // Register state info
+#include <cyg/hal/hal_intr.h>           // HAL interrupt macros
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/ppc8xx.h>
+#include <cyg/io/pcmcia.h>
+#include "pcmcia_mpc8xx.h"
+
+/* Macros to convert pin value to bit mask */
+#define PCMCIA_GPIO_PC_AVCC_A0      (0x8000 >> CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVCC_A0)
+#define PCMCIA_GPIO_PC_AVCC_A1      (0x8000 >> CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVCC_A1)
+#define PCMCIA_GPIO_PC_AVPP_A0      (0x8000 >> CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVPP_A0)
+#define PCMCIA_GPIO_PC_AVPP_A1      (0x8000 >> CYGPKG_DEVS_PCMCIA_MPC8XX_GPIO_PC_AVPP_A1)
+
+/* Bit mask of all the PCMCIA GPIO Port C pins */
+#define PCMCIA_GPIO_PC_MASK         (PCMCIA_GPIO_PC_AVCC_A0 | \
+                                     PCMCIA_GPIO_PC_AVCC_A1 | \
+                                     PCMCIA_GPIO_PC_AVPP_A0 | \
+                                     PCMCIA_GPIO_PC_AVPP_A1)
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_custom_init
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      none
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+void
+_pcmcia_custom_init(void)
+{
+    volatile EPPC *                 eppc = (volatile EPPC *)eppc_base();
+
+    /* Setup PPC ports as outputs. */
+    eppc->pio_pcpar &= ~PCMCIA_GPIO_PC_MASK;
+    eppc->pio_pcdir |= PCMCIA_GPIO_PC_MASK;
+    /* PCMCIA Power supply off. */
+    eppc->pio_pcdat |= PCMCIA_GPIO_PC_MASK;
+} /* _pcmcia_custom_init */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_custom_on
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      slot
+ *      vselect
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+void
+_pcmcia_custom_on(struct cf_slot *slot, unsigned int vselect)
+{
+    volatile EPPC *                 eppc = (volatile EPPC *)eppc_base();
+
+    vselect &= (PCMCIA_VOLTSEL_3V | PCMCIA_VOLTSEL_5V);
+    if (slot->index == 0) {
+        switch (vselect) {
+            case PCMCIA_VOLTSEL_3V :
+                eppc->pio_pcdat |= PCMCIA_GPIO_PC_AVCC_A1;
+                eppc->pio_pcdat &= ~PCMCIA_GPIO_PC_AVCC_A0;
+                break;
+
+            case PCMCIA_VOLTSEL_5V  :
+                eppc->pio_pcdat &= ~PCMCIA_GPIO_PC_AVCC_A1;
+                eppc->pio_pcdat |= PCMCIA_GPIO_PC_AVCC_A0;
+                break;
+
+            default:
+                _pcmcia_custom_off(slot);
+                break;
+        } /* switch */
+    }
+} /* _pcmcia_custom_on */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      _pcmcia_custom_off
+ *  DESCRIPTION
+ *
+ *  PARAMETERS
+ *      slot
+ *  RETURNS
+ *      void
+ *---------------------------------------------------------------
+ */
+void
+_pcmcia_custom_off(struct cf_slot * slot)
+{
+    volatile EPPC *                 eppc = (volatile EPPC *)eppc_base();
+
+    if (slot->index == 0) {
+        /* PCMCIA Power supply off. */
+        eppc->pio_pcdat |= PCMCIA_GPIO_PC_MASK;
+    }
+} /* _pcmcia_custom_off */
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.h ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.h
--- ecos.20080311/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.h   1969-12-31 18:00:00.000000000 -0600
+++ ecos.20080311.devs-pcmcia-mpc8xx/packages/devs/pcmcia/powerpc/mpc8xx/current/src/pcmcia_mpc8xx.h    2008-03-17 14:51:41.000000000 -0600
@@ -0,0 +1,312 @@
+//==========================================================================
+//
+//      PowerPC MPC8XX PCMCIA support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):       Shaun Louie
+// Contributors:    Shaun Louie
+// Date:            2008-03-17
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+/*===========================================================
+ * Dependencies
+ *=========================================================*/
+#include <pkgconf/hal.h> /* For IMMR base */
+#include <pkgconf/devs_pcmcia_mpc8xx.h>
+
+/* Binary to gray-code */
+#define binary2gray(b)                      ((b) ^ ((b) >> 1))
+
+/*===========================================================
+ * Definitions
+ *=========================================================*/
+/* Card Configuration and Status Register (CCSR) */
+#define PCMCIA_CCSR_IO_IS_8                 0x20  /*host can only make 8bit IO cycles. */
+#define PCMCIA_CCSR_AUDIO                   0x08  /*Pin BVD2 is used for audio data. */
+#define PCMCIA_CCSR_PWRDWN                  0x04  /*Request card to Power down. */
+
+/*===========================================================
+ * PORx register bits.
+ *=========================================================*/
+#define PCMCIA_POR_BSIZE(S)                 ((S) << 27) /* Bank size = (2 pwr S). */
+#define PCMCIA_POR_PSHT(HT)                 ((HT) << 16)  /* Strobe Hold time. */
+#define PCMCIA_POR_PSST(ST)                 ((ST) << 12)  /* Setup time. */
+#define PCMCIA_POR_PSL(L)                   ((L) << 7)    /* Strobe length. */
+#define PCMCIA_POR_PS8                      0x00000000    /* 8 bit port size. */
+#define PCMCIA_POR_PS16                     0x00000040    /* 16 bit port size. */
+#define PCMCIA_POR_COMM_MEM                 (0 << 3)
+#define PCMCIA_POR_ATTR_MEM                 (2 << 3)
+#define PCMCIA_POR_IO_SPACE                 (3 << 3)
+#define PCMCIA_POR_DMA_REGION               (4 << 3)
+#define PCMCIA_POR_SLOT_A                   0x00000000    /* This region accesses slot A. */
+#define PCMCIA_POR_SLOT_B                   0x00000004    /* This region accesses slot B. */
+#define PCMCIA_POR_WP                       0x00000002    /* Write protect. */
+#define PCMCIA_POR_PV                       0x00000001    /* Valid region. */
+
+/*
+ * We need these because the PPC has a weird way of setting a PCMCIA
+ * memory window size :-/.
+ */
+#define PCMCIA_POR_BSIZE_1K                 PCMCIA_POR_BSIZE(binary2gray(10))
+#define PCMCIA_POR_BSIZE_2K                 PCMCIA_POR_BSIZE(binary2gray(11))
+#define PCMCIA_POR_BSIZE_4K                 PCMCIA_POR_BSIZE(binary2gray(12))
+#define PCMCIA_POR_BSIZE_8K                 PCMCIA_POR_BSIZE(binary2gray(13))
+#define PCMCIA_POR_BSIZE_16K                PCMCIA_POR_BSIZE(binary2gray(14))
+#define PCMCIA_POR_BSIZE_32K                PCMCIA_POR_BSIZE(binary2gray(15))
+#define PCMCIA_POR_BSIZE_64K                PCMCIA_POR_BSIZE(binary2gray(16))
+#define PCMCIA_POR_BSIZE_128K               PCMCIA_POR_BSIZE(binary2gray(17))
+#define PCMCIA_POR_BSIZE_256K               PCMCIA_POR_BSIZE(binary2gray(18))
+#define PCMCIA_POR_BSIZE_512K               PCMCIA_POR_BSIZE(binary2gray(19))
+#define PCMCIA_POR_BSIZE_1M                 PCMCIA_POR_BSIZE(binary2gray(20))
+#define PCMCIA_POR_BSIZE_2M                 PCMCIA_POR_BSIZE(binary2gray(21))
+#define PCMCIA_POR_BSIZE_4M                 PCMCIA_POR_BSIZE(binary2gray(22))
+#define PCMCIA_POR_BSIZE_8M                 PCMCIA_POR_BSIZE(binary2gray(23))
+#define PCMCIA_POR_BSIZE_16M                PCMCIA_POR_BSIZE(binary2gray(24))
+#define PCMCIA_POR_BSIZE_32M                PCMCIA_POR_BSIZE(binary2gray(25))
+#define PCMCIA_POR_BSIZE_64M                PCMCIA_POR_BSIZE(binary2gray(26))
+
+/* PCMCIA_A_COMM_MEM */
+#ifdef CYGPKG_DEVS_PCMCIA_MPC8XX_COMMON_SZ_64M
+# define PCMCIA_MEM_COMMON_SZ               (64 * 1024 * 1024)
+# define PCMCIA_MEM_COMMON_BSIZE            PCMCIA_POR_BSIZE_64M
+#else
+# error "Unsupported commmon memory size"
+#endif
+
+/* PCMCIA_A_ATTR_MEM */
+#ifdef CYGPKG_DEVS_PCMCIA_MPC8XX_ATTR_SZ_64M
+# define PCMCIA_MEM_ATTR_SZ                 (64 * 1024 * 1024)
+# define PCMCIA_MEM_ATTR_BSIZE              PCMCIA_POR_BSIZE_64M
+#else
+# error "Unsupported attribute memory size"
+#endif
+
+/* PCMCIA_A_IO_SPACE */
+#ifdef CYGPKG_DEVS_PCMCIA_MPC8XX_IO_SZ_64M
+# define PCMCIA_MEM_IO_SZ                   (64 * 1024 * 1024)
+# define PCMCIA_MEM_IO_BSIZE                PCMCIA_POR_BSIZE_64M
+#else
+# error "Unsupported IO memory size"
+#endif
+
+/* Default PCMCIA timing (in bus-clocks). */
+#define PCMCIA_DFLT_SETUP_TIME              2
+#define PCMCIA_DFLT_LEN_TIME                5
+#define PCMCIA_DFLT_HOLD_TIME               2
+
+/*===========================================================
+ * PIPR, PSCR and PER register bits. (half)
+ *=========================================================*/
+#define PCMCIA_VS1                          0x8000
+#define PCMCIA_VS2                          0x4000
+#define PCMCIA_WP                           0x2000
+#define PCMCIA_CD2                          0x1000
+#define PCMCIA_CD1                          0x0800
+#define PCMCIA_BVD2                         0x0400
+#define PCMCIA_BVD1                         0x0200
+#define PCMCIA_RDY                          0x0100
+#define PCMCIA_IRQ                          0x0100
+/* PSCR and PER specific. */
+#define PCMCIA_IRQ_L                        0x0080  /* Low level on IRQ */
+#define PCMCIA_IRQ_H                        0x0040  /* High level on IRQ */
+#define PCMCIA_IRQ_R                        0x0020  /* Rising edge on IRQ */
+#define PCMCIA_IRQ_F                        0x0010  /* Falling edge on IRQ */
+
+/*
+ * Voltage select pin value table.
+ *-----+-----+-------------------------------
+ * VS1 | VS2 | Description
+ *-----+-----+-------------------------------
+ *  0  |  0  | X.XV, else 3.3V, else none
+ *  0  |  1  | 3.3V, else none
+ *  1  |  0  | X.XV, else none
+ *  1  |  1  | 5V, else none
+ *-----+-----+-------------------------------
+ */
+#define PCMCIA_VOLTSEL_3V                   (PCMCIA_VS2)
+#define PCMCIA_VOLTSEL_5V                   (PCMCIA_VS1 | PCMCIA_VS2)
+
+/*===========================================================
+ * PGCR-A and PGCR-B register bits
+ *=========================================================*/
+#define PCMCIA_PGCR_DREQ                    0x00008000
+#define PCMCIA_PGCR_OE                      0x00000080
+#define PCMCIA_PGCR_RESET                   0x00000040
+
+/*===========================================================
+ * Delay constants
+ *=========================================================*/
+#define PCMCIA_POWER_OFF_DELAY              1000000 /* 1s delay after power-off (discharge)*/
+#define PCMCIA_POWER_ON_DELAY               500000  /* 500ms delay after power-on.     */
+#define PCMCIA_HARD_RESET_PULSE             100000  /* 100ms PCMCIA Hard Reset pulse. */
+#define PCMCIA_HARD_RESET_DELAY             500000  /* 500ms delay after Hard Reset.  */
+#define PCMCIA_SOFT_RESET_PULSE             100000  /* 100ms PCMCIA Soft Reset pulse. */
+#define PCMCIA_SOFT_RESET_DELAY             500000  /* 500ms delay after Soft Reset.  */
+
+/*===========================================================
+ * Interrupts
+ *=========================================================*/
+/* Define the interrupt signal to use. */
+#define PCMCIA_SIU_INTR                     CYGNUM_HAL_INTERRUPT_SIU_LVL2
+#define PCMCIA_INTERRUPT                    2
+/* To be set in PGCRx as well.  PGCRA = IMMR + 0x0e0 */
+#define PCMCIA_PGCR_INTR_LVL(L)             (0x80000000 >> (L))
+
+/*===========================================================
+ * Card Information Structure Tuple Code
+ *=========================================================*/
+/* Maximium tuple size */
+#define MAX_TUPLE_SZ                        256
+
+/* configuration tuple size of fields byte masks */
+#define TPCC_RASZ_MASK                      0x03
+#define TPCC_RMSZ_MASK                      0x3C
+#define TPCC_RFSZ_MASK                      0xC0
+
+#define TPCE_IF_MASK                        0x80
+#define TPCE_FS_IO_MASK                     0x08
+#define TPCE_FS_PD_MASK                     0x03
+#define TPCE_FS_PD_EXT                      0x80
+#define TPCE_FS_TI_MASK                     0x04
+
+#define TPCE_TD_WAITSCALE_MASK              0x03
+#define TPCE_TD_WAITSCALE_UNUSED            0x03
+#define TPCE_TD_REBU_MASK                   0x1C
+#define TPCE_TD_REBU_UNUSED                 0x1C
+#define TPCE_TD_RESERVED_MASK               0xE0
+#define TPCE_TD_RESERVED_UNUSED             0xE0
+
+#define TPCE_IO_RANGE                       0x80
+#define TPCE_IO_BUS16                       0x40
+#define TPCE_IO_BUS8                        0x20
+#define IO_ADDR_LINES_MASK                  0x1F
+
+#define TPCE_VC_NOM                         0x01
+
+/*===========================================================
+ * PPC PCMCIA internal registers and bits.
+ *=========================================================*/
+#define PPC_PCMCIA_BASE                     (CYGARC_REG_IMM_BASE + 0x00000080)
+
+volatile typedef struct {
+    unsigned int        pbr;    /* PCMCIA interface base register */
+    unsigned int        por;    /* PCMCIA interface option register */
+} __attribute__ ((packed)) PBR_POR;
+
+volatile typedef struct {
+    unsigned int        pbr0;   /* PCMCIA interface base register0   */
+    unsigned int        por0;   /* PCMCIA interface option register0 */
+    unsigned int        pbr1;   /*               .                   */
+    unsigned int        por1;   /*               .                   */
+    unsigned int        pbr2;   /*               .                   */
+    unsigned int        por2;   /*               .                   */
+    unsigned int        pbr3;   /*               .                   */
+    unsigned int        por3;   /*               .                   */
+    unsigned int        pbr4;   /*               .                   */
+    unsigned int        por4;   /*               .                   */
+    unsigned int        pbr5;   /*               .                   */
+    unsigned int        por5;   /*               .                   */
+    unsigned int        pbr6;   /*               .                   */
+    unsigned int        por6;   /*               .                   */
+    unsigned int        pbr7;   /* PCMCIA interface base register7   */
+    unsigned int        por7;   /* PCMCIA interface option register7 */
+} __attribute__ ((packed)) ALL_PBR_POR;
+
+volatile typedef struct {
+    PBR_POR             comm;   /* PCMCIA PBR & POR registers for common memory. */
+    PBR_POR             attr;   /* PCMCIA PBR & POR registers for attrib memory. */
+    PBR_POR             io;     /* PCMCIA PBR & POR registers for I/O space. */
+    PBR_POR             spare;  /* Spare PCMCIA PBR & POR registers. */
+} __attribute__ ((packed)) SLOT_PBR_POR;
+
+volatile typedef struct {
+    union {
+      /* All PCMCIA PBR and POR registers by index */
+      PBR_POR           array[8];
+      /* PCMCIA PBR and POR registers per slot. */
+      SLOT_PBR_POR      slot[2];
+    } pir;
+    unsigned char       reserved1[32];
+    union {
+      struct {
+        unsigned int    A;  /* PCMCIA-A interface general control. */
+        unsigned int    B;  /* PCMCIA-B interface general control. */
+      } reg;
+      unsigned int      slot[2]; /* Selects register by slot index. */
+    } pgcr;
+    union {
+      unsigned int      reg;
+      unsigned short    slot[2]; /* Selects regsiter word by slot index. */
+    } pscr;
+    unsigned char       reserved2[4];
+    union {
+      unsigned int      reg;     /* PCMCIA interface input pins register. */
+      unsigned short    slot[2]; /* Selects register word by slot index. */
+    } pipr;
+    unsigned char       reserved3[4];
+    union {
+      unsigned int      reg;     /* PCMCIA interrupt enable register. */
+      unsigned short    slot[2]; /* Selects regstr word by slot index. */
+    } per;
+} __attribute__ ((packed)) PcmciaRegisterT;
+
+/*===========================================================
+ * Function Declarations
+ *=========================================================*/
+bool            _pcmcia_memmap_init(struct cf_slot *);
+bool            _pcmcia_conf_baseaddr(struct cf_slot *, unsigned int *);
+bool            _pcmcia_get_startioaddr(struct cf_slot *, unsigned int *);
+unsigned char   _pcmcia_card_detect(struct cf_slot *);
+bool            _pcmcia_get_cis_tuple(struct cf_slot *, unsigned char, unsigned char *);
+
+void            cf_hwr_init(struct cf_slot *);
+bool            cf_hwr_change_state(struct cf_slot *, int);
+void            cf_hwr_poll(struct cf_slot *);
+void            cf_hwr_clear_interrupt(struct cf_slot *);
+bool            cf_hwr_card_inserted(struct cf_slot *);
+
+bool            cf_hwr_reset_hard(struct cf_slot *);
+bool            cf_hwr_reset_soft(struct cf_slot *);
+
+/* Custom Hardware Setup */
+void            _pcmcia_custom_init(void);
+void            _pcmcia_custom_on(struct cf_slot *, unsigned int);
+void            _pcmcia_custom_off(struct cf_slot *);
diff -r -U 5 -N -x CVS -x '*~' -x '.#~' ecos.20080311/packages/ecos.db ecos.20080311.devs-pcmcia-mpc8xx/packages/ecos.db
--- ecos.20080311/packages/ecos.db  2008-01-06 08:19:30.000000000 -0600
+++ ecos.20080311.devs-pcmcia-mpc8xx/packages/ecos.db   2008-03-17 14:39:57.000000000 -0600
@@ -187,10 +187,19 @@
         description "
            This package contains hardware support for PCMCIA
            and Compact Flash devices on the Compaq iPAQ pocket PC."
 }

+package CYGPKG_DEVS_PCMCIA_MPC8XX {
+   alias           { "PowerPC MPC8XX PCMCIA support" pcmcia_mpc8xx}
+   directory       devs/pcmcia/powerpc/mpc8xx
+   script          pcmcia_mpc8xx.cdl
+   hardware
+   description     "This package contains hardware support for PCMCIA
+                    on the PowerPC MPC8XX"
+}
+
 package CYGPKG_IO_FLASH {
    alias       { "Generic FLASH memory support" flash }
    directory   io/flash
    script      io_flash.cdl
         description "

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]