Statistics
| Branch: | Revision:

root / hw / pxa2xx_pcmcia.c @ b2d4d832

History | View | Annotate | Download (5.2 kB)

1 a171fe39 balrog
/*
2 a171fe39 balrog
 * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
3 a171fe39 balrog
 *
4 a171fe39 balrog
 * Copyright (c) 2006 Openedhand Ltd.
5 a171fe39 balrog
 * Written by Andrzej Zaborowski <balrog@zabor.org>
6 a171fe39 balrog
 *
7 a171fe39 balrog
 * This code is licensed under the GPLv2.
8 a171fe39 balrog
 */
9 a171fe39 balrog
10 87ecb68b pbrook
#include "hw.h"
11 87ecb68b pbrook
#include "pcmcia.h"
12 9596ebb7 pbrook
#include "pxa.h"
13 a171fe39 balrog
14 bc24a225 Paul Brook
struct PXA2xxPCMCIAState {
15 bc24a225 Paul Brook
    PCMCIASocket slot;
16 bc24a225 Paul Brook
    PCMCIACardState *card;
17 a171fe39 balrog
18 a171fe39 balrog
    qemu_irq irq;
19 a171fe39 balrog
    qemu_irq cd_irq;
20 a171fe39 balrog
};
21 a171fe39 balrog
22 a171fe39 balrog
static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
23 c227f099 Anthony Liguori
                target_phys_addr_t offset)
24 a171fe39 balrog
{
25 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
26 a171fe39 balrog
27 a171fe39 balrog
    if (s->slot.attached) {
28 a171fe39 balrog
        return s->card->common_read(s->card->state, offset);
29 a171fe39 balrog
    }
30 a171fe39 balrog
31 a171fe39 balrog
    return 0;
32 a171fe39 balrog
}
33 a171fe39 balrog
34 a171fe39 balrog
static void pxa2xx_pcmcia_common_write(void *opaque,
35 c227f099 Anthony Liguori
                target_phys_addr_t offset, uint32_t value)
36 a171fe39 balrog
{
37 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
38 a171fe39 balrog
39 a171fe39 balrog
    if (s->slot.attached) {
40 a171fe39 balrog
        s->card->common_write(s->card->state, offset, value);
41 a171fe39 balrog
    }
42 a171fe39 balrog
}
43 a171fe39 balrog
44 a171fe39 balrog
static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
45 c227f099 Anthony Liguori
                target_phys_addr_t offset)
46 a171fe39 balrog
{
47 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
48 a171fe39 balrog
49 a171fe39 balrog
    if (s->slot.attached) {
50 a171fe39 balrog
        return s->card->attr_read(s->card->state, offset);
51 a171fe39 balrog
    }
52 a171fe39 balrog
53 a171fe39 balrog
    return 0;
54 a171fe39 balrog
}
55 a171fe39 balrog
56 a171fe39 balrog
static void pxa2xx_pcmcia_attr_write(void *opaque,
57 c227f099 Anthony Liguori
                target_phys_addr_t offset, uint32_t value)
58 a171fe39 balrog
{
59 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
60 a171fe39 balrog
61 a171fe39 balrog
    if (s->slot.attached) {
62 a171fe39 balrog
        s->card->attr_write(s->card->state, offset, value);
63 a171fe39 balrog
    }
64 a171fe39 balrog
}
65 a171fe39 balrog
66 a171fe39 balrog
static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
67 c227f099 Anthony Liguori
                target_phys_addr_t offset)
68 a171fe39 balrog
{
69 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
70 a171fe39 balrog
71 a171fe39 balrog
    if (s->slot.attached) {
72 a171fe39 balrog
        return s->card->io_read(s->card->state, offset);
73 a171fe39 balrog
    }
74 a171fe39 balrog
75 a171fe39 balrog
    return 0;
76 a171fe39 balrog
}
77 a171fe39 balrog
78 a171fe39 balrog
static void pxa2xx_pcmcia_io_write(void *opaque,
79 c227f099 Anthony Liguori
                target_phys_addr_t offset, uint32_t value)
80 a171fe39 balrog
{
81 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
82 a171fe39 balrog
83 a171fe39 balrog
    if (s->slot.attached) {
84 a171fe39 balrog
        s->card->io_write(s->card->state, offset, value);
85 a171fe39 balrog
    }
86 a171fe39 balrog
}
87 a171fe39 balrog
88 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const pxa2xx_pcmcia_common_readfn[] = {
89 a171fe39 balrog
    pxa2xx_pcmcia_common_read,
90 a171fe39 balrog
    pxa2xx_pcmcia_common_read,
91 a171fe39 balrog
    pxa2xx_pcmcia_common_read,
92 a171fe39 balrog
};
93 a171fe39 balrog
94 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_common_writefn[] = {
95 a171fe39 balrog
    pxa2xx_pcmcia_common_write,
96 a171fe39 balrog
    pxa2xx_pcmcia_common_write,
97 a171fe39 balrog
    pxa2xx_pcmcia_common_write,
98 a171fe39 balrog
};
99 a171fe39 balrog
100 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const pxa2xx_pcmcia_attr_readfn[] = {
101 a171fe39 balrog
    pxa2xx_pcmcia_attr_read,
102 a171fe39 balrog
    pxa2xx_pcmcia_attr_read,
103 a171fe39 balrog
    pxa2xx_pcmcia_attr_read,
104 a171fe39 balrog
};
105 a171fe39 balrog
106 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_attr_writefn[] = {
107 a171fe39 balrog
    pxa2xx_pcmcia_attr_write,
108 a171fe39 balrog
    pxa2xx_pcmcia_attr_write,
109 a171fe39 balrog
    pxa2xx_pcmcia_attr_write,
110 a171fe39 balrog
};
111 a171fe39 balrog
112 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const pxa2xx_pcmcia_io_readfn[] = {
113 a171fe39 balrog
    pxa2xx_pcmcia_io_read,
114 a171fe39 balrog
    pxa2xx_pcmcia_io_read,
115 a171fe39 balrog
    pxa2xx_pcmcia_io_read,
116 a171fe39 balrog
};
117 a171fe39 balrog
118 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_io_writefn[] = {
119 a171fe39 balrog
    pxa2xx_pcmcia_io_write,
120 a171fe39 balrog
    pxa2xx_pcmcia_io_write,
121 a171fe39 balrog
    pxa2xx_pcmcia_io_write,
122 a171fe39 balrog
};
123 a171fe39 balrog
124 a171fe39 balrog
static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
125 a171fe39 balrog
{
126 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
127 a171fe39 balrog
    if (!s->irq)
128 a171fe39 balrog
        return;
129 a171fe39 balrog
130 a171fe39 balrog
    qemu_set_irq(s->irq, level);
131 a171fe39 balrog
}
132 a171fe39 balrog
133 c227f099 Anthony Liguori
PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base)
134 a171fe39 balrog
{
135 a171fe39 balrog
    int iomemtype;
136 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s;
137 a171fe39 balrog
138 bc24a225 Paul Brook
    s = (PXA2xxPCMCIAState *)
139 bc24a225 Paul Brook
            qemu_mallocz(sizeof(PXA2xxPCMCIAState));
140 a171fe39 balrog
141 a171fe39 balrog
    /* Socket I/O Memory Space */
142 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
143 a171fe39 balrog
                    pxa2xx_pcmcia_io_writefn, s);
144 8da3ff18 pbrook
    cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);
145 a171fe39 balrog
146 a171fe39 balrog
    /* Then next 64 MB is reserved */
147 a171fe39 balrog
148 a171fe39 balrog
    /* Socket Attribute Memory Space */
149 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_attr_readfn,
150 a171fe39 balrog
                    pxa2xx_pcmcia_attr_writefn, s);
151 8da3ff18 pbrook
    cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
152 a171fe39 balrog
153 a171fe39 balrog
    /* Socket Common Memory Space */
154 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_common_readfn,
155 a171fe39 balrog
                    pxa2xx_pcmcia_common_writefn, s);
156 8da3ff18 pbrook
    cpu_register_physical_memory(base | 0x0c000000, 0x04000000, iomemtype);
157 a171fe39 balrog
158 a171fe39 balrog
    if (base == 0x30000000)
159 a171fe39 balrog
        s->slot.slot_string = "PXA PC Card Socket 1";
160 a171fe39 balrog
    else
161 a171fe39 balrog
        s->slot.slot_string = "PXA PC Card Socket 0";
162 a171fe39 balrog
    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
163 a171fe39 balrog
    pcmcia_socket_register(&s->slot);
164 3f582262 balrog
165 a171fe39 balrog
    return s;
166 a171fe39 balrog
}
167 a171fe39 balrog
168 a171fe39 balrog
/* Insert a new card into a slot */
169 bc24a225 Paul Brook
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
170 a171fe39 balrog
{
171 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
172 a171fe39 balrog
    if (s->slot.attached)
173 a171fe39 balrog
        return -EEXIST;
174 a171fe39 balrog
175 a171fe39 balrog
    if (s->cd_irq) {
176 a171fe39 balrog
        qemu_irq_raise(s->cd_irq);
177 a171fe39 balrog
    }
178 a171fe39 balrog
179 a171fe39 balrog
    s->card = card;
180 a171fe39 balrog
181 a171fe39 balrog
    s->slot.attached = 1;
182 a171fe39 balrog
    s->card->slot = &s->slot;
183 a171fe39 balrog
    s->card->attach(s->card->state);
184 a171fe39 balrog
185 a171fe39 balrog
    return 0;
186 a171fe39 balrog
}
187 a171fe39 balrog
188 a171fe39 balrog
/* Eject card from the slot */
189 a171fe39 balrog
int pxa2xx_pcmcia_dettach(void *opaque)
190 a171fe39 balrog
{
191 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
192 a171fe39 balrog
    if (!s->slot.attached)
193 a171fe39 balrog
        return -ENOENT;
194 a171fe39 balrog
195 a171fe39 balrog
    s->card->detach(s->card->state);
196 b9d38e95 Blue Swirl
    s->card->slot = NULL;
197 b9d38e95 Blue Swirl
    s->card = NULL;
198 a171fe39 balrog
199 a171fe39 balrog
    s->slot.attached = 0;
200 a171fe39 balrog
201 a171fe39 balrog
    if (s->irq)
202 a171fe39 balrog
        qemu_irq_lower(s->irq);
203 a171fe39 balrog
    if (s->cd_irq)
204 a171fe39 balrog
        qemu_irq_lower(s->cd_irq);
205 a171fe39 balrog
206 a171fe39 balrog
    return 0;
207 a171fe39 balrog
}
208 a171fe39 balrog
209 a171fe39 balrog
/* Who to notify on card events */
210 a171fe39 balrog
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
211 a171fe39 balrog
{
212 bc24a225 Paul Brook
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
213 a171fe39 balrog
    s->irq = irq;
214 a171fe39 balrog
    s->cd_irq = cd_irq;
215 a171fe39 balrog
}