Replace tabs by 8 spaces. No code change, by Herve Poussineau.
[qemu/dscho.git] / hw / pxa2xx_pcmcia.c
blobf1399f467fcc4c9c0c4ef89b2eda18466aed1714
1 /*
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.
8 */
10 #include "vl.h"
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;
19 qemu_irq irq;
20 qemu_irq cd_irq;
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);
33 return 0;
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);
57 return 0;
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) {
77 offset -= s->io_base;
78 return s->card->io_read(s->card->state, offset);
81 return 0;
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) {
90 offset -= s->io_base;
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;
134 if (!s->irq)
135 return;
137 qemu_set_irq(s->irq, level);
140 struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base)
142 int iomemtype;
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";
170 else
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);
175 return s;
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)
183 return -EEXIST;
185 if (s->cd_irq) {
186 qemu_irq_raise(s->cd_irq);
189 s->card = card;
191 s->slot.attached = 1;
192 s->card->slot = &s->slot;
193 s->card->attach(s->card->state);
195 return 0;
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)
203 return -ENOENT;
205 s->card->detach(s->card->state);
206 s->card->slot = 0;
207 s->card = 0;
209 s->slot.attached = 0;
211 if (s->irq)
212 qemu_irq_lower(s->irq);
213 if (s->cd_irq)
214 qemu_irq_lower(s->cd_irq);
216 return 0;
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;
223 s->irq = irq;
224 s->cd_irq = cd_irq;