Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * drivers/pcmcia/sa1100_simpad.c
  3  *
  4  * PCMCIA implementation routines for simpad
  5  *
  6  */
  7 #include <linux/module.h>
  8 #include <linux/kernel.h>
  9 #include <linux/device.h>
 10 #include <linux/init.h>
 11 
 12 #include <mach/hardware.h>
 13 #include <asm/mach-types.h>
 14 #include <asm/irq.h>
 15 #include <mach/simpad.h>
 16 #include "sa1100_generic.h"
 17  
 18 extern long get_cs3_shadow(void);
 19 extern void set_cs3_bit(int value); 
 20 extern void clear_cs3_bit(int value);
 21 
 22 static struct pcmcia_irqs irqs[] = {
 23         { 1, IRQ_GPIO_CF_CD, "CF_CD" },
 24 };
 25 
 26 static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 27 {
 28 
 29         clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 30 
 31         skt->irq = IRQ_GPIO_CF_IRQ;
 32 
 33         return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 34 }
 35 
 36 static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 37 {
 38         soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 39 
 40         /* Disable CF bus: */
 41         //set_cs3_bit(PCMCIA_BUFF_DIS);
 42         clear_cs3_bit(PCMCIA_RESET);       
 43 }
 44 
 45 static void
 46 simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 47                            struct pcmcia_state *state)
 48 {
 49         unsigned long levels = GPLR;
 50         long cs3reg = get_cs3_shadow();
 51 
 52         state->detect=((levels & GPIO_CF_CD)==0)?1:0;
 53         state->ready=(levels & GPIO_CF_IRQ)?1:0;
 54         state->bvd1=1; /* Not available on Simpad. */
 55         state->bvd2=1; /* Not available on Simpad. */
 56         state->wrprot=0; /* Not available on Simpad. */
 57   
 58         if((cs3reg & 0x0c) == 0x0c) {
 59                 state->vs_3v=0;
 60                 state->vs_Xv=0;
 61         } else {
 62                 state->vs_3v=1;
 63                 state->vs_Xv=0;
 64         }
 65 }
 66 
 67 static int
 68 simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 69                                const socket_state_t *state)
 70 {
 71         unsigned long flags;
 72 
 73         local_irq_save(flags);
 74 
 75         /* Murphy: see table of MIC2562a-1 */
 76         switch (state->Vcc) {
 77         case 0:
 78                 clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 79                 break;
 80 
 81         case 33:  
 82                 clear_cs3_bit(VCC_3V_EN|EN1);
 83                 set_cs3_bit(VCC_5V_EN|EN0);
 84                 break;
 85 
 86         case 50:
 87                 clear_cs3_bit(VCC_5V_EN|EN1);
 88                 set_cs3_bit(VCC_3V_EN|EN0);
 89                 break;
 90 
 91         default:
 92                 printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
 93                         __func__, state->Vcc);
 94                 clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 95                 local_irq_restore(flags);
 96                 return -1;
 97         }
 98 
 99 
100         local_irq_restore(flags);
101 
102         return 0;
103 }
104 
105 static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
106 {
107         soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
108 }
109 
110 static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
111 {
112         soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
113         set_cs3_bit(PCMCIA_RESET);
114 }
115 
116 static struct pcmcia_low_level simpad_pcmcia_ops = { 
117         .owner                  = THIS_MODULE,
118         .hw_init                = simpad_pcmcia_hw_init,
119         .hw_shutdown            = simpad_pcmcia_hw_shutdown,
120         .socket_state           = simpad_pcmcia_socket_state,
121         .configure_socket       = simpad_pcmcia_configure_socket,
122         .socket_init            = simpad_pcmcia_socket_init,
123         .socket_suspend         = simpad_pcmcia_socket_suspend,
124 };
125 
126 int __init pcmcia_simpad_init(struct device *dev)
127 {
128         int ret = -ENODEV;
129 
130         if (machine_is_simpad())
131                 ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1);
132 
133         return ret;
134 }
135 
  This page was automatically generated by the LXR engine.