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.
9 * Contributions after 2012-01-13 are licensed under the terms of the
10 * GNU GPL, version 2 or (at your option) any later version.
18 struct PXA2xxPCMCIAState
{
20 PCMCIACardState
*card
;
21 MemoryRegion common_iomem
;
22 MemoryRegion attr_iomem
;
29 static uint64_t pxa2xx_pcmcia_common_read(void *opaque
,
30 hwaddr offset
, unsigned size
)
32 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
34 if (s
->slot
.attached
) {
35 return s
->card
->common_read(s
->card
->state
, offset
);
41 static void pxa2xx_pcmcia_common_write(void *opaque
, hwaddr offset
,
42 uint64_t value
, unsigned size
)
44 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
46 if (s
->slot
.attached
) {
47 s
->card
->common_write(s
->card
->state
, offset
, value
);
51 static uint64_t pxa2xx_pcmcia_attr_read(void *opaque
,
52 hwaddr offset
, unsigned size
)
54 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
56 if (s
->slot
.attached
) {
57 return s
->card
->attr_read(s
->card
->state
, offset
);
63 static void pxa2xx_pcmcia_attr_write(void *opaque
, hwaddr offset
,
64 uint64_t value
, unsigned size
)
66 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
68 if (s
->slot
.attached
) {
69 s
->card
->attr_write(s
->card
->state
, offset
, value
);
73 static uint64_t pxa2xx_pcmcia_io_read(void *opaque
,
74 hwaddr offset
, unsigned size
)
76 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
78 if (s
->slot
.attached
) {
79 return s
->card
->io_read(s
->card
->state
, offset
);
85 static void pxa2xx_pcmcia_io_write(void *opaque
, hwaddr offset
,
86 uint64_t value
, unsigned size
)
88 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
90 if (s
->slot
.attached
) {
91 s
->card
->io_write(s
->card
->state
, offset
, value
);
95 static const MemoryRegionOps pxa2xx_pcmcia_common_ops
= {
96 .read
= pxa2xx_pcmcia_common_read
,
97 .write
= pxa2xx_pcmcia_common_write
,
98 .endianness
= DEVICE_NATIVE_ENDIAN
101 static const MemoryRegionOps pxa2xx_pcmcia_attr_ops
= {
102 .read
= pxa2xx_pcmcia_attr_read
,
103 .write
= pxa2xx_pcmcia_attr_write
,
104 .endianness
= DEVICE_NATIVE_ENDIAN
107 static const MemoryRegionOps pxa2xx_pcmcia_io_ops
= {
108 .read
= pxa2xx_pcmcia_io_read
,
109 .write
= pxa2xx_pcmcia_io_write
,
110 .endianness
= DEVICE_NATIVE_ENDIAN
113 static void pxa2xx_pcmcia_set_irq(void *opaque
, int line
, int level
)
115 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
119 qemu_set_irq(s
->irq
, level
);
122 PXA2xxPCMCIAState
*pxa2xx_pcmcia_init(MemoryRegion
*sysmem
,
125 PXA2xxPCMCIAState
*s
;
127 s
= (PXA2xxPCMCIAState
*)
128 g_malloc0(sizeof(PXA2xxPCMCIAState
));
130 /* Socket I/O Memory Space */
131 memory_region_init_io(&s
->iomem
, &pxa2xx_pcmcia_io_ops
, s
,
132 "pxa2xx-pcmcia-io", 0x04000000);
133 memory_region_add_subregion(sysmem
, base
| 0x00000000,
136 /* Then next 64 MB is reserved */
138 /* Socket Attribute Memory Space */
139 memory_region_init_io(&s
->attr_iomem
, &pxa2xx_pcmcia_attr_ops
, s
,
140 "pxa2xx-pcmcia-attribute", 0x04000000);
141 memory_region_add_subregion(sysmem
, base
| 0x08000000,
144 /* Socket Common Memory Space */
145 memory_region_init_io(&s
->common_iomem
, &pxa2xx_pcmcia_common_ops
, s
,
146 "pxa2xx-pcmcia-common", 0x04000000);
147 memory_region_add_subregion(sysmem
, base
| 0x0c000000,
150 if (base
== 0x30000000)
151 s
->slot
.slot_string
= "PXA PC Card Socket 1";
153 s
->slot
.slot_string
= "PXA PC Card Socket 0";
154 s
->slot
.irq
= qemu_allocate_irqs(pxa2xx_pcmcia_set_irq
, s
, 1)[0];
155 pcmcia_socket_register(&s
->slot
);
160 /* Insert a new card into a slot */
161 int pxa2xx_pcmcia_attach(void *opaque
, PCMCIACardState
*card
)
163 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
164 if (s
->slot
.attached
)
168 qemu_irq_raise(s
->cd_irq
);
173 s
->slot
.attached
= 1;
174 s
->card
->slot
= &s
->slot
;
175 s
->card
->attach(s
->card
->state
);
180 /* Eject card from the slot */
181 int pxa2xx_pcmcia_dettach(void *opaque
)
183 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
184 if (!s
->slot
.attached
)
187 s
->card
->detach(s
->card
->state
);
188 s
->card
->slot
= NULL
;
191 s
->slot
.attached
= 0;
194 qemu_irq_lower(s
->irq
);
196 qemu_irq_lower(s
->cd_irq
);
201 /* Who to notify on card events */
202 void pxa2xx_pcmcia_set_irq_cb(void *opaque
, qemu_irq irq
, qemu_irq cd_irq
)
204 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;