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

Linux/Unix编程

开发平台:

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. #include "sa1100_generic.h"
  13. #ifdef CONFIG_SA1100_CERF_CPLD
  14. #define CERF_SOCKET 0
  15. #else
  16. #define CERF_SOCKET 1
  17. #endif
  18. static struct irqs {
  19. int irq;
  20. unsigned int gpio;
  21. const char *str;
  22. } irqs[] = {
  23. { IRQ_GPIO_CF_CD,   GPIO_CF_CD,   "CF_CD"   },
  24. { IRQ_GPIO_CF_BVD2, GPIO_CF_BVD2, "CF_BVD2" },
  25. { IRQ_GPIO_CF_BVD1, GPIO_CF_BVD1, "CF_BVD1" }
  26. };
  27. static int cerf_pcmcia_init(struct pcmcia_init *init)
  28. {
  29.   int i, res;
  30.   set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
  31.   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
  32.     set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
  33.     res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
  34.       irqs[i].str, NULL);
  35.     if (res)
  36.       goto irq_err;
  37.   }
  38.   return 2;
  39.  irq_err:
  40.   printk(KERN_ERR "%s: Request for IRQ%d failedn", __FUNCTION__, irqs[i].irq);
  41.   while (i--)
  42.     free_irq(irqs[i].irq, NULL);
  43.   return -1;
  44. }
  45. static int cerf_pcmcia_shutdown(void)
  46. {
  47.   int i;
  48.   for (i = 0; i < ARRAY_SIZE(irqs); i++)
  49.     free_irq(irqs[i].irq, NULL);
  50.   return 0;
  51. }
  52. static int cerf_pcmcia_socket_state(struct pcmcia_state_array
  53.        *state_array){
  54.   unsigned long levels;
  55.   int i = CERF_SOCKET;
  56.   if(state_array->size<2) return -1;
  57.   levels=GPLR;
  58.   state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0;
  59.   state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0;
  60.   state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0;
  61.   state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0;
  62.   state_array->state[i].wrprot=0;
  63.   state_array->state[i].vs_3v=1;
  64.   state_array->state[i].vs_Xv=0;
  65.   return 1;
  66. }
  67. static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
  68.   if(info->sock>1) return -1;
  69.   if (info->sock == CERF_SOCKET)
  70.     info->irq=IRQ_GPIO_CF_IRQ;
  71.   return 0;
  72. }
  73. static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
  74.    *configure)
  75. {
  76.   if(configure->sock>1)
  77.     return -1;
  78.   if (configure->sock != CERF_SOCKET)
  79.     return 0;
  80.   switch(configure->vcc){
  81.   case 0:
  82.     break;
  83.   case 50:
  84.   case 33:
  85. #ifdef CONFIG_SA1100_CERF_CPLD
  86.      GPCR = GPIO_PWR_SHUTDOWN;
  87. #endif
  88.      break;
  89.   default:
  90.     printk(KERN_ERR "%s(): unrecognized Vcc %un", __FUNCTION__,
  91.    configure->vcc);
  92.     return -1;
  93.   }
  94.   if(configure->reset)
  95.   {
  96. #ifdef CONFIG_SA1100_CERF_CPLD
  97.     GPSR = GPIO_CF_RESET;
  98. #endif
  99.   }
  100.   else
  101.   {
  102. #ifdef CONFIG_SA1100_CERF_CPLD
  103.     GPCR = GPIO_CF_RESET;
  104. #endif
  105.   }
  106.   return 0;
  107. }
  108. static int cerf_pcmcia_socket_init(int sock)
  109. {
  110.   int i;
  111.   if (sock == CERF_SOCKET)
  112.     for (i = 0; i < ARRAY_SIZE(irqs); i++)
  113.       set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
  114.   return 0;
  115. }
  116. static int cerf_pcmcia_socket_suspend(int sock)
  117. {
  118.   int i;
  119.   if (sock == CERF_SOCKET)
  120.     for (i = 0; i < ARRAY_SIZE(irqs); i++)
  121.       set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
  122.   return 0;
  123. }
  124. struct pcmcia_low_level cerf_pcmcia_ops = { 
  125.   init: cerf_pcmcia_init,
  126.   shutdown: cerf_pcmcia_shutdown,
  127.   socket_state: cerf_pcmcia_socket_state,
  128.   get_irq_info: cerf_pcmcia_get_irq_info,
  129.   configure_socket: cerf_pcmcia_configure_socket,
  130.   socket_init: cerf_pcmcia_socket_init,
  131.   socket_suspend: cerf_pcmcia_socket_suspend,
  132. };