From: Stefan E. <se...@us...> - 2004-02-10 00:40:06
|
Update of /cvsroot/blob/blob/src/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20308/src/lib Modified Files: pcmcia.c Makefile.am Added Files: pcmcia-pxa.c pcmcia-sa1111.c Log Message: PCMCIA CLEANUP Remove PCMCIA mess and do it like the ethernet driver stuff. Probably breaks SA1111 PCMCIA stuff, but I'm the only one who uses that anyway, and I'll fix. The SA11x0 stuff is still missing. --- NEW FILE: pcmcia-pxa.c --- /********************************************************************** * pcmcia-pxa.c - pxa pcmcia functions * * (C) by Stefan Eletzhofer <ste...@el...> * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/types.h> #include <blob/errno.h> #include <blob/util.h> #include <blob/command.h> #include <blob/time.h> #include <blob/serial.h> #include <blob/arch.h> #include <blob/pcmcia.h> //#include <blob/pcmcia-pxa.h> /********************************************************************** * defines */ #ifdef DEBUG # define _DBG( x, fmt, args... ) do { if ( dbg>=x ) printf( "%s:" fmt "\n", __FUNCTION__, ## args ) }while(0); # define _DBGERR( x, code ) do { if ( dbg>=x ) printf( "%s(%d): ERROR %d.\n", __FUNCTION__, __LINE__, code ); ret = code; goto DONE; }while(0); #else # define _DBG( x, fmt, args... ) do { } while(0); # define _DBGERR( x, code ) do { ret = code; goto DONE; } while(0); #endif /********************************************************************** * globals */ /********************************************************************** * module globals */ static char *version = "$Id: pcmcia-pxa.c,v 1.1 2004/02/09 19:25:12 seletz Exp $"; #ifdef DEBUG static int dbg = 1; #else static int dbg = 0; #endif static struct pcmcia_sock pxa_sockets[2] = { { .nr = 0, .state = 0, .vcc = 0, .vpp = 0, .io_base = _PCMCIA0IO, .attr_base = _PCMCIA0Attr, .mem_base = _PCMCIA0Mem, }, { .nr = 1, .state = 0, .vcc = 0, .vpp = 0, .io_base = _PCMCIA1IO, .attr_base = _PCMCIA1Attr, .mem_base = _PCMCIA1Mem, } }; /********************************************************************** * statics */ /********************************************************************* * pxa_gpio_mode * @gpio_mode: desc * * Set GPIO alternate functions * * FIXME this function should'nt be static */ static void pxa_gpio_mode(int gpio_mode) { int gpio = gpio_mode & GPIO_MD_MASK_NR; int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; int gafr; if (gpio_mode & GPIO_MD_MASK_DIR) GPDR(gpio) |= GPIO_bit(gpio); else GPDR(gpio) &= ~GPIO_bit(gpio); gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); } /********************************************************************* * pcmcia_pxa_init - short desc * @void: desc * * Long desc */ int pcmcia_pxa_init( void ) { int ret = 0; /* setup GPIO */ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | GPIO_bit(GPIO53_nPCE_2); /* setup AFR */ pxa_gpio_mode(GPIO48_nPOE_MD); pxa_gpio_mode(GPIO49_nPWE_MD); pxa_gpio_mode(GPIO50_nPIOR_MD); pxa_gpio_mode(GPIO51_nPIOW_MD); pxa_gpio_mode(GPIO52_nPCE_1_MD); pxa_gpio_mode(GPIO53_nPCE_2_MD); pxa_gpio_mode(GPIO54_pSKTSEL_MD); /* REVISIT: s/b dependent on num sockets */ pxa_gpio_mode(GPIO55_nPREG_MD); pxa_gpio_mode(GPIO56_nPWAIT_MD); pxa_gpio_mode(GPIO57_nIOIS16_MD); DONE: return ret; } /********************************************************************** * exported */ pcmcia_driver_t pxa_pcmcia_driver = { .name = "PXA PCMCIA", .first = 0, .nr = 2, .sock = pxa_sockets, .init = pcmcia_pxa_init, .power = NULL, .sock_detect = NULL, .sock_enable = NULL, .sock_disable = NULL, .sock_reset = NULL, .sock_status_dump= NULL, }; /* vim: set ts=8 sw=8 tw=75: */ --- NEW FILE: pcmcia-sa1111.c --- /********************************************************************** * pcmcia-sa1111.c - sa1111 pcmcia functions * * (C) by Stefan Eletzhofer <ste...@el...> * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/types.h> #include <blob/errno.h> #include <blob/util.h> #include <blob/command.h> #include <blob/time.h> #include <blob/serial.h> #include <blob/arch.h> #include <blob/pcmcia.h> #include <blob/pcmcia-sa11x0.h> #ifdef SA1111_BASE #include <blob/proc/sa1111.h> #endif /********************************************************************** * defines */ #ifdef DEBUG # define _DBG( x, fmt, args... ) do { if ( dbg>=x ) printf( "%s:" fmt "\n", __FUNCTION__, ## args ) }while(0); # define _DBGERR( x, code ) do { if ( dbg>=x ) printf( "%s(%d): ERROR %d.\n", __FUNCTION__, __LINE__, code ); ret = code; goto DONE; }while(0); #else # define _DBG( x, fmt, args... ) do { } while(0); # define _DBGERR( x, code ) do { ret = code; goto DONE; } while(0); #endif /********************************************************************** * globals */ /********************************************************************** * module globals */ static char *version = "$Id: pcmcia-sa1111.c,v 1.1 2004/02/09 19:25:12 seletz Exp $"; #ifdef DEBUG static int dbg = 1; #else static int dbg = 0; #endif static struct pcmcia_sock sa1111_sockets[2] = { { .nr = 0, .state = 0, .vcc = 0, .vpp = 0, .io_base = PCMCIA_S0_IO_BASE, .attr_base = PCMCIA_S0_ATTR_BASE, .mem_base = PCMCIA_S0_MEM_BASE, }, { .nr = 1, .state = 0, .vcc = 0, .vpp = 0, .io_base = PCMCIA_S1_IO_BASE, .attr_base = PCMCIA_S1_ATTR_BASE, .mem_base = PCMCIA_S1_MEM_BASE, } }; /********************************************************************** * statics */ /********************************************************************* * pcmcia_sa1111_init - short desc * @void: desc * * Long desc */ int pcmcia_sa1111_init( void ) { int ret = 0; DONE: return ret; } /********************************************************************* * pcmcia_sa1111_voltage_set - set socket voltage * @sock: the socket * @vcc: voltage * @vpp: voltage * * This function should set socket voltage for <sock>. */ int pcmcia_sa1111_voltage_set( struct pcmcia_sock *sock, int vcc, int vpp ) { int ret = 0; if ( !sock ) _DBGERR( dbg, -EINVAL ); DONE: return ret; } /********************************************************************* * pcmcia_sa1111_sock_detect - detect socket * @sock: desc * * setect if a card is inserted in socket <sock>. * -1 error, 0 no card, 1 card in. */ int pcmcia_sa1111_sock_detect( struct pcmcia_sock *sock ) { int ret = 0; int detect = 0; unsigned int flags = PCSR; if ( !sock ) _DBGERR( dbg, -EINVAL ); switch ( sock->nr ) { case 0: detect = (flags & PCSR_S0_DETECT) == 0; break; case 1: detect = (flags & PCSR_S1_DETECT) == 0; break; default: detect = -1; break; } ret = detect; DONE: return ret; } /********************************************************************* * pcmcia_sa1111_sock_enable - short desc * @sock: desc * * Enable socket */ int pcmcia_sa1111_sock_enable( struct pcmcia_sock *sock ) { int ret = 0; if ( !sock ) _DBGERR( dbg, -EINVAL ); switch ( sock->nr ) { case 0: PCCR = (PCCR & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN; break; case 1: PCCR = (PCCR & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN; break; default: ret = -1; break; } DONE: return ret; } /********************************************************************* * pcmcia_sa1111_sock_disable - short desc * @sock: desc * * Long desc */ int pcmcia_sa1111_sock_disable( struct pcmcia_sock *sock ) { int ret = 0; if ( !sock ) _DBGERR( dbg, -EINVAL ); switch ( sock->nr ) { case 0: PCCR = PCCR | PCCR_S0_PSE; break; case 1: PCCR = PCCR | PCCR_S1_PSE; break; default: ret = -1; break; } DONE: return ret; } /********************************************************************* * pcmcia_sa1111_sock_reset - short desc * @sock: desc * * Long desc */ int pcmcia_sa1111_sock_reset( struct pcmcia_sock *sock ) { int ret = 0; if ( !sock ) _DBGERR( dbg, -EINVAL ); switch ( sock->nr ) { case 0: PCCR |= PCCR_S0_RST; msleep(20); PCCR &= ~PCCR_S0_RST; msleep(20); break; case 1: PCCR |= PCCR_S1_RST; msleep(20); PCCR &= ~PCCR_S1_RST; msleep(20); break; default: ret = -1; break; } DONE: return ret; } /********************************************************************* * pcmcia_sa1111_sock_status_dump * @sock: desc */ int pcmcia_sa1111_sock_status_dump( struct pcmcia_sock *sock ) { int ret = 0; int status = PCSR; if ( !sock ) _DBGERR( dbg, -EINVAL ); switch ( sock->nr ) { case 0: printf("s0: "); if (status & PCSR_S0_READY) printf("ready "); else printf(" "); if (status & PCSR_S0_DETECT) printf("detect "); else printf(" "); if (status & PCSR_S0_VS1) printf("vs1 "); else printf(" "); if (status & PCSR_S0_VS2) printf("vs2 "); else printf(" "); if (status & PCSR_S0_WP) printf("wp "); else printf(" "); if (status & PCSR_S0_BVD1) printf("bvd1 "); else printf(" "); if (status & PCSR_S0_BVD2) printf("bvd2 "); else printf(" "); printf( "\n" ); break; case 1: printf("s1: "); if (status & PCSR_S1_READY) printf("ready "); else printf(" "); if (status & PCSR_S1_DETECT) printf("detect "); else printf(" "); if (status & PCSR_S1_VS1) printf("vs1 "); else printf(" "); if (status & PCSR_S1_VS2) printf("vs2 "); else printf(" "); if (status & PCSR_S1_WP) printf("wp "); else printf(" "); if (status & PCSR_S1_BVD1) printf("bvd1 "); else printf(" "); if (status & PCSR_S1_BVD2) printf("bvd2 "); else printf(" "); printf( "\n" ); break; default: ret = -1; break; } DONE: return ret; } /********************************************************************** * exported */ pcmcia_driver_t sa1111_pcmcia_driver = { .name = "SA1111 PCMCIA", .first = 0, .nr = 2, .sock = sa1111_sockets, .init = pcmcia_sa1111_init, .power = pcmcia_sa1111_voltage_set, .sock_detect = pcmcia_sa1111_sock_detect, .sock_enable = pcmcia_sa1111_sock_enable, .sock_disable = pcmcia_sa1111_sock_disable, .sock_reset = pcmcia_sa1111_sock_reset, .sock_status_dump= pcmcia_sa1111_sock_status_dump, }; /* vim: set ts=8 sw=8 tw=75: */ Index: pcmcia.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/pcmcia.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- pcmcia.c 20 Aug 2003 23:12:22 -0000 1.8 +++ pcmcia.c 9 Feb 2004 19:25:12 -0000 1.9 @@ -5,7 +5,7 @@ * work from Brad Parker. * * Copyright (C) 2001, Brad Parker (br...@he...) - * Copyright (C) 2002, Stefan Eletzhofer <ste...@el...> + * Copyright (C) 2002-4, Stefan Eletzhofer <ste...@el...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,70 +41,30 @@ #include <blob/arch.h> #include <blob/pcmcia.h> -#ifdef SA1111_BASE -#include <blob/proc/sa1111.h> -#endif - /********************************************************************** * Defines / Makros */ -#define WEAK_SYM __attribute__ (( weak )) - #define MEMb(adr) (*((u8 *)(adr))) #define PCMCIA_DEBUG 1 #ifdef PCMCIA_DEBUG -# define DBG( x, args... ) if ( pcmcia_dbg>x ) printf( args ); +# define _DBG( x, fmt, args... ) do { if ( dbg>=x ) printf( "%s:" fmt "\n", __FUNCTION__, ## args ); }while(0) +# define _DBGERR( x, code ) do { if ( dbg>=x ) printf( "%s(%d): ERROR %d.\n", __FUNCTION__, __LINE__, code ); ret = code; goto DONE; } while(0) #else -# define DBG( x, args... ) +# define _DBG( x, fmt, args... ) do { } while(0) +# define _DBGERR( x, code ) do { ret = code; goto DONE; } while(0) #endif /********************************************************************** - * types - */ -typedef struct { - u16 status; - int vcc; - int vpp; - u32 attr_base; - u32 base; - volatile u8 *ident; - volatile u8 *feature_p[PCMCIA_MAX_FEATURES]; - int n_features; - u16 config_base; -} pcmcia_slot_t; - -/********************************************************************** - * program globals - */ - -pcmcia_slot_t pcmcia_slots[ PCMCIA_MAX_SLOTS ] = { - { - status: 0, - vcc: 0, - vpp: 0, - attr_base: PCMCIA_S0_ATTR_BASE, - base: PCMCIA_S0_BASE, - },{ - status: 0, - vcc: 0, - vpp: 0, - attr_base: PCMCIA_S1_ATTR_BASE, - base: PCMCIA_S1_BASE, - }, -}; - - -/********************************************************************** * module globals */ #ident "$Id$" #ifdef PCMCIA_DEBUG -static int pcmcia_dbg = 1; +static int dbg = 1; #else -static int pcmcia_dbg = 0; +static int dbg = 0; #endif /********************************************************************** @@ -112,185 +72,114 @@ */ static int pcmcia_print_fixed(volatile u8 *p); static int pcmcia_print_funcid(int func); +static int pcmcia_identify( volatile unsigned char *p ); +static int pcmcia_cis_parse( struct pcmcia_sock *sock ); /********************************************************************** - * exported functions + * static functions */ -void pcmcia_dbg_set( int level ) -{ - pcmcia_dbg = level; -} - -/* do whatever is needed to get pcmcia initialized */ -int WEAK_SYM pcmcia_init() -{ - return 0; -} - -/* set pcmcia slot voltage levels */ -int WEAK_SYM pcmcia_voltage_set( int slot, int vcc, int vpp ) -{ - return 0; -} - -/* detect slot */ -int WEAK_SYM pcmcia_slot_detect( int slot ) +/* print function id strings */ +static int pcmcia_print_funcid(int func) { - int detect = 0; -#ifdef SA1111_BASE - unsigned int flags = PCSR; - - switch ( slot ) { - case 0: - detect = (flags & PCSR_S0_DETECT) == 0; + printf("\t "); + switch (func) { + case CISTPL_FUNCID_MULTI: + printf("Multi-Function"); break; - case 1: - detect = (flags & PCSR_S1_DETECT) == 0; + case CISTPL_FUNCID_MEMORY: + printf("Memory"); break; - default: - detect = -1; - goto DONE; + case CISTPL_FUNCID_SERIAL: + printf("Serial Port"); break; - } - - if ( detect ) { - pcmcia_slots[slot].status |= PCMCIA_SS_DETECT; - } else { - pcmcia_slots[slot].status &= ~PCMCIA_SS_DETECT; - } - - DBG( 1, "%s: slot %d status: %x\n", __FUNCTION__, slot, pcmcia_slots[slot].status ); -DONE: -#else -#warning "FIXME: non sa1111 systems not yet supported" -#endif - return detect; -} - -/* enable slot */ -int WEAK_SYM pcmcia_slot_enable( int slot ) -{ - int ret = 0; - -#ifdef SA1111_BASE - switch ( slot ) { - case 0: - PCCR = (PCCR & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN; + case CISTPL_FUNCID_PARALLEL: + printf("Parallel Port"); break; - case 1: - PCCR = (PCCR & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN; + case CISTPL_FUNCID_FIXED: + printf("Fixed Disk"); + break; + case CISTPL_FUNCID_VIDEO: + printf("Video Adapter"); + break; + case CISTPL_FUNCID_NETWORK: + printf("Network Adapter"); + break; + case CISTPL_FUNCID_AIMS: + printf("AIMS Card"); + break; + case CISTPL_FUNCID_SCSI: + printf("SCSI Adapter"); break; default: - ret = -1; - goto DONE; + printf("Unknown"); break; } + printf(" Card\n"); - pcmcia_slots[slot].status |= PCMCIA_SS_ENABLED; - - DBG( 1, "%s: slot %d status: %x\n", __FUNCTION__, slot, pcmcia_slots[slot].status ); -DONE: -#else -#warning "FIXME: non sa1111 systems not yet supported" -#endif - return ret; + return 0; } -/* disable slot */ -int WEAK_SYM pcmcia_slot_disable( int slot ) +/* print info for FIXED_DISK function type card */ +static int pcmcia_print_fixed(volatile u8 *p) { - int ret = 0; + if (p == NULL) + return -1; -#ifdef SA1111_BASE - switch ( slot ) { - case 0: - PCCR = PCCR | PCCR_S0_PSE; - break; - case 1: - PCCR = PCCR | PCCR_S1_PSE; - break; - default: - ret = -1; - goto DONE; + printf("\t "); + + switch (*p) { + case CISTPL_FUNCE_IDE_IFACE: + { u8 iface = *(p+2); + + printf((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown"); + printf(" interface "); break; } + case CISTPL_FUNCE_IDE_MASTER: + case CISTPL_FUNCE_IDE_SLAVE: + { u8 f1 = *(p+2); + u8 f2 = *(p+4); - pcmcia_slots[slot].status &= ~PCMCIA_SS_ENABLED; + printf((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]"); - DBG( 1, "%s: slot %d status: %x\n", __FUNCTION__, slot, pcmcia_slots[slot].status ); -DONE: -#else -#warning "FIXME: non sa1111 systems not yet supported" -#endif - return ret; -} + if (f1 & CISTPL_IDE_UNIQUE) + printf(" [unique]"); -/* reset pcmcia slot */ -int WEAK_SYM pcmcia_slot_reset(int slot) -{ - int ret = 0; + printf((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]"); -#ifdef SA1111_BASE - switch ( slot ) { - case 0: - PCCR |= PCCR_S0_RST; - msleep(20); - PCCR &= ~PCCR_S0_RST; - msleep(20); - break; - case 1: - PCCR |= PCCR_S1_RST; - msleep(20); - PCCR &= ~PCCR_S1_RST; - msleep(20); - break; - default: - ret = -1; - break; - } + if (f2 & CISTPL_IDE_HAS_SLEEP) + printf(" [sleep]"); - DBG( 1, "%s: slot %d reset\n", __FUNCTION__, slot ); -#else -#warning "FIXME: non sa1111 systems not yet supported" -#endif - return ret; -} + if (f2 & CISTPL_IDE_HAS_STANDBY) + printf(" [standby]"); -/* dump slot HW line stati */ -int pcmcia_dump_stati( void ) -{ -#ifdef SA1111_BASE - int status = PCSR; + if (f2 & CISTPL_IDE_HAS_IDLE) + printf(" [idle]"); - printf("s0: "); - if (status & PCSR_S0_READY) printf("ready "); else printf(" "); - if (status & PCSR_S0_DETECT) printf("detect "); else printf(" "); - if (status & PCSR_S0_VS1) printf("vs1 "); else printf(" "); - if (status & PCSR_S0_VS2) printf("vs2 "); else printf(" "); - if (status & PCSR_S0_WP) printf("wp "); else printf(" "); - if (status & PCSR_S0_BVD1) printf("bvd1 "); else printf(" "); - if (status & PCSR_S0_BVD2) printf("bvd2 "); else printf(" "); - printf("; "); + if (f2 & CISTPL_IDE_LOW_POWER) + printf(" [low power]"); - printf("s1: "); - if (status & PCSR_S1_READY) printf("ready "); else printf(" "); - if (status & PCSR_S1_DETECT) printf("detect "); else printf(" "); - if (status & PCSR_S1_VS1) printf("vs1 "); else printf(" "); - if (status & PCSR_S1_VS2) printf("vs2 "); else printf(" "); - if (status & PCSR_S1_WP) printf("wp "); else printf(" "); - if (status & PCSR_S1_BVD1) printf("bvd1 "); else printf(" "); - if (status & PCSR_S1_BVD2) printf("bvd2 "); else printf(" "); + if (f2 & CISTPL_IDE_REG_INHIBIT) + printf(" [reg inhibit]"); + + if (f2 & CISTPL_IDE_HAS_INDEX) + printf(" [index]"); + + if (f2 & CISTPL_IDE_IOIS16) + printf(" [IOis16]"); + + break; + } + } printf("\n"); -#else -#warning "FIXME: non sa1111 systems not yet supported" -#endif return 0; } + /* identify pcmcia card */ -int pcmcia_identify( volatile unsigned char *p ) +static int pcmcia_identify( volatile unsigned char *p ) { unsigned char id_str[PCMCIA_MAX_IDENT_CHARS]; unsigned char data; @@ -326,53 +215,36 @@ else break; } - DBG( 1, "%s: id_str='%s'\n", __FUNCTION__, id_str); + _DBG( 1, "%s: id_str='%s'\n", __FUNCTION__, id_str); return (1); /* don't know */ } -/* parse cis tuples of card in slot <slot> */ -int pcmcia_cis_parse( int slot ) +/* parse cis tuples of card in sock <sock> */ +static int pcmcia_cis_parse( struct pcmcia_sock *sock ) { - int ret = 0; - void *cfg_mem_addr = NULL; - volatile u8 *ident = NULL; + int ret = 0; + void *cfg_mem_addr = NULL; volatile u8 *p = NULL; volatile u8 *start = NULL; - int n_features = 0; - u8 func_id = ~0; - u8 len = 0; - u8 code = 0; - u16 config_base = 0; - int found = 0; - int i = 0; + int n_features = 0; + u8 func_id = ~0; + u8 len = 0; + u8 code = 0; + u16 config_base = 0; + int found = 0; + int i = 0; volatile u8 **feature_p; - /* sanity check */ - if ( slot < 0 ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; - } - if ( slot > PCMCIA_MAX_SLOTS ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; - } - - if ( !( pcmcia_slots[slot].status & PCMCIA_SS_ENABLED ) || - !( pcmcia_slots[slot].status & PCMCIA_SS_DETECT )) { - printf( "pcmcia: slot %d not detected and enabled\n", slot ); - ret = -1; - goto DONE; + if ( !( sock->state & PCMCIA_SS_ENABLED ) || !( sock->state & PCMCIA_SS_DETECT )) { + _DBG( 1, "pcmcia: sock %d not detected and enabled\n", sock ); + _DBGERR( dbg, -1 ); } - cfg_mem_addr = (void *)pcmcia_slots[slot].attr_base; - feature_p = pcmcia_slots[slot].feature_p; - ident = pcmcia_slots[slot].ident; - + cfg_mem_addr = (void *)sock->attr_base; + feature_p = sock->feature_p; - DBG( 1, "%s: PCMCIA MEM: %p\n", __FUNCTION__, cfg_mem_addr); + _DBG( 1, "%s: PCMCIA MEM: %p\n", __FUNCTION__, cfg_mem_addr); start = p = (volatile u8 *)cfg_mem_addr; @@ -386,7 +258,7 @@ len = *p; p += 2; #if PCMCIA_DEBUG - if (pcmcia_dbg > 10) { + if (dbg > 10) { volatile u8 *q = p; printf("\nTuple code %2x length %d\n\tData:", code, len); @@ -400,12 +272,12 @@ switch (code) { case CISTPL_VERS_1: - ident = p + 4; - DBG( 1, "%s: ident=%p\n", __FUNCTION__, ident ); + sock->ident = p + 4; + _DBG( 1, "%s: ident=%p\n", __FUNCTION__, sock->ident ); break; case CISTPL_FUNCID: func_id = *p; - DBG( 1, "%s: func_id=%d\n", __FUNCTION__, func_id ); + _DBG( 1, "%s: func_id=%d\n", __FUNCTION__, func_id ); break; case CISTPL_FUNCE: if (n_features < PCMCIA_MAX_FEATURES) @@ -413,15 +285,15 @@ break; case CISTPL_CONFIG: config_base = (*(p+6) << 8) + (*(p+4)); - pcmcia_slots[slot].config_base = config_base; - DBG( 1, "%s: config_base=0x%04x\n", __FUNCTION__, config_base ); + sock->config_base = config_base; + _DBG( 1, "%s: config_base=0x%04x\n", __FUNCTION__, config_base ); default: break; } p += 2 * len; } - found = pcmcia_identify( ident ); + found = pcmcia_identify( sock->ident ); if (func_id != ((u8)~0)) { pcmcia_print_funcid(func_id); @@ -441,249 +313,352 @@ return ret; } -int pcmcia_slot_address_get( int slot, u32 *base, u32 *attr ) +/********************************************************************** + * exported functions + */ + +pcmcia_driver_t *pcmcia_driver = NULL; + +void pcmcia_dbg_set( int level ) +{ + dbg = level; +} + +/********************************************************************* + * pcmcia_init - init pcmcia subsystem + * + * Initializes lowlevel driver. Each detected card is reset and identified. + */ +int pcmcia_init( void ) { int ret = 0; + int nr, start, end; + int detected = 0; + struct pcmcia_sock *sockets; - /* sanity check */ - if ( slot < 0 ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); + + /* init subsystem */ + if ( pcmcia_driver->init ) { + ret = pcmcia_driver->init(); + if ( ret ) _DBGERR( dbg, ret ); } - if ( slot > PCMCIA_MAX_SLOTS ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; + + sockets = pcmcia_driver->sock; + + /* for each sock starting with first */ + start = pcmcia_driver->first; + end = start + pcmcia_driver->nr; + for ( nr=start; nr<end; nr++ ) { + struct pcmcia_sock *sock = sockets + nr; + + /* detect */ + ret = pcmcia_sock_detect( sock ); + if ( ret <= 0 ) continue; + _DBG( 1, "detected socket %d", nr ); + + /* enable */ + ret = pcmcia_sock_enable( sock ); + if ( ret ) continue; + _DBG( 1, "enabled socket %d", nr ); + + /* reset */ + ret = pcmcia_sock_reset( sock ); + if ( ret ) _DBGERR( dbg, ret ); + _DBG( 1, "reset socket %d", nr ); + + /* identify */ + ret = pcmcia_cis_parse( sock ); + if ( ret ) _DBGERR( dbg, ret ); + detected ++; } - if ( !( pcmcia_slots[slot].status & PCMCIA_SS_ENABLED ) || - !( pcmcia_slots[slot].status & PCMCIA_SS_DETECT )) { - printf( "pcmcia: slot %d not detected and enabled\n", slot ); - ret = -1; - goto DONE; + ret = detected; +DONE: + return ret; } - DBG( 1, "%s: base=%p\n", __FUNCTION__, (void *)pcmcia_slots[slot].base); - DBG( 1, "%s: attr_base=%p\n", __FUNCTION__, (void *)pcmcia_slots[slot].attr_base); +/********************************************************************* + * pcmcia_sock_dump_status - dump socket status + * @nr: desc + */ +int pcmcia_sock_dump_status( nr ) +{ + int ret = 0; + struct pcmcia_sock *sock = NULL; - if ( base ) *base = pcmcia_slots[slot].base; - if ( attr ) *attr = pcmcia_slots[slot].attr_base; + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); + if ( !PCMCIA_SOCK_NR_VALID( nr ) ) _DBGERR( dbg, -EINVAL ); - ret = 0; + ret = pcmcia_sock_get( nr, &sock ); + if ( ret ) _DBGERR( dbg, ret ); + + ret = pcmcia_driver->sock_status_dump( sock ); DONE: return ret; } -int pcmcia_slot_cfg_reg_get( int slot, u16 *cfg_base ) +/********************************************************************* + * pcmcia_sock_reset - reset socket + * @sock: desc + */ +int pcmcia_sock_reset( struct pcmcia_sock *sock ) { int ret = 0; - /* sanity check */ - if ( slot < 0 ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; + if ( !sock ) _DBGERR( dbg, -EINVAL ); + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); + + if ( pcmcia_driver->sock_reset ) { + ret = pcmcia_driver->sock_reset( sock ); + _DBG( 1, "sock_reset() = %d", ret ); } - if ( slot > PCMCIA_MAX_SLOTS ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; +DONE: + return ret; } - if ( !( pcmcia_slots[slot].status & PCMCIA_SS_ENABLED ) || - !( pcmcia_slots[slot].status & PCMCIA_SS_DETECT )) { - printf( "pcmcia: slot %d not detected and enabled\n", slot ); - ret = -1; - goto DONE; - } +/********************************************************************* + * pcmcia_sock_detect - detect socket + * @sock: desc + */ +int pcmcia_sock_detect( struct pcmcia_sock *sock ) +{ + int ret = 1; - DBG( 1, "%s: cfg_base=0x%03x\n", __FUNCTION__, pcmcia_slots[slot].config_base); + if ( !sock ) _DBGERR( dbg, -EINVAL ); + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); - if ( cfg_base ) *cfg_base = pcmcia_slots[slot].config_base; + if ( pcmcia_driver->sock_detect ) { + ret = pcmcia_driver->sock_detect( sock ); + if ( ret < 0 ) _DBGERR( dbg, ret ); + } - ret = 0; + _DBG( 1, "detect = %d", ret ); + + if ( ret ) { + sock->state |= PCMCIA_SS_DETECT; + } else { + sock->state &= ~PCMCIA_SS_DETECT; + } DONE: return ret; } -int pcmcia_slot_attr_read( int slot, u16 offset, u8 *value ) +/********************************************************************* + * pcmcia_sock_enable - enable socket + * @sock: desc + */ +int pcmcia_sock_enable( struct pcmcia_sock *sock ) { int ret = 0; - /* sanity check */ - if ( slot < 0 ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; - } - if ( slot > PCMCIA_MAX_SLOTS ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; + if ( !sock ) _DBGERR( dbg, -EINVAL ); + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); + + if ( pcmcia_driver->sock_enable ) { + ret = pcmcia_driver->sock_enable( sock ); + if ( ret ) _DBGERR( dbg, ret ); } - if ( !value ) { - printf( "pcmcia: value==NULL\n" ); - ret = -1; - goto DONE; + + sock->state |= PCMCIA_SS_ENABLED; +DONE: + return ret; } - if ( !( pcmcia_slots[slot].status & PCMCIA_SS_ENABLED ) || - !( pcmcia_slots[slot].status & PCMCIA_SS_DETECT )) { - printf( "pcmcia: slot %d not detected and enabled\n", slot ); - ret = -1; - goto DONE; +/********************************************************************* + * pcmcia_sock_disable - disable socket + * @sock: desc + */ +int pcmcia_sock_disable( struct pcmcia_sock *sock ) +{ + int ret = 0; + + if ( !sock ) _DBGERR( dbg, -EINVAL ); + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); + + if ( pcmcia_driver->sock_disable ) { + ret = pcmcia_driver->sock_disable( sock ); + if ( ret ) _DBGERR( dbg, ret ); } - *value = MEMb( - pcmcia_slots[slot].attr_base + - pcmcia_slots[slot].config_base + - offset - ); + sock->state &= ~PCMCIA_SS_ENABLED; +DONE: + return ret; +} - DBG( 1, "%s: ATTR_REG(0x%02x) => 0x%02x\n", __FUNCTION__, - offset, *value ); +/********************************************************************* + * pcmcia_sock_get - short desc + * @nr: desc + * @sock: desc + * + * Long desc + */ +int pcmcia_sock_get( int nr, struct pcmcia_sock **sock ) +{ + int ret = 0; - ret = 0; + if ( !pcmcia_driver ) _DBGERR( dbg, -EINVAL ); + if ( !PCMCIA_SOCK_NR_VALID( nr ) ) _DBGERR( dbg, -EINVAL ); + + if ( sock ) + *sock = pcmcia_driver->sock + nr; DONE: return ret; } -int pcmcia_slot_attr_write( int slot, u16 offset, u8 value ) +/****************************************************************************** + * ATTRIBUTE SPACE ACCESS + */ +int pcmcia_sock_attr_read( int sock, u16 offset, u8 *value ) { int ret = 0; - /* sanity check */ - if ( slot < 0 ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; - } - if ( slot > PCMCIA_MAX_SLOTS ) { - printf( "pcmcia: invalid slot slot %d\n", slot ); - ret = -1; - goto DONE; - } + if ( !PCMCIA_SOCK_NR_VALID( sock ) ) _DBGERR( dbg, -EINVAL ); - if ( !( pcmcia_slots[slot].status & PCMCIA_SS_ENABLED ) || - !( pcmcia_slots[slot].status & PCMCIA_SS_DETECT )) { - printf( "pcmcia: slot %d not detected and enabled\n", slot ); - ret = -1; - goto DONE; + *value = MEMb( pcmcia_driver->sock[sock].attr_base + offset ); + + _DBG( 1, "%s: ATTR_REG(0x%02x) => 0x%02x\n", __FUNCTION__, + offset, *value ); + + ret = 0; +DONE: + return ret; } - DBG( 1, "%s: ATTR_REG(0x%02x) <= 0x%02x\n", __FUNCTION__, +int pcmcia_sock_attr_write( int sock, u16 offset, u8 value ) +{ + int ret = 0; + + if ( !PCMCIA_SOCK_NR_VALID( sock ) ) _DBGERR( dbg, -EINVAL ); + + _DBG( 1, "%s: ATTR_REG(0x%02x) <= 0x%02x\n", __FUNCTION__, offset, value ); - MEMb( pcmcia_slots[slot].attr_base + - pcmcia_slots[slot].config_base + - offset - ) = value; + MEMb( pcmcia_driver->sock[sock].attr_base + offset) = value; ret = 0; DONE: return ret; } -/********************************************************************** - * static functions +/****************************************************************************** + * IO SPACE ACCESS */ - -/* print function id strings */ -static int pcmcia_print_funcid(int func) +int pcmcia_sock_io_read( int sock, u16 offset, u8 *value ) { - printf("\t "); - switch (func) { - case CISTPL_FUNCID_MULTI: - printf("Multi-Function"); - break; - case CISTPL_FUNCID_MEMORY: - printf("Memory"); - break; - case CISTPL_FUNCID_SERIAL: - printf("Serial Port"); - break; - case CISTPL_FUNCID_PARALLEL: - printf("Parallel Port"); - break; - case CISTPL_FUNCID_FIXED: - printf("Fixed Disk"); - break; - case CISTPL_FUNCID_VIDEO: - printf("Video Adapter"); - break; - case CISTPL_FUNCID_NETWORK: - printf("Network Adapter"); - break; - case CISTPL_FUNCID_AIMS: - printf("AIMS Card"); - break; - case CISTPL_FUNCID_SCSI: - printf("SCSI Adapter"); - break; - default: - printf("Unknown"); - break; - } - printf(" Card\n"); + int ret = 0; - return 0; + if ( !PCMCIA_SOCK_NR_VALID( sock ) ) _DBGERR( dbg, -EINVAL ); + + *value = MEMb( pcmcia_driver->sock[sock].io_base + offset); + + _DBG( 1, "%s: IO_REG(0x%02x) => 0x%02x\n", __FUNCTION__, + offset, *value ); + + ret = 0; +DONE: + return ret; } -/* print info for FIXED_DISK function type card */ -static int pcmcia_print_fixed(volatile u8 *p) +int pcmcia_sock_io_write( int sock, u16 offset, u8 value ) { - if (p == NULL) - return -1; + int ret = 0; - printf("\t "); + if ( !PCMCIA_SOCK_NR_VALID( sock ) ) _DBGERR( dbg, -EINVAL ); - switch (*p) { - case CISTPL_FUNCE_IDE_IFACE: - { u8 iface = *(p+2); + _DBG( 1, "%s: IO_REG(0x%02x) <= 0x%02x\n", __FUNCTION__, + offset, value ); - printf((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown"); - printf(" interface "); - break; + MEMb( pcmcia_driver->sock[sock].io_base + value ); + ret = 0; +DONE: + return ret; } - case CISTPL_FUNCE_IDE_MASTER: - case CISTPL_FUNCE_IDE_SLAVE: - { u8 f1 = *(p+2); - u8 f2 = *(p+4); - printf((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]"); +/****************************************************************************** + * MEMORY SPACE ACCESS + */ +int pcmcia_sock_mem_read( int sock, u16 offset, u8 *value ) +{ + int ret = 0; - if (f1 & CISTPL_IDE_UNIQUE) - printf(" [unique]"); + if ( !PCMCIA_SOCK_NR_VALID( sock ) ) _DBGERR( dbg, -EINVAL ); - printf((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]"); + *value = MEMb( pcmcia_driver->sock[sock].mem_base + offset); - if (f2 & CISTPL_IDE_HAS_SLEEP) - printf(" [sleep]"); + _DBG( 1, "%s: MEM_REG(0x%02x) => 0x%02x\n", __FUNCTION__, + offset, *value ); - if (f2 & CISTPL_IDE_HAS_STANDBY) - printf(" [standby]"); + ret = 0; +DONE: + return ret; +} - if (f2 & CISTPL_IDE_HAS_IDLE) - printf(" [idle]"); +int pcmcia_sock_mem_write( int sock, u16 offset, u8 value ) +{ + int ret = 0; - if (f2 & CISTPL_IDE_LOW_POWER) - printf(" [low power]"); + if ( !PCMCIA_SOCK_NR_VALID( sock ) ) _DBGERR( dbg, -EINVAL ); - if (f2 & CISTPL_IDE_REG_INHIBIT) - printf(" [reg inhibit]"); + _DBG( 1, "%s: MEM_REG(0x%02x) <= 0x%02x\n", __FUNCTION__, + offset, value ); - if (f2 & CISTPL_IDE_HAS_INDEX) - printf(" [index]"); + MEMb( pcmcia_driver->sock[sock].mem_base + value ); + ret = 0; +DONE: + return ret; +} - if (f2 & CISTPL_IDE_IOIS16) - printf(" [IOis16]"); +/****************************************************************************** + * Test commands + */ - break; - } +/********************************************************************* + * test_pcmcia_cmd - short desc + * @argc: desc + * @char *argv[]: desc + * + * Long desc + */ +int test_pcmcia_cmd( int argc, char *argv[] ) +{ + int ret = 0; + int nr, start, end; + + pcmcia_dbg_set( 100 ); + + if ( !pcmcia_driver ) { + printf( "No pcmcia driver!\n" ); + ret = -EINVAL; goto DONE; } + + printf( "Testing BLOB PCMCIA\n" ); + printf( "-------------------\n" ); + printf("\n"); + printf( "driver: '%s'\n", pcmcia_driver->name?pcmcia_driver->name:"UNKNOWN" ); + + printf( "\n" ); + printf( "%d sockets configured, starting at %d\n", pcmcia_driver->nr, pcmcia_driver->first ); + + start = pcmcia_driver->first; + end = start + pcmcia_driver->nr; + for ( nr=start; nr<end; nr++ ) { + struct pcmcia_sock *sock; + ret = pcmcia_sock_get( nr, &sock ); + if ( ret ) _DBGERR( dbg, ret ); + + printf( "Socket %d: IO [ 0x%08X ], ATTR [ 0x%08X ], MEM [ 0x%08X ]\n", + nr, sock->io_base, sock->attr_base, sock->mem_base ); - return 0; } + ret = pcmcia_init(); + printf( "detected %d cards.\n", ret ); + + ret = 0; +DONE: + return ret; +} +char pcmciatest_help[] = "pcmcia_test command\n"; +__commandlist(test_pcmcia_cmd, "pcmcia_test", pcmciatest_help ); Index: Makefile.am =================================================================== RCS file: /cvsroot/blob/blob/src/lib/Makefile.am,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- Makefile.am 27 Nov 2003 08:02:31 -0000 1.35 +++ Makefile.am 9 Feb 2004 19:25:12 -0000 1.36 @@ -75,6 +75,8 @@ ip_bits.c\ ide.c \ pcmcia.c \ + pcmcia-sa1111.c \ + pcmcia-pxa.c \ cf.c \ generic_io.c \ gio_part_blob.c \ |