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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * drivers/pcmcia/sa1100_simpad.c
  3.  *
  4.  * PCMCIA implementation routines for simpad
  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.  
  13. extern long get_cs3_shadow(void);
  14. extern void set_cs3_bit(int value); 
  15. extern void clear_cs3_bit(int value);
  16. static int simpad_pcmcia_init(struct pcmcia_init *init){
  17.   int irq, res;
  18.   set_cs3_bit(PCMCIA_RESET);
  19.   clear_cs3_bit(PCMCIA_BUFF_DIS);
  20.   clear_cs3_bit(PCMCIA_RESET);
  21.   clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  22.   /* Set transition detect */
  23.   set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_NO_EDGES );
  24.   set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
  25.   /* Register interrupts */
  26.   irq = IRQ_GPIO_CF_CD;
  27.   res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
  28.   if( res < 0 ) goto irq_err;
  29.   /* There's only one slot, but it's "Slot 1": */
  30.   return 2;
  31. irq_err:
  32.   printk( KERN_ERR "%s: Request for IRQ %lu failedn", __FUNCTION__, irq );
  33.   return -1;
  34. }
  35. static int simpad_pcmcia_shutdown(void)
  36. {
  37.   /* disable IRQs */
  38.   free_irq( IRQ_GPIO_CF_CD, NULL );
  39.   
  40.   /* Disable CF bus: */
  41.   
  42.   //set_cs3_bit(PCMCIA_BUFF_DIS);
  43.   clear_cs3_bit(PCMCIA_RESET);       
  44.   
  45.   return 0;
  46. }
  47. static int simpad_pcmcia_socket_state(struct pcmcia_state_array
  48.        *state_array)
  49. {
  50.   unsigned long levels;
  51.   unsigned long *cs3reg = CS3_BASE;
  52.   if(state_array->size<2) return -1;
  53.   memset(state_array->state, 0, 
  54.  (state_array->size)*sizeof(struct pcmcia_state));
  55.   levels=GPLR;
  56.   state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
  57.   state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
  58.   state_array->state[1].bvd1=1; /* Not available on Simpad. */
  59.   state_array->state[1].bvd2=1; /* Not available on Simpad. */
  60.   state_array->state[1].wrprot=0; /* Not available on Simpad. */
  61.   
  62.   if((*cs3reg & 0x0c) == 0x0c) {
  63.     state_array->state[1].vs_3v=0;
  64.     state_array->state[1].vs_Xv=0;
  65.   } else
  66.   {
  67.     state_array->state[1].vs_3v=1;
  68.     state_array->state[1].vs_Xv=0;
  69.   }
  70.   return 1;
  71. }
  72. static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
  73.   if(info->sock>1) return -1;
  74.   if(info->sock==1)
  75.     info->irq=IRQ_GPIO_CF_IRQ;
  76.   return 0;
  77. }
  78. static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
  79.    *configure)
  80. {
  81.   unsigned long value, flags;
  82.   if(configure->sock>1) return -1;
  83.   if(configure->sock==0) return 0;
  84.   save_flags_cli(flags);
  85.   /* Murphy: see table of MIC2562a-1 */
  86.   switch(configure->vcc){
  87.   case 0:
  88.     clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  89.     break;
  90.   case 33:  
  91.     clear_cs3_bit(VCC_3V_EN|EN0);
  92.     set_cs3_bit(VCC_5V_EN|EN1);
  93.     break;
  94.   case 50:
  95.     clear_cs3_bit(VCC_5V_EN|EN1);
  96.     set_cs3_bit(VCC_3V_EN|EN0);
  97.     break;
  98.   default:
  99.     printk(KERN_ERR "%s(): unrecognized Vcc %un", __FUNCTION__,
  100.    configure->vcc);
  101.     clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  102.     restore_flags(flags);
  103.     return -1;
  104.   }
  105.   /* Silently ignore Vpp, output enable, speaker enable. */
  106.   restore_flags(flags);
  107.   return 0;
  108. }
  109. static int simpad_pcmcia_socket_init(int sock)
  110. {
  111.   set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_BOTH_EDGES);
  112.   return 0;
  113. }
  114. static int simpad_pcmcia_socket_suspend(int sock)
  115. {
  116.   set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_NO_EDGES);
  117.   return 0;
  118. }
  119. struct pcmcia_low_level simpad_pcmcia_ops = { 
  120.   init: simpad_pcmcia_init,
  121.   shutdown: simpad_pcmcia_shutdown,
  122.   socket_state: simpad_pcmcia_socket_state,
  123.   get_irq_info: simpad_pcmcia_get_irq_info,
  124.   configure_socket: simpad_pcmcia_configure_socket,
  125.   socket_init: simpad_pcmcia_socket_init,
  126.   socket_suspend: simpad_pcmcia_socket_suspend,
  127. };