sa1100_stork.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
- /*
- * drivers/pcmcia/sa1100_stork.c
- *
- Copyright 2001 (C) Ken Gordon
- This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
- 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.
- 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.
- *
- * PCMCIA implementation routines for stork
- *
- */
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
- #include <linux/i2c.h>
- #include <asm/hardware.h>
- #include <asm/irq.h>
- #include "sa1100_generic.h"
- static int debug = 0;
- static struct pcmcia_init sa1100_stork_pcmcia_init;
- static int stork_pcmcia_init(struct pcmcia_init *init)
- {
- int irq, res;
- printk("in stork_pcmcia_initn");
- sa1100_stork_pcmcia_init = *init;
- /* Set transition detect */
- set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES );
- set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
- /* Register interrupts */
- irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
- res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
- if( res < 0 ) goto irq_err;
- irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
- res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
- if( res < 0 ) goto irq_err;
- return 2;
- irq_err:
- printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failedn", irq );
- return -1;
- }
- static int stork_pcmcia_shutdown(void)
- {
- printk(__FUNCTION__ "n");
- /* disable IRQs */
- free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
- free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );
-
- /* Disable CF bus: */
- storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
- storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
- storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
- return 0;
- }
- static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
- {
- unsigned long levels;
- if(state_array->size<2) return -1;
- memset(state_array->state, 0,
- (state_array->size)*sizeof(struct pcmcia_state));
- levels=GPLR;
- if (debug > 1)
- printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%xn", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
- state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
- state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
- state_array->state[0].bvd1= 1;
- state_array->state[0].bvd2= 1;
- state_array->state[0].wrprot=0;
- state_array->state[0].vs_3v=1;
- state_array->state[0].vs_Xv=0;
- state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
- state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
- state_array->state[1].bvd1=1;
- state_array->state[1].bvd2=1;
- state_array->state[1].wrprot=0;
- state_array->state[1].vs_3v=1;
- state_array->state[1].vs_Xv=0;
- return 1;
- }
- static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
- {
- switch (info->sock) {
- case 0:
- info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
- break;
- case 1:
- info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
- break;
- default:
- return -1;
- }
- return 0;
- }
- static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
- {
- int card = configure->sock;
- unsigned long flags;
- int DETECT, RDY, POWER, RESET;
- if (card > 1) return -1;
- printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%dn",
- card, configure->vcc, configure->vpp, configure->reset);
- save_flags_cli(flags);
- if (card == 0) {
- DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
- RDY = GPIO_STORK_PCMCIA_A_RDY;
- POWER = STORK_PCMCIA_A_POWER_ON;
- RESET = STORK_PCMCIA_A_RESET;
- } else {
- DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
- RDY = GPIO_STORK_PCMCIA_B_RDY;
- POWER = STORK_PCMCIA_B_POWER_ON;
- RESET = STORK_PCMCIA_B_RESET;
- }
-
- /*
- if (storkTestGPIO(DETECT)) {
- printk("no card detected - but resetting anywayrn");
- }
- */
- switch (configure->vcc) {
- case 0:
- /* storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON); */
- storkClearLatchA(POWER);
- break;
- case 50:
- case 33:
- storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
- storkSetLatchA(POWER);
- break;
- default:
- printk(KERN_ERR "%s(): unrecognized Vcc %un", __FUNCTION__,
- configure->vcc);
- restore_flags(flags);
- return -1;
- }
- if (configure->reset)
- storkSetLatchB(RESET);
- else
- storkClearLatchB(RESET);
- restore_flags(flags);
- /* silently ignore vpp and speaker enables. */
- printk(__FUNCTION__ ": finishedn");
- return 0;
- }
- static int stork_pcmcia_socket_init(int sock)
- {
- storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
- if (sock == 0)
- set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_BOTH_EDGES);
- else if (sock == 1)
- set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES);
- return 0;
- }
- static int stork_pcmcia_socket_suspend(int sock)
- {
- if (sock == 0)
- set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_NO_EDGES);
- else if (sock == 1) {
- set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES);
- /*
- * Hack!
- */
- storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
- }
- return 0;
- }
- struct pcmcia_low_level stork_pcmcia_ops = {
- init: stork_pcmcia_init,
- shutdown: stork_pcmcia_shutdown,
- socket_state: stork_pcmcia_socket_state,
- get_irq_info: stork_pcmcia_get_irq_info,
- configure_socket: stork_pcmcia_configure_socket,
- socket_init: stork_pcmcia_socket_init,
- socket_suspend: stork_pcmcia_socket_suspend,
- };