linux-old/drivers/pcmcia/sa1100_stork.c
<<
>>
Prefs
   1/* 
   2 * drivers/pcmcia/sa1100_stork.c
   3 *
   4    Copyright 2001 (C) Ken Gordon
   5
   6    This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
   7
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 2 of the License.
  11
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16
  17 * 
  18 * PCMCIA implementation routines for stork
  19 *
  20 */
  21
  22#include <linux/config.h>
  23#include <linux/module.h>
  24#include <linux/init.h>
  25#include <linux/kernel.h>
  26#include <linux/sched.h>
  27
  28#include <asm/hardware.h>
  29#include <asm/irq.h>
  30#include "sa1100_generic.h"
  31
  32static int debug = 0;
  33
  34static struct pcmcia_init sa1100_stork_pcmcia_init;
  35
  36static int stork_pcmcia_init(struct pcmcia_init *init)
  37{
  38        int irq, res;
  39        printk("in stork_pcmcia_init\n");
  40
  41        sa1100_stork_pcmcia_init = *init;
  42
  43        /* Set transition detect */
  44        set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES );
  45        set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
  46
  47        /* Register interrupts */
  48        irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
  49        res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
  50        if( res < 0 ) goto irq_err;
  51        irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
  52        res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
  53        if( res < 0 ) goto irq_err;
  54
  55        return 2;
  56
  57 irq_err:
  58        printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
  59        return -1;
  60}
  61
  62static int stork_pcmcia_shutdown(void)
  63{
  64        printk(__FUNCTION__ "\n");
  65        /* disable IRQs */
  66        free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
  67        free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );
  68  
  69        /* Disable CF bus: */
  70        storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
  71        storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
  72        storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
  73        return 0;
  74}
  75
  76static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
  77{
  78        unsigned long levels;
  79
  80        if(state_array->size<2) return -1;
  81
  82        memset(state_array->state, 0, 
  83               (state_array->size)*sizeof(struct pcmcia_state));
  84
  85        levels=GPLR;
  86
  87        if (debug > 1)
  88                printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
  89        state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
  90        state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
  91        state_array->state[0].bvd1= 1;
  92        state_array->state[0].bvd2= 1;
  93        state_array->state[0].wrprot=0;
  94        state_array->state[0].vs_3v=1;
  95        state_array->state[0].vs_Xv=0;
  96
  97        state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
  98        state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
  99        state_array->state[1].bvd1=1;
 100        state_array->state[1].bvd2=1;
 101        state_array->state[1].wrprot=0;
 102        state_array->state[1].vs_3v=1;
 103        state_array->state[1].vs_Xv=0;
 104
 105        return 1;
 106}
 107
 108static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
 109{
 110
 111        switch (info->sock) {
 112        case 0:
 113                info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
 114                break;
 115        case 1:
 116                info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
 117                break;
 118        default:
 119                return -1;
 120        }
 121        return 0;
 122}
 123
 124static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
 125{
 126        int card = configure->sock;
 127        unsigned long flags;
 128
 129        int DETECT, RDY, POWER, RESET;
 130
 131        if (card > 1) return -1;
 132
 133        printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n", 
 134                       card, configure->vcc, configure->vpp, configure->reset);
 135
 136        save_flags_cli(flags);
 137
 138        if (card == 0) {
 139            DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
 140            RDY = GPIO_STORK_PCMCIA_A_RDY;
 141            POWER = STORK_PCMCIA_A_POWER_ON;
 142            RESET = STORK_PCMCIA_A_RESET;
 143        } else {
 144            DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
 145            RDY = GPIO_STORK_PCMCIA_B_RDY;
 146            POWER = STORK_PCMCIA_B_POWER_ON;
 147            RESET = STORK_PCMCIA_B_RESET;
 148        }
 149    
 150/*
 151        if (storkTestGPIO(DETECT)) {
 152           printk("no card detected - but resetting anyway\r\n");
 153        }
 154*/
 155        switch (configure->vcc) {
 156        case 0:
 157/*              storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON); */
 158                storkClearLatchA(POWER);
 159                break;
 160
 161        case 50:
 162        case 33:
 163                storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
 164                storkSetLatchA(POWER);
 165                break;
 166
 167        default:
 168                printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
 169                       configure->vcc);
 170                restore_flags(flags);
 171                return -1;
 172        }
 173
 174        if (configure->reset)
 175                storkSetLatchB(RESET);
 176        else
 177                storkClearLatchB(RESET);
 178
 179        restore_flags(flags);
 180
 181        /* silently ignore vpp and speaker enables. */
 182
 183        printk(__FUNCTION__ ": finished\n");
 184
 185        return 0;
 186}
 187
 188static int stork_pcmcia_socket_init(int sock)
 189{
 190        storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
 191
 192        if (sock == 0)
 193                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_BOTH_EDGES);
 194        else if (sock == 1)
 195                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES);
 196
 197        return 0;
 198}
 199
 200static int stork_pcmcia_socket_suspend(int sock)
 201{
 202        if (sock == 0)
 203                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_NO_EDGES);
 204        else if (sock == 1) {
 205                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES);
 206
 207                /*
 208                 * Hack!
 209                 */
 210                storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
 211        }
 212
 213        return 0;
 214}
 215
 216struct pcmcia_low_level stork_pcmcia_ops = { 
 217        init:                   stork_pcmcia_init,
 218        shutdown:               stork_pcmcia_shutdown,
 219        socket_state:           stork_pcmcia_socket_state,
 220        get_irq_info:           stork_pcmcia_get_irq_info,
 221        configure_socket:       stork_pcmcia_configure_socket,
 222
 223        socket_init:            stork_pcmcia_socket_init,
 224        socket_suspend:         stork_pcmcia_socket_suspend,
 225};
 226
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.