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.
14 struct pxa2xx_pcmcia_s
{
15 struct pcmcia_socket_s slot
;
16 struct pcmcia_card_s
*card
;
17 target_phys_addr_t common_base
;
18 target_phys_addr_t attr_base
;
19 target_phys_addr_t io_base
;
25 static uint32_t pxa2xx_pcmcia_common_read(void *opaque
,
26 target_phys_addr_t offset
)
28 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
30 if (s
->slot
.attached
) {
31 offset
-= s
->common_base
;
32 return s
->card
->common_read(s
->card
->state
, offset
);
38 static void pxa2xx_pcmcia_common_write(void *opaque
,
39 target_phys_addr_t offset
, uint32_t value
)
41 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
43 if (s
->slot
.attached
) {
44 offset
-= s
->common_base
;
45 s
->card
->common_write(s
->card
->state
, offset
, value
);
49 static uint32_t pxa2xx_pcmcia_attr_read(void *opaque
,
50 target_phys_addr_t offset
)
52 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
54 if (s
->slot
.attached
) {
55 offset
-= s
->attr_base
;
56 return s
->card
->attr_read(s
->card
->state
, offset
);
62 static void pxa2xx_pcmcia_attr_write(void *opaque
,
63 target_phys_addr_t offset
, uint32_t value
)
65 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
67 if (s
->slot
.attached
) {
68 offset
-= s
->attr_base
;
69 s
->card
->attr_write(s
->card
->state
, offset
, value
);
73 static uint32_t pxa2xx_pcmcia_io_read(void *opaque
,
74 target_phys_addr_t offset
)
76 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
78 if (s
->slot
.attached
) {
80 return s
->card
->io_read(s
->card
->state
, offset
);
86 static void pxa2xx_pcmcia_io_write(void *opaque
,
87 target_phys_addr_t offset
, uint32_t value
)
89 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
91 if (s
->slot
.attached
) {
93 s
->card
->io_write(s
->card
->state
, offset
, value
);
97 static CPUReadMemoryFunc
*pxa2xx_pcmcia_common_readfn
[] = {
98 pxa2xx_pcmcia_common_read
,
99 pxa2xx_pcmcia_common_read
,
100 pxa2xx_pcmcia_common_read
,
103 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_common_writefn
[] = {
104 pxa2xx_pcmcia_common_write
,
105 pxa2xx_pcmcia_common_write
,
106 pxa2xx_pcmcia_common_write
,
109 static CPUReadMemoryFunc
*pxa2xx_pcmcia_attr_readfn
[] = {
110 pxa2xx_pcmcia_attr_read
,
111 pxa2xx_pcmcia_attr_read
,
112 pxa2xx_pcmcia_attr_read
,
115 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_attr_writefn
[] = {
116 pxa2xx_pcmcia_attr_write
,
117 pxa2xx_pcmcia_attr_write
,
118 pxa2xx_pcmcia_attr_write
,
121 static CPUReadMemoryFunc
*pxa2xx_pcmcia_io_readfn
[] = {
122 pxa2xx_pcmcia_io_read
,
123 pxa2xx_pcmcia_io_read
,
124 pxa2xx_pcmcia_io_read
,
127 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_io_writefn
[] = {
128 pxa2xx_pcmcia_io_write
,
129 pxa2xx_pcmcia_io_write
,
130 pxa2xx_pcmcia_io_write
,
133 static void pxa2xx_pcmcia_set_irq(void *opaque
, int line
, int level
)
135 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
139 qemu_set_irq(s
->irq
, level
);
142 struct pxa2xx_pcmcia_s
*pxa2xx_pcmcia_init(target_phys_addr_t base
)
145 struct pxa2xx_pcmcia_s
*s
;
147 s
= (struct pxa2xx_pcmcia_s
*)
148 qemu_mallocz(sizeof(struct pxa2xx_pcmcia_s
));
150 /* Socket I/O Memory Space */
151 s
->io_base
= base
| 0x00000000;
152 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn
,
153 pxa2xx_pcmcia_io_writefn
, s
);
154 cpu_register_physical_memory(s
->io_base
, 0x04000000, iomemtype
);
156 /* Then next 64 MB is reserved */
158 /* Socket Attribute Memory Space */
159 s
->attr_base
= base
| 0x08000000;
160 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn
,
161 pxa2xx_pcmcia_attr_writefn
, s
);
162 cpu_register_physical_memory(s
->attr_base
, 0x04000000, iomemtype
);
164 /* Socket Common Memory Space */
165 s
->common_base
= base
| 0x0c000000;
166 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn
,
167 pxa2xx_pcmcia_common_writefn
, s
);
168 cpu_register_physical_memory(s
->common_base
, 0x04000000, iomemtype
);
170 if (base
== 0x30000000)
171 s
->slot
.slot_string
= "PXA PC Card Socket 1";
173 s
->slot
.slot_string
= "PXA PC Card Socket 0";
174 s
->slot
.irq
= qemu_allocate_irqs(pxa2xx_pcmcia_set_irq
, s
, 1)[0];
175 pcmcia_socket_register(&s
->slot
);
180 /* Insert a new card into a slot */
181 int pxa2xx_pcmcia_attach(void *opaque
, struct pcmcia_card_s
*card
)
183 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
184 if (s
->slot
.attached
)
188 qemu_irq_raise(s
->cd_irq
);
193 s
->slot
.attached
= 1;
194 s
->card
->slot
= &s
->slot
;
195 s
->card
->attach(s
->card
->state
);
200 /* Eject card from the slot */
201 int pxa2xx_pcmcia_dettach(void *opaque
)
203 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
204 if (!s
->slot
.attached
)
207 s
->card
->detach(s
->card
->state
);
211 s
->slot
.attached
= 0;
214 qemu_irq_lower(s
->irq
);
216 qemu_irq_lower(s
->cd_irq
);
221 /* Who to notify on card events */
222 void pxa2xx_pcmcia_set_irq_cb(void *opaque
, qemu_irq irq
, qemu_irq cd_irq
)
224 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;