sa1100_stork.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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