sync hh.org
[hh.org.git] / drivers / pcmcia / sa1100_jornada56x.c
blob44ad5ea75a50e1312fcbcf02ab9630ed3fd2c3d4
2 /*
3 * drivers/pcmcia/sa1100_jornada56x.c
5 * PCMCIA implementation routines for the HP Jornada 56x
7 */
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/device.h>
12 #include <linux/init.h>
14 #include <asm/hardware.h>
15 #include <asm/mach-types.h>
16 #include <asm/irq.h>
17 #include <asm/arch/jornada56x.h>
18 #include "sa1100_generic.h"
20 #define SOCKET0_POWER GPIO_GPIO7
21 static struct pcmcia_irqs irqs[] = {
22 { 1, IRQ_JORNADA_CF_REMOVE, "Jornada56x CF Remove" },
23 { 1, IRQ_JORNADA_CF_INSERT, "Jornada56x CF Insert" },
24 { 1, IRQ_JORNADA_CF_STSCHG, "Jornada56x CF Status" },
25 { 1, IRQ_JORNADA_CF_WAIT_ERR, "Jornada56x CF Wait err" },
28 static int jornada56x_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
30 JORNADA_GPDPDR |= SOCKET0_POWER;
31 JORNADA_GPDPSR = SOCKET0_POWER;
33 skt->irq = IRQ_JORNADA_CF;
35 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
38 static void jornada56x_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
40 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
43 static void jornada56x_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
45 unsigned long status = JORNADA_CFSR;
47 state->detect=(status & JORNADA_CF_VALID)?1:0;
48 state->ready=(status & JORNADA_CF_READY)?1:0;
49 state->bvd1=(status & JORNADA_CF_BVD1)?1:0;
50 state->bvd2=(status & JORNADA_CF_BVD2)?1:0;
51 state->wrprot=(status & JORNADA_CF_WP)?1:0;
52 state->vs_3v=(status & JORNADA_CF_VS1)?0:1;
53 state->vs_Xv=(status & JORNADA_CF_VS2)?0:2;
56 static int jornada56x_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
58 switch (state->Vcc) {
59 case 0:
60 JORNADA_GPDPSR = SOCKET0_POWER;
61 break;
62 case 33:
63 JORNADA_GPDPCR = SOCKET0_POWER;
64 JORNADA_CFCR = JORNADA_CF_PWAIT_EN | JORNADA_CF_FLT;
65 break;
66 default:
67 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, state->Vcc);
68 return -1;
70 if (state->flags & SS_RESET) {
71 JORNADA_CFCR |= JORNADA_CF_RESET;
73 else {
74 JORNADA_CFCR &= ~JORNADA_CF_RESET;
76 return 0;
79 static void jornada56x_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
81 JORNADA_GPDPSR = SOCKET0_POWER;
82 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
85 static void jornada56x_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
87 JORNADA_GPDPSR = SOCKET0_POWER;
88 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
91 static struct pcmcia_low_level jornada56x_pcmcia_ops = {
92 .owner = THIS_MODULE,
93 .hw_init = jornada56x_pcmcia_hw_init,
94 .hw_shutdown = jornada56x_pcmcia_hw_shutdown,
95 .socket_state = jornada56x_pcmcia_socket_state,
96 .configure_socket = jornada56x_pcmcia_configure_socket,
97 .socket_init = jornada56x_pcmcia_socket_init,
98 .socket_suspend = jornada56x_pcmcia_socket_suspend,
101 int __init pcmcia_jornada56x_init(struct device *dev)
103 int ret = -ENODEV;
105 if (machine_is_jornada56x())
106 ret = sa11xx_drv_pcmcia_probe(dev, &jornada56x_pcmcia_ops, 0, 1);
108 return ret;