sa1100_cerf.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * drivers/pcmcia/sa1100_cerf.c
  3.  *
  4.  * PCMCIA implementation routines for CerfBoard
  5.  * Based off the Assabet.
  6.  *
  7.  */
  8. #include <linux/kernel.h>
  9. #include <linux/sched.h>
  10. #include <asm/hardware.h>
  11. #include <asm/irq.h>
  12. #ifdef CONFIG_SA1100_CERF
  13. include "sa1100_generic.h"
  14. #else
  15. #include <asm/arch/pcmcia.h>
  16. #endif
  17. #include "sa1100_cerf.h"
  18. /*
  19.  * Set this to zero to remove all the debug statements via
  20.  * dead code elimination
  21.  */
  22. //#define DEBUGGING       1
  23. #if DEBUGGING
  24. static unsigned int pcmcia_debug = DEBUGGING;
  25. #else
  26. #define pcmcia_debug 0     /* gcc will remove all the debug code for us */
  27. #endif
  28. static struct irqs {
  29. int irq;
  30. unsigned int gpio;
  31. const char *str;
  32. } irqs[] = {
  33. { PCMCIA_IRQ_CF_CD,   PCMCIA_GPIO_CF_CD_EDGE,   "CF_CD"   },
  34. { PCMCIA_IRQ_CF_BVD2, PCMCIA_GPIO_CF_BVD2_EDGE, "CF_BVD2" },
  35. { PCMCIA_IRQ_CF_BVD1, PCMCIA_GPIO_CF_BVD1_EDGE, "CF_BVD1" }
  36. };
  37. static int cerf_pcmcia_init(struct pcmcia_init *init)
  38. {
  39. int i, res;
  40. if( pcmcia_debug)
  41. printk( KERN_INFO "cerf_pcmcia_init: entern");
  42. cerf_pcmcia_set_gpio_direction();
  43. set_GPIO_IRQ_edge( PCMCIA_GPIO_CF_IRQ_EDGE, GPIO_FALLING_EDGE );
  44. for (i = 0; i < ARRAY_SIZE(irqs); i++) {
  45. set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
  46. res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
  47. irqs[i].str, NULL);
  48. if (res)
  49. goto irq_err;
  50. }
  51. printk( KERN_INFO "PCMCIA for Cerf: OKn");
  52. return CERF_SOCKET+1; /* last socket used +1 */
  53. irq_err:
  54. printk(KERN_ERR "%s: Request for IRQ%d failedn", 
  55. __FUNCTION__, irqs[i].irq);
  56. while (i--)
  57. free_irq(irqs[i].irq, NULL);
  58. return -1;
  59. }
  60. static int cerf_pcmcia_shutdown(void)
  61. {
  62. int i;
  63. if( pcmcia_debug)
  64. printk( KERN_INFO "cerf_pcmcia_shutdown: entern");
  65. for (i = 0; i < ARRAY_SIZE(irqs); i++)
  66. free_irq(irqs[i].irq, NULL);
  67. return 0;
  68. }
  69. static int cerf_pcmcia_socket_state(struct pcmcia_state_array *state_array)
  70. {
  71. int i = CERF_SOCKET;
  72. if( pcmcia_debug > 3)
  73. printk( KERN_INFO "cerf_pcmcia_socket_state: i=%d, size=%dn",
  74. i, state_array->size);
  75.         memset(state_array->state, 0,
  76.                         (state_array->size)*sizeof(struct pcmcia_state));
  77. state_array->state[i].detect = cerf_pcmcia_level_detect();
  78. state_array->state[i].ready  = cerf_pcmcia_level_ready();
  79. state_array->state[i].bvd1   = cerf_pcmcia_level_bvd1();
  80. state_array->state[i].bvd2   = cerf_pcmcia_level_bvd2();
  81. state_array->state[i].wrprot=0;
  82. state_array->state[i].vs_3v=1;
  83. state_array->state[i].vs_Xv=0;
  84. if( pcmcia_debug > 3)
  85. printk( KERN_INFO "cerf_pcmcia_socket_state: "
  86. "detect=%d ready=%d bvd1=%d bvd2=%dn", 
  87. state_array->state[i].detect,
  88. state_array->state[i].ready,
  89. state_array->state[i].bvd1,
  90. state_array->state[i].bvd2);
  91. return 1;
  92. }
  93. static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
  94. if( pcmcia_debug)
  95. printk( KERN_INFO "cerf_pcmcia_get_irq_info: "
  96. "sock=%dn", info->sock);
  97. if(info->sock>1) return -1;
  98. if (info->sock == CERF_SOCKET)
  99. info->irq=PCMCIA_IRQ_CF_IRQ;
  100. if( pcmcia_debug)
  101. printk( KERN_INFO "cerf_pcmcia_get_irq_info: irq=%dn",info->irq);
  102. return 0;
  103. }
  104. static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
  105. *configure)
  106. {
  107. if( pcmcia_debug)
  108. printk( KERN_INFO "cerf_pcmcia_configure_socket:"
  109. "sock=%d vcc=%d reset=%dn",
  110. configure->sock, configure->vcc, configure->reset);
  111. if(configure->sock>1)
  112. return -1;
  113. if (configure->sock != CERF_SOCKET)
  114. return 0;
  115. switch(configure->vcc){
  116. case 0:
  117. break;
  118. case 50:
  119. case 33:
  120. #if defined(CONFIG_SA1100_CERF_CPLD)
  121.                         PCMCIA_GPDR |= PCMCIA_PWR_SHUTDOWN;
  122.                         PCMCIA_GPCR |= PCMCIA_PWR_SHUTDOWN;
  123. #endif
  124.                         /* voltage selected automatically */
  125. break;
  126. default:
  127. printk(KERN_ERR "%s(): unrecognized Vcc %un", 
  128. __FUNCTION__, configure->vcc);
  129. return -1;
  130. }
  131. if(configure->reset)
  132. {
  133. PCMCIA_GPSR = PCMCIA_GPIO_CF_RESET_MASK;
  134. }
  135. else
  136. {
  137. PCMCIA_GPCR = PCMCIA_GPIO_CF_RESET_MASK;
  138. }
  139. return 0;
  140. }
  141. #ifdef CONFIG_SA1100_CERF
  142. static int cerf_pcmcia_socket_init(int sock)
  143. {
  144.   int i;
  145.   if( pcmcia_debug)
  146.       printk( KERN_INFO "cerf_pcmcia_socket_init: sock=%dn",sock);
  147.   if (sock == CERF_SOCKET)
  148.     for (i = 0; i < ARRAY_SIZE(irqs); i++)
  149.       set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
  150.   return 0;
  151. }
  152. static int cerf_pcmcia_socket_suspend(int sock)
  153. {
  154.   int i;
  155.   if( pcmcia_debug)
  156.       printk( KERN_INFO "cerf_pcmcia_socket_suspend: sock=%dn",sock);
  157.   if (sock == CERF_SOCKET)
  158.     for (i = 0; i < ARRAY_SIZE(irqs); i++)
  159.       set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
  160.   return 0;
  161. }
  162. #endif
  163. struct pcmcia_low_level cerf_pcmcia_ops = { 
  164.   init: cerf_pcmcia_init,
  165.   shutdown: cerf_pcmcia_shutdown,
  166.   socket_state: cerf_pcmcia_socket_state,
  167.   get_irq_info: cerf_pcmcia_get_irq_info,
  168.   configure_socket: cerf_pcmcia_configure_socket,
  169. #ifdef CONFIG_SA1100_CERF
  170.   socket_init: cerf_pcmcia_socket_init,
  171.   socket_suspend: cerf_pcmcia_socket_suspend,
  172. #endif
  173. };