Statistics
| Branch: | Revision:

root / hw / pxa2xx_pcmcia.c @ 06adb549

History | View | Annotate | Download (5.7 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 a171fe39 balrog
struct pxa2xx_pcmcia_s {
15 a171fe39 balrog
    struct pcmcia_socket_s slot;
16 a171fe39 balrog
    struct pcmcia_card_s *card;
17 a171fe39 balrog
    target_phys_addr_t common_base;
18 a171fe39 balrog
    target_phys_addr_t attr_base;
19 a171fe39 balrog
    target_phys_addr_t io_base;
20 a171fe39 balrog
21 a171fe39 balrog
    qemu_irq irq;
22 a171fe39 balrog
    qemu_irq cd_irq;
23 a171fe39 balrog
};
24 a171fe39 balrog
25 a171fe39 balrog
static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
26 a171fe39 balrog
                target_phys_addr_t offset)
27 a171fe39 balrog
{
28 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
29 a171fe39 balrog
30 a171fe39 balrog
    if (s->slot.attached) {
31 a171fe39 balrog
        offset -= s->common_base;
32 a171fe39 balrog
        return s->card->common_read(s->card->state, offset);
33 a171fe39 balrog
    }
34 a171fe39 balrog
35 a171fe39 balrog
    return 0;
36 a171fe39 balrog
}
37 a171fe39 balrog
38 a171fe39 balrog
static void pxa2xx_pcmcia_common_write(void *opaque,
39 a171fe39 balrog
                target_phys_addr_t offset, uint32_t value)
40 a171fe39 balrog
{
41 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
42 a171fe39 balrog
43 a171fe39 balrog
    if (s->slot.attached) {
44 a171fe39 balrog
        offset -= s->common_base;
45 a171fe39 balrog
        s->card->common_write(s->card->state, offset, value);
46 a171fe39 balrog
    }
47 a171fe39 balrog
}
48 a171fe39 balrog
49 a171fe39 balrog
static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
50 a171fe39 balrog
                target_phys_addr_t offset)
51 a171fe39 balrog
{
52 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
53 a171fe39 balrog
54 a171fe39 balrog
    if (s->slot.attached) {
55 a171fe39 balrog
        offset -= s->attr_base;
56 a171fe39 balrog
        return s->card->attr_read(s->card->state, offset);
57 a171fe39 balrog
    }
58 a171fe39 balrog
59 a171fe39 balrog
    return 0;
60 a171fe39 balrog
}
61 a171fe39 balrog
62 a171fe39 balrog
static void pxa2xx_pcmcia_attr_write(void *opaque,
63 a171fe39 balrog
                target_phys_addr_t offset, uint32_t value)
64 a171fe39 balrog
{
65 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
66 a171fe39 balrog
67 a171fe39 balrog
    if (s->slot.attached) {
68 a171fe39 balrog
        offset -= s->attr_base;
69 a171fe39 balrog
        s->card->attr_write(s->card->state, offset, value);
70 a171fe39 balrog
    }
71 a171fe39 balrog
}
72 a171fe39 balrog
73 a171fe39 balrog
static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
74 a171fe39 balrog
                target_phys_addr_t offset)
75 a171fe39 balrog
{
76 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
77 a171fe39 balrog
78 a171fe39 balrog
    if (s->slot.attached) {
79 a171fe39 balrog
        offset -= s->io_base;
80 a171fe39 balrog
        return s->card->io_read(s->card->state, offset);
81 a171fe39 balrog
    }
82 a171fe39 balrog
83 a171fe39 balrog
    return 0;
84 a171fe39 balrog
}
85 a171fe39 balrog
86 a171fe39 balrog
static void pxa2xx_pcmcia_io_write(void *opaque,
87 a171fe39 balrog
                target_phys_addr_t offset, uint32_t value)
88 a171fe39 balrog
{
89 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
90 a171fe39 balrog
91 a171fe39 balrog
    if (s->slot.attached) {
92 a171fe39 balrog
        offset -= s->io_base;
93 a171fe39 balrog
        s->card->io_write(s->card->state, offset, value);
94 a171fe39 balrog
    }
95 a171fe39 balrog
}
96 a171fe39 balrog
97 a171fe39 balrog
static CPUReadMemoryFunc *pxa2xx_pcmcia_common_readfn[] = {
98 a171fe39 balrog
    pxa2xx_pcmcia_common_read,
99 a171fe39 balrog
    pxa2xx_pcmcia_common_read,
100 a171fe39 balrog
    pxa2xx_pcmcia_common_read,
101 a171fe39 balrog
};
102 a171fe39 balrog
103 a171fe39 balrog
static CPUWriteMemoryFunc *pxa2xx_pcmcia_common_writefn[] = {
104 a171fe39 balrog
    pxa2xx_pcmcia_common_write,
105 a171fe39 balrog
    pxa2xx_pcmcia_common_write,
106 a171fe39 balrog
    pxa2xx_pcmcia_common_write,
107 a171fe39 balrog
};
108 a171fe39 balrog
109 a171fe39 balrog
static CPUReadMemoryFunc *pxa2xx_pcmcia_attr_readfn[] = {
110 a171fe39 balrog
    pxa2xx_pcmcia_attr_read,
111 a171fe39 balrog
    pxa2xx_pcmcia_attr_read,
112 a171fe39 balrog
    pxa2xx_pcmcia_attr_read,
113 a171fe39 balrog
};
114 a171fe39 balrog
115 a171fe39 balrog
static CPUWriteMemoryFunc *pxa2xx_pcmcia_attr_writefn[] = {
116 a171fe39 balrog
    pxa2xx_pcmcia_attr_write,
117 a171fe39 balrog
    pxa2xx_pcmcia_attr_write,
118 a171fe39 balrog
    pxa2xx_pcmcia_attr_write,
119 a171fe39 balrog
};
120 a171fe39 balrog
121 a171fe39 balrog
static CPUReadMemoryFunc *pxa2xx_pcmcia_io_readfn[] = {
122 a171fe39 balrog
    pxa2xx_pcmcia_io_read,
123 a171fe39 balrog
    pxa2xx_pcmcia_io_read,
124 a171fe39 balrog
    pxa2xx_pcmcia_io_read,
125 a171fe39 balrog
};
126 a171fe39 balrog
127 a171fe39 balrog
static CPUWriteMemoryFunc *pxa2xx_pcmcia_io_writefn[] = {
128 a171fe39 balrog
    pxa2xx_pcmcia_io_write,
129 a171fe39 balrog
    pxa2xx_pcmcia_io_write,
130 a171fe39 balrog
    pxa2xx_pcmcia_io_write,
131 a171fe39 balrog
};
132 a171fe39 balrog
133 a171fe39 balrog
static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
134 a171fe39 balrog
{
135 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
136 a171fe39 balrog
    if (!s->irq)
137 a171fe39 balrog
        return;
138 a171fe39 balrog
139 a171fe39 balrog
    qemu_set_irq(s->irq, level);
140 a171fe39 balrog
}
141 a171fe39 balrog
142 a171fe39 balrog
struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base)
143 a171fe39 balrog
{
144 a171fe39 balrog
    int iomemtype;
145 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s;
146 a171fe39 balrog
147 a171fe39 balrog
    s = (struct pxa2xx_pcmcia_s *)
148 a171fe39 balrog
            qemu_mallocz(sizeof(struct pxa2xx_pcmcia_s));
149 a171fe39 balrog
150 a171fe39 balrog
    /* Socket I/O Memory Space */
151 a171fe39 balrog
    s->io_base = base | 0x00000000;
152 a171fe39 balrog
    iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn,
153 a171fe39 balrog
                    pxa2xx_pcmcia_io_writefn, s);
154 187337f8 pbrook
    cpu_register_physical_memory(s->io_base, 0x04000000, iomemtype);
155 a171fe39 balrog
156 a171fe39 balrog
    /* Then next 64 MB is reserved */
157 a171fe39 balrog
158 a171fe39 balrog
    /* Socket Attribute Memory Space */
159 a171fe39 balrog
    s->attr_base = base | 0x08000000;
160 a171fe39 balrog
    iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn,
161 a171fe39 balrog
                    pxa2xx_pcmcia_attr_writefn, s);
162 187337f8 pbrook
    cpu_register_physical_memory(s->attr_base, 0x04000000, iomemtype);
163 a171fe39 balrog
164 a171fe39 balrog
    /* Socket Common Memory Space */
165 a171fe39 balrog
    s->common_base = base | 0x0c000000;
166 a171fe39 balrog
    iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn,
167 a171fe39 balrog
                    pxa2xx_pcmcia_common_writefn, s);
168 187337f8 pbrook
    cpu_register_physical_memory(s->common_base, 0x04000000, iomemtype);
169 a171fe39 balrog
170 a171fe39 balrog
    if (base == 0x30000000)
171 a171fe39 balrog
        s->slot.slot_string = "PXA PC Card Socket 1";
172 a171fe39 balrog
    else
173 a171fe39 balrog
        s->slot.slot_string = "PXA PC Card Socket 0";
174 a171fe39 balrog
    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
175 a171fe39 balrog
    pcmcia_socket_register(&s->slot);
176 3f582262 balrog
177 a171fe39 balrog
    return s;
178 a171fe39 balrog
}
179 a171fe39 balrog
180 a171fe39 balrog
/* Insert a new card into a slot */
181 a171fe39 balrog
int pxa2xx_pcmcia_attach(void *opaque, struct pcmcia_card_s *card)
182 a171fe39 balrog
{
183 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
184 a171fe39 balrog
    if (s->slot.attached)
185 a171fe39 balrog
        return -EEXIST;
186 a171fe39 balrog
187 a171fe39 balrog
    if (s->cd_irq) {
188 a171fe39 balrog
        qemu_irq_raise(s->cd_irq);
189 a171fe39 balrog
    }
190 a171fe39 balrog
191 a171fe39 balrog
    s->card = card;
192 a171fe39 balrog
193 a171fe39 balrog
    s->slot.attached = 1;
194 a171fe39 balrog
    s->card->slot = &s->slot;
195 a171fe39 balrog
    s->card->attach(s->card->state);
196 a171fe39 balrog
197 a171fe39 balrog
    return 0;
198 a171fe39 balrog
}
199 a171fe39 balrog
200 a171fe39 balrog
/* Eject card from the slot */
201 a171fe39 balrog
int pxa2xx_pcmcia_dettach(void *opaque)
202 a171fe39 balrog
{
203 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
204 a171fe39 balrog
    if (!s->slot.attached)
205 a171fe39 balrog
        return -ENOENT;
206 a171fe39 balrog
207 a171fe39 balrog
    s->card->detach(s->card->state);
208 a171fe39 balrog
    s->card->slot = 0;
209 a171fe39 balrog
    s->card = 0;
210 a171fe39 balrog
211 a171fe39 balrog
    s->slot.attached = 0;
212 a171fe39 balrog
213 a171fe39 balrog
    if (s->irq)
214 a171fe39 balrog
        qemu_irq_lower(s->irq);
215 a171fe39 balrog
    if (s->cd_irq)
216 a171fe39 balrog
        qemu_irq_lower(s->cd_irq);
217 a171fe39 balrog
218 a171fe39 balrog
    return 0;
219 a171fe39 balrog
}
220 a171fe39 balrog
221 a171fe39 balrog
/* Who to notify on card events */
222 a171fe39 balrog
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
223 a171fe39 balrog
{
224 a171fe39 balrog
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
225 a171fe39 balrog
    s->irq = irq;
226 a171fe39 balrog
    s->cd_irq = cd_irq;
227 a171fe39 balrog
}