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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * drivers/pcmcia/sa1100_yopy.c
  3.  *
  4.  * PCMCIA implementation routines for Yopy
  5.  *
  6.  */
  7. #include <linux/kernel.h>
  8. #include <linux/sched.h>
  9. #include <asm/hardware.h>
  10. #include <asm/irq.h>
  11. #include "sa1100_generic.h"
  12. static inline void pcmcia_power(int on) {
  13. /* high for power up */
  14. yopy_gpio_set(GPIO_CF_POWER, on);
  15. }
  16. static inline void pcmcia_reset(int reset)
  17. {
  18. /* high for reset */
  19. yopy_gpio_set(GPIO_CF_RESET, reset);
  20. }
  21. static int yopy_pcmcia_init(struct pcmcia_init *init)
  22. {
  23. int irq, res;
  24. pcmcia_power(0);
  25. pcmcia_reset(1);
  26. /* Set transition detect */
  27. set_GPIO_IRQ_edge(GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
  28.   GPIO_NO_EDGES);
  29. set_GPIO_IRQ_edge( GPIO_CF_IREQ, GPIO_FALLING_EDGE );
  30. /* Register interrupts */
  31. irq = IRQ_CF_CD;
  32. res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_CD", NULL);
  33. if (res < 0) goto irq_err;
  34. irq = IRQ_CF_BVD2;
  35. res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL);
  36. if (res < 0) goto irq_err;
  37. irq = IRQ_CF_BVD1;
  38. res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL);
  39. if (res < 0) goto irq_err;
  40. return 1;
  41. irq_err:
  42. printk(KERN_ERR "%s: Request for IRQ %d failedn", __FUNCTION__, irq);
  43. return -1;
  44. }
  45. static int yopy_pcmcia_shutdown(void)
  46. {
  47. /* disable IRQs */
  48. free_irq( IRQ_CF_CD, NULL );
  49. free_irq( IRQ_CF_BVD2, NULL );
  50. free_irq( IRQ_CF_BVD1, NULL );
  51. /* Disable CF */
  52. pcmcia_reset(1);
  53. pcmcia_power(0);
  54. return 0;
  55. }
  56. static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
  57. {
  58. unsigned long levels;
  59. if (state_array->size != 1)
  60. return -1;
  61. memset(state_array->state, 0,
  62.        state_array->size * sizeof(struct pcmcia_state));
  63. levels = GPLR;
  64. state_array->state[0].detect = (levels & GPIO_CF_CD)    ? 0 : 1;
  65. state_array->state[0].ready  = (levels & GPIO_CF_READY) ? 1 : 0;
  66. state_array->state[0].bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
  67. state_array->state[0].bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
  68. state_array->state[0].wrprot = 0; /* Not available on Yopy. */
  69. state_array->state[0].vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
  70. state_array->state[0].vs_Xv  = 0;
  71. return 1;
  72. }
  73. static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
  74. {
  75. if (info->sock != 0)
  76. return -1;
  77. info->irq = IRQ_CF_IREQ;
  78. return 0;
  79. }
  80. static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
  81. {
  82. if (configure->sock != 0)
  83. return -1;
  84. switch (configure->vcc) {
  85. case 0: /* power off */;
  86. pcmcia_power(0);
  87. break;
  88. case 50:
  89. printk(KERN_WARNING __FUNCTION__"(): CS asked for 5V, applying 3.3V..n");
  90. case 33:
  91. pcmcia_power(1);
  92. break;
  93. default:
  94. printk(KERN_ERR __FUNCTION__"(): unrecognized Vcc %un",
  95.        configure->vcc);
  96. return -1;
  97. }
  98. pcmcia_reset(configure->reset);
  99. /* Silently ignore Vpp, output enable, speaker enable. */
  100. return 0;
  101. }
  102. static int yopy_pcmcia_socket_init(int sock)
  103. {
  104. set_GPIO_IRQ_edge(GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
  105.   GPIO_BOTH_EDGES);
  106. return 0;
  107. }
  108. static int yopy_pcmcia_socket_suspend(int sock)
  109. {
  110. set_GPIO_IRQ_edge(GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
  111.   GPIO_NO_EDGES);
  112. return 0;
  113. }
  114. struct pcmcia_low_level yopy_pcmcia_ops = {
  115. init: yopy_pcmcia_init,
  116. shutdown: yopy_pcmcia_shutdown,
  117. socket_state: yopy_pcmcia_socket_state,
  118. get_irq_info: yopy_pcmcia_get_irq_info,
  119. configure_socket: yopy_pcmcia_configure_socket,
  120. socket_init: yopy_pcmcia_socket_init,
  121. socket_suspend: yopy_pcmcia_socket_suspend,
  122. };