2 * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
4 * Copyright (c) 2006 Openedhand Ltd.
5 * Written by Andrzej Zaborowski <balrog@zabor.org>
7 * This code is licensed under the GPLv2.
12 struct pxa2xx_pcmcia_s
{
13 struct pcmcia_socket_s slot
;
14 struct pcmcia_card_s
*card
;
15 target_phys_addr_t common_base
;
16 target_phys_addr_t attr_base
;
17 target_phys_addr_t io_base
;
23 static uint32_t pxa2xx_pcmcia_common_read(void *opaque
,
24 target_phys_addr_t offset
)
26 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
28 if (s
->slot
.attached
) {
29 offset
-= s
->common_base
;
30 return s
->card
->common_read(s
->card
->state
, offset
);
36 static void pxa2xx_pcmcia_common_write(void *opaque
,
37 target_phys_addr_t offset
, uint32_t value
)
39 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
41 if (s
->slot
.attached
) {
42 offset
-= s
->common_base
;
43 s
->card
->common_write(s
->card
->state
, offset
, value
);
47 static uint32_t pxa2xx_pcmcia_attr_read(void *opaque
,
48 target_phys_addr_t offset
)
50 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
52 if (s
->slot
.attached
) {
53 offset
-= s
->attr_base
;
54 return s
->card
->attr_read(s
->card
->state
, offset
);
60 static void pxa2xx_pcmcia_attr_write(void *opaque
,
61 target_phys_addr_t offset
, uint32_t value
)
63 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
65 if (s
->slot
.attached
) {
66 offset
-= s
->attr_base
;
67 s
->card
->attr_write(s
->card
->state
, offset
, value
);
71 static uint32_t pxa2xx_pcmcia_io_read(void *opaque
,
72 target_phys_addr_t offset
)
74 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
76 if (s
->slot
.attached
) {
78 return s
->card
->io_read(s
->card
->state
, offset
);
84 static void pxa2xx_pcmcia_io_write(void *opaque
,
85 target_phys_addr_t offset
, uint32_t value
)
87 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
89 if (s
->slot
.attached
) {
91 s
->card
->io_write(s
->card
->state
, offset
, value
);
95 static CPUReadMemoryFunc
*pxa2xx_pcmcia_common_readfn
[] = {
96 pxa2xx_pcmcia_common_read
,
97 pxa2xx_pcmcia_common_read
,
98 pxa2xx_pcmcia_common_read
,
101 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_common_writefn
[] = {
102 pxa2xx_pcmcia_common_write
,
103 pxa2xx_pcmcia_common_write
,
104 pxa2xx_pcmcia_common_write
,
107 static CPUReadMemoryFunc
*pxa2xx_pcmcia_attr_readfn
[] = {
108 pxa2xx_pcmcia_attr_read
,
109 pxa2xx_pcmcia_attr_read
,
110 pxa2xx_pcmcia_attr_read
,
113 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_attr_writefn
[] = {
114 pxa2xx_pcmcia_attr_write
,
115 pxa2xx_pcmcia_attr_write
,
116 pxa2xx_pcmcia_attr_write
,
119 static CPUReadMemoryFunc
*pxa2xx_pcmcia_io_readfn
[] = {
120 pxa2xx_pcmcia_io_read
,
121 pxa2xx_pcmcia_io_read
,
122 pxa2xx_pcmcia_io_read
,
125 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_io_writefn
[] = {
126 pxa2xx_pcmcia_io_write
,
127 pxa2xx_pcmcia_io_write
,
128 pxa2xx_pcmcia_io_write
,
131 static void pxa2xx_pcmcia_set_irq(void *opaque
, int line
, int level
)
133 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
137 qemu_set_irq(s
->irq
, level
);
140 struct pxa2xx_pcmcia_s
*pxa2xx_pcmcia_init(target_phys_addr_t base
)
143 struct pxa2xx_pcmcia_s
*s
;
145 s
= (struct pxa2xx_pcmcia_s
*)
146 qemu_mallocz(sizeof(struct pxa2xx_pcmcia_s
));
148 /* Socket I/O Memory Space */
149 s
->io_base
= base
| 0x00000000;
150 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn
,
151 pxa2xx_pcmcia_io_writefn
, s
);
152 cpu_register_physical_memory(s
->io_base
, 0x04000000, iomemtype
);
154 /* Then next 64 MB is reserved */
156 /* Socket Attribute Memory Space */
157 s
->attr_base
= base
| 0x08000000;
158 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn
,
159 pxa2xx_pcmcia_attr_writefn
, s
);
160 cpu_register_physical_memory(s
->attr_base
, 0x04000000, iomemtype
);
162 /* Socket Common Memory Space */
163 s
->common_base
= base
| 0x0c000000;
164 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn
,
165 pxa2xx_pcmcia_common_writefn
, s
);
166 cpu_register_physical_memory(s
->common_base
, 0x04000000, iomemtype
);
168 if (base
== 0x30000000)
169 s
->slot
.slot_string
= "PXA PC Card Socket 1";
171 s
->slot
.slot_string
= "PXA PC Card Socket 0";
172 s
->slot
.irq
= qemu_allocate_irqs(pxa2xx_pcmcia_set_irq
, s
, 1)[0];
173 pcmcia_socket_register(&s
->slot
);
178 /* Insert a new card into a slot */
179 int pxa2xx_pcmcia_attach(void *opaque
, struct pcmcia_card_s
*card
)
181 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
182 if (s
->slot
.attached
)
186 qemu_irq_raise(s
->cd_irq
);
191 s
->slot
.attached
= 1;
192 s
->card
->slot
= &s
->slot
;
193 s
->card
->attach(s
->card
->state
);
198 /* Eject card from the slot */
199 int pxa2xx_pcmcia_dettach(void *opaque
)
201 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
202 if (!s
->slot
.attached
)
205 s
->card
->detach(s
->card
->state
);
209 s
->slot
.attached
= 0;
212 qemu_irq_lower(s
->irq
);
214 qemu_irq_lower(s
->cd_irq
);
219 /* Who to notify on card events */
220 void pxa2xx_pcmcia_set_irq_cb(void *opaque
, qemu_irq irq
, qemu_irq cd_irq
)
222 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;