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.
13 struct pxa2xx_pcmcia_s
{
14 struct pcmcia_socket_s slot
;
15 struct pcmcia_card_s
*card
;
16 target_phys_addr_t common_base
;
17 target_phys_addr_t attr_base
;
18 target_phys_addr_t io_base
;
24 static uint32_t pxa2xx_pcmcia_common_read(void *opaque
,
25 target_phys_addr_t offset
)
27 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
29 if (s
->slot
.attached
) {
30 offset
-= s
->common_base
;
31 return s
->card
->common_read(s
->card
->state
, offset
);
37 static void pxa2xx_pcmcia_common_write(void *opaque
,
38 target_phys_addr_t offset
, uint32_t value
)
40 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
42 if (s
->slot
.attached
) {
43 offset
-= s
->common_base
;
44 s
->card
->common_write(s
->card
->state
, offset
, value
);
48 static uint32_t pxa2xx_pcmcia_attr_read(void *opaque
,
49 target_phys_addr_t offset
)
51 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
53 if (s
->slot
.attached
) {
54 offset
-= s
->attr_base
;
55 return s
->card
->attr_read(s
->card
->state
, offset
);
61 static void pxa2xx_pcmcia_attr_write(void *opaque
,
62 target_phys_addr_t offset
, uint32_t value
)
64 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
66 if (s
->slot
.attached
) {
67 offset
-= s
->attr_base
;
68 s
->card
->attr_write(s
->card
->state
, offset
, value
);
72 static uint32_t pxa2xx_pcmcia_io_read(void *opaque
,
73 target_phys_addr_t offset
)
75 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
77 if (s
->slot
.attached
) {
79 return s
->card
->io_read(s
->card
->state
, offset
);
85 static void pxa2xx_pcmcia_io_write(void *opaque
,
86 target_phys_addr_t offset
, uint32_t value
)
88 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
90 if (s
->slot
.attached
) {
92 s
->card
->io_write(s
->card
->state
, offset
, value
);
96 static CPUReadMemoryFunc
*pxa2xx_pcmcia_common_readfn
[] = {
97 pxa2xx_pcmcia_common_read
,
98 pxa2xx_pcmcia_common_read
,
99 pxa2xx_pcmcia_common_read
,
102 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_common_writefn
[] = {
103 pxa2xx_pcmcia_common_write
,
104 pxa2xx_pcmcia_common_write
,
105 pxa2xx_pcmcia_common_write
,
108 static CPUReadMemoryFunc
*pxa2xx_pcmcia_attr_readfn
[] = {
109 pxa2xx_pcmcia_attr_read
,
110 pxa2xx_pcmcia_attr_read
,
111 pxa2xx_pcmcia_attr_read
,
114 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_attr_writefn
[] = {
115 pxa2xx_pcmcia_attr_write
,
116 pxa2xx_pcmcia_attr_write
,
117 pxa2xx_pcmcia_attr_write
,
120 static CPUReadMemoryFunc
*pxa2xx_pcmcia_io_readfn
[] = {
121 pxa2xx_pcmcia_io_read
,
122 pxa2xx_pcmcia_io_read
,
123 pxa2xx_pcmcia_io_read
,
126 static CPUWriteMemoryFunc
*pxa2xx_pcmcia_io_writefn
[] = {
127 pxa2xx_pcmcia_io_write
,
128 pxa2xx_pcmcia_io_write
,
129 pxa2xx_pcmcia_io_write
,
132 static void pxa2xx_pcmcia_set_irq(void *opaque
, int line
, int level
)
134 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
138 qemu_set_irq(s
->irq
, level
);
141 struct pxa2xx_pcmcia_s
*pxa2xx_pcmcia_init(target_phys_addr_t base
)
144 struct pxa2xx_pcmcia_s
*s
;
146 s
= (struct pxa2xx_pcmcia_s
*)
147 qemu_mallocz(sizeof(struct pxa2xx_pcmcia_s
));
149 /* Socket I/O Memory Space */
150 s
->io_base
= base
| 0x00000000;
151 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn
,
152 pxa2xx_pcmcia_io_writefn
, s
);
153 cpu_register_physical_memory(s
->io_base
, 0x04000000, iomemtype
);
155 /* Then next 64 MB is reserved */
157 /* Socket Attribute Memory Space */
158 s
->attr_base
= base
| 0x08000000;
159 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn
,
160 pxa2xx_pcmcia_attr_writefn
, s
);
161 cpu_register_physical_memory(s
->attr_base
, 0x04000000, iomemtype
);
163 /* Socket Common Memory Space */
164 s
->common_base
= base
| 0x0c000000;
165 iomemtype
= cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn
,
166 pxa2xx_pcmcia_common_writefn
, s
);
167 cpu_register_physical_memory(s
->common_base
, 0x04000000, iomemtype
);
169 if (base
== 0x30000000)
170 s
->slot
.slot_string
= "PXA PC Card Socket 1";
172 s
->slot
.slot_string
= "PXA PC Card Socket 0";
173 s
->slot
.irq
= qemu_allocate_irqs(pxa2xx_pcmcia_set_irq
, s
, 1)[0];
174 pcmcia_socket_register(&s
->slot
);
179 /* Insert a new card into a slot */
180 int pxa2xx_pcmcia_attach(void *opaque
, struct pcmcia_card_s
*card
)
182 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
183 if (s
->slot
.attached
)
187 qemu_irq_raise(s
->cd_irq
);
192 s
->slot
.attached
= 1;
193 s
->card
->slot
= &s
->slot
;
194 s
->card
->attach(s
->card
->state
);
199 /* Eject card from the slot */
200 int pxa2xx_pcmcia_dettach(void *opaque
)
202 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;
203 if (!s
->slot
.attached
)
206 s
->card
->detach(s
->card
->state
);
210 s
->slot
.attached
= 0;
213 qemu_irq_lower(s
->irq
);
215 qemu_irq_lower(s
->cd_irq
);
220 /* Who to notify on card events */
221 void pxa2xx_pcmcia_set_irq_cb(void *opaque
, qemu_irq irq
, qemu_irq cd_irq
)
223 struct pxa2xx_pcmcia_s
*s
= (struct pxa2xx_pcmcia_s
*) opaque
;