shpcmcia.c revision 1.4 1 /* $NetBSD: shpcmcia.c,v 1.4 2012/10/27 17:17:51 chs Exp $ */
2
3 /*-
4 * Copyright (C) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: shpcmcia.c,v 1.4 2012/10/27 17:17:51 chs Exp $");
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/device.h>
35 #include <sys/malloc.h>
36 #include <sys/kthread.h>
37 #include <sys/kernel.h>
38 #include <sys/callout.h>
39 #include <sys/bus.h>
40 #include <sys/intr.h>
41
42 #include <dev/pcmcia/pcmciachip.h>
43 #include <dev/pcmcia/pcmciavar.h>
44
45 #include <machine/autoconf.h>
46
47 #include <sh3/devreg.h>
48 #include <sh3/bscreg.h>
49 #include <sh3/pfcreg.h>
50
51 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4reg.h>
52 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4var.h>
53
54 #ifdef SHPCMCIA_DEBUG
55 #define DPRINTF(s) printf s
56 #else
57 #define DPRINTF(s)
58 #endif
59
60 static int shpcmcia_chip_mem_alloc(pcmcia_chipset_handle_t,
61 bus_size_t, struct pcmcia_mem_handle *);
62 static void shpcmcia_chip_mem_free(pcmcia_chipset_handle_t,
63 struct pcmcia_mem_handle *);
64 static int shpcmcia_chip_mem_map(pcmcia_chipset_handle_t, int,
65 bus_addr_t, bus_size_t, struct pcmcia_mem_handle *,
66 bus_size_t *, int *);
67 static void shpcmcia_chip_mem_unmap(pcmcia_chipset_handle_t, int);
68 static int shpcmcia_chip_io_alloc(pcmcia_chipset_handle_t,
69 bus_addr_t, bus_size_t, bus_size_t,
70 struct pcmcia_io_handle *);
71 static void shpcmcia_chip_io_free(pcmcia_chipset_handle_t,
72 struct pcmcia_io_handle *);
73 static int shpcmcia_chip_io_map(pcmcia_chipset_handle_t, int,
74 bus_addr_t, bus_size_t, struct pcmcia_io_handle *, int *);
75 static void shpcmcia_chip_io_unmap(pcmcia_chipset_handle_t, int);
76 static void *shpcmcia_chip_intr_establish(pcmcia_chipset_handle_t,
77 struct pcmcia_function *, int, int (*)(void *), void *);
78 static void shpcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t,
79 void *);
80 static void shpcmcia_chip_socket_enable(pcmcia_chipset_handle_t);
81 static void shpcmcia_chip_socket_disable(pcmcia_chipset_handle_t);
82 static void shpcmcia_chip_socket_settype(pcmcia_chipset_handle_t,
83 int);
84
85 static struct pcmcia_chip_functions shpcmcia_chip_functions = {
86 /* memory space allocation */
87 .mem_alloc = shpcmcia_chip_mem_alloc,
88 .mem_free = shpcmcia_chip_mem_free,
89
90 /* memory space window mapping */
91 .mem_map = shpcmcia_chip_mem_map,
92 .mem_unmap = shpcmcia_chip_mem_unmap,
93
94 /* I/O space allocation */
95 .io_alloc = shpcmcia_chip_io_alloc,
96 .io_free = shpcmcia_chip_io_free,
97
98 /* I/O space window mapping */
99 .io_map = shpcmcia_chip_io_map,
100 .io_unmap = shpcmcia_chip_io_unmap,
101
102 /* interrupt glue */
103 .intr_establish = shpcmcia_chip_intr_establish,
104 .intr_disestablish = shpcmcia_chip_intr_disestablish,
105
106 /* card enable/disable */
107 .socket_enable = shpcmcia_chip_socket_enable,
108 .socket_disable = shpcmcia_chip_socket_disable,
109 .socket_settype = shpcmcia_chip_socket_settype,
110
111 /* card detection */
112 .card_detect = NULL,
113 };
114
115 /*
116 * event thread
117 */
118 struct shpcmcia_event {
119 SIMPLEQ_ENTRY(shpcmcia_event) pe_q;
120 int pe_type;
121 };
122
123 /* pe_type */
124 #define SHPCMCIA_EVENT_INSERT 0
125 #define SHPCMCIA_EVENT_REMOVE 1
126
127 struct shpcmcia_softc;
128 struct shpcmcia_handle {
129 struct shpcmcia_softc *sc;
130
131 int flags;
132 #define SHPCMCIA_FLAG_SOCKETP 0x0001
133 #define SHPCMCIA_FLAG_CARDP 0x0002
134 int laststate;
135 #define SHPCMCIA_LASTSTATE_EMPTY 0x0000
136 #define SHPCMCIA_LASTSTATE_PRESENT 0x0002
137
138
139 int memalloc;
140 struct {
141 bus_addr_t addr;
142 bus_size_t size;
143 long offset;
144 int kind;
145 #define SHPCMCIA_MEM_WINS 5
146 } mem[SHPCMCIA_MEM_WINS];
147
148 int ioalloc;
149 struct {
150 bus_addr_t addr;
151 bus_size_t size;
152 int width;
153 #define SHPCMCIA_IO_WINS 2
154 } io[SHPCMCIA_IO_WINS];
155
156 device_t pcmcia;
157
158 int shutdown;
159 lwp_t *event_thread;
160 SIMPLEQ_HEAD(, shpcmcia_event) events;
161 };
162
163 struct shpcmcia_softc {
164 device_t sc_dev;
165
166 bus_space_tag_t sc_iot;
167 bus_space_handle_t sc_ioh;
168 bus_space_tag_t sc_memt;
169 bus_space_handle_t sc_memh;
170 bus_space_tag_t sc_attt;
171 bus_space_handle_t sc_atth;
172
173 pcmcia_chipset_tag_t sc_pct;
174
175 void *sc_ih;
176 #if 0
177 void *sc_detect_ih;
178 #else
179 callout_t sc_detect_ch;
180 #endif
181
182 bus_addr_t sc_membase;
183 #define SHPCMCIA_MAX_MEM_PAGES (8 * sizeof(int))
184
185 bus_addr_t sc_iobase;
186 bus_size_t sc_iosize;
187
188 #define SHPCMCIA_NSLOTS 1
189 struct shpcmcia_handle sc_handle[SHPCMCIA_NSLOTS];
190 };
191
192 static int shpcmcia_probe(device_t, cfdata_t, void *);
193 static void shpcmcia_attach(device_t, device_t, void *);
194 static int shpcmcia_print(void *, const char *);
195
196 CFATTACH_DECL_NEW(shpcmcia, sizeof(struct shpcmcia_softc),
197 shpcmcia_probe, shpcmcia_attach, NULL, NULL);
198
199 #if 0
200 static int shpcmcia_card_detect_intr(void *arg);
201 #else
202 static void shpcmcia_card_detect_poll(void *arg);
203 #endif
204
205 static void shpcmcia_init_socket(struct shpcmcia_handle *);
206 static void shpcmcia_attach_socket(struct shpcmcia_handle *);
207 static void shpcmcia_attach_sockets(struct shpcmcia_softc *);
208
209 static void shpcmcia_event_thread(void *);
210 static void shpcmcia_queue_event(struct shpcmcia_handle *, int);
211
212 static void shpcmcia_attach_card(struct shpcmcia_handle *);
213 static void shpcmcia_detach_card(struct shpcmcia_handle *, int );
214 static void shpcmcia_deactivate_card(struct shpcmcia_handle *);
215
216 static int
217 shpcmcia_probe(device_t parent, cfdata_t cfp, void *aux)
218 {
219 struct mainbus_attach_args *maa = aux;
220
221 if (strcmp(maa->ma_name, "shpcmcia") != 0)
222 return 0;
223 return 1;
224 }
225
226 static void
227 shpcmcia_attach(device_t parent, device_t self, void *aux)
228 {
229 struct shpcmcia_softc *sc = device_private(self);
230 #if 0
231 uint32_t reg;
232 #endif
233
234 sc->sc_dev = self;
235
236 aprint_naive("\n");
237 aprint_normal("\n");
238
239 #if 0
240 /* setup bus controller */
241 /* max wait */
242 reg = _reg_read_4(SH4_WCR1);
243 reg |= 0x00700000;
244 _reg_write_4(SH4_WCR1, reg);
245 reg = _reg_read_4(SH4_WCR2);
246 reg |= 0xfff00000;
247 _reg_write_4(SH4_WCR2, reg);
248 reg = _reg_read_4(SH4_WCR3);
249 reg |= 0x07700000;
250 _reg_write_4(SH4_WCR3, reg);
251 reg = _reg_read_4(SH4_PCR);
252 reg |= 0xffffffff;
253 _reg_write_4(SH4_PCR, reg);
254 #endif
255
256 sc->sc_pct = (pcmcia_chipset_tag_t)&shpcmcia_chip_functions;
257 sc->sc_iot = &ap_ms104_sh4_bus_io;
258 sc->sc_memt = &ap_ms104_sh4_bus_mem;
259 sc->sc_attt = &ap_ms104_sh4_bus_att;
260
261 if (bus_space_map(sc->sc_attt, 0x14000000, 4 * 1024, 0, &sc->sc_atth))
262 panic("%s: couldn't map attribute\n", device_xname(sc->sc_dev));
263 if (bus_space_map(sc->sc_iot, 0x15000000, 64 * 1024, 0,
264 &sc->sc_ioh))
265 panic("%s: couldn't map io memory\n", device_xname(sc->sc_dev));
266 if (bus_space_map(sc->sc_memt, 0x16000000, 32 * 1024 * 1024, 0,
267 &sc->sc_memh))
268 panic("%s: couldn't map memory\n", device_xname(sc->sc_dev));
269
270 sc->sc_iobase = sc->sc_ioh;
271 sc->sc_iosize = 64 * 1024;
272 sc->sc_membase = sc->sc_memh;
273
274 sc->sc_handle[0].sc = sc;
275 sc->sc_handle[0].flags = SHPCMCIA_FLAG_SOCKETP;
276 sc->sc_handle[0].laststate = SHPCMCIA_LASTSTATE_EMPTY;
277 SIMPLEQ_INIT(&sc->sc_handle[0].events);
278
279 #if 0
280 sc->sc_detect_ih = gpio_intr_establish(GPIO_PIN_CARD_CD,
281 shpcmcia_card_detect_intr, sc);
282 if (sc->sc_detect_ih == NULL) {
283 aprint_error_dev(self, "couldn't establish detect interrupt\n");
284 }
285 #else
286 callout_init(&sc->sc_detect_ch, 0);
287 callout_reset(&sc->sc_detect_ch, hz, shpcmcia_card_detect_poll, sc);
288 #endif
289
290 shpcmcia_attach_sockets(sc);
291 }
292
293 static void
294 shpcmcia_attach_sockets(struct shpcmcia_softc *sc)
295 {
296
297 shpcmcia_attach_socket(&sc->sc_handle[0]);
298 }
299
300 static void
301 shpcmcia_attach_socket(struct shpcmcia_handle *h)
302 {
303 struct pcmciabus_attach_args paa;
304
305 /* initialize the rest of the handle */
306 h->shutdown = 0;
307 h->memalloc = 0;
308 h->ioalloc = 0;
309
310 /* now, config one pcmcia device per socket */
311 paa.paa_busname = "pcmcia";
312 paa.pct = (pcmcia_chipset_tag_t)h->sc->sc_pct;
313 paa.pch = (pcmcia_chipset_handle_t)h;
314
315 h->pcmcia = config_found_ia(h->sc->sc_dev, "pcmciabus", &paa,
316 shpcmcia_print);
317
318 /* if there's actually a pcmcia device attached, initialize the slot */
319 if (h->pcmcia)
320 shpcmcia_init_socket(h);
321 }
322
323 /*ARGSUSED*/
324 static int
325 shpcmcia_print(void *arg, const char *pnp)
326 {
327
328 if (pnp)
329 aprint_normal("pcmcia at %s", pnp);
330 return UNCONF;
331 }
332
333 static void
334 shpcmcia_init_socket(struct shpcmcia_handle *h)
335 {
336 uint16_t reg;
337
338 /*
339 * queue creation of a kernel thread to handle insert/removal events.
340 */
341 #ifdef DIAGNOSTIC
342 if (h->event_thread != NULL)
343 panic("shpcmcia_attach_socket: event thread");
344 #endif
345
346 /* if there's a card there, then attach it. */
347 reg = _reg_read_2(SH4_PDTRA);
348 if (!(reg & (1 << GPIO_PIN_CARD_CD))) {
349 shpcmcia_attach_card(h);
350 h->laststate = SHPCMCIA_LASTSTATE_PRESENT;
351 } else {
352 h->laststate = SHPCMCIA_LASTSTATE_EMPTY;
353 }
354
355 if (kthread_create(PRI_NONE, 0, NULL, shpcmcia_event_thread, h,
356 &h->event_thread, "%s", device_xname(h->sc->sc_dev))) {
357 aprint_error_dev(h->sc->sc_dev,
358 "unable to create event thread\n");
359 panic("shpcmcia_create_event_thread");
360 }
361 }
362
363 /*
364 * event thread
365 */
366 static void
367 shpcmcia_event_thread(void *arg)
368 {
369 struct shpcmcia_handle *h = (struct shpcmcia_handle *)arg;
370 struct shpcmcia_event *pe;
371 int s;
372
373 while (h->shutdown == 0) {
374 s = splhigh();
375 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
376 splx(s);
377 (void) tsleep(&h->events, PWAIT, "waitev", 0);
378 continue;
379 } else {
380 splx(s);
381 /* sleep .25s to be enqueued chatterling interrupts */
382 (void) tsleep((void *)shpcmcia_event_thread,
383 PWAIT, "waitss", hz / 4);
384 }
385 s = splhigh();
386 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
387 splx(s);
388
389 switch (pe->pe_type) {
390 case SHPCMCIA_EVENT_INSERT:
391 s = splhigh();
392 for (;;) {
393 struct shpcmcia_event *pe1, *pe2;
394
395 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
396 break;
397 if (pe1->pe_type != SHPCMCIA_EVENT_REMOVE)
398 break;
399 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
400 break;
401 if (pe2->pe_type == SHPCMCIA_EVENT_INSERT) {
402 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
403 free(pe1, M_TEMP);
404 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
405 free(pe2, M_TEMP);
406 }
407 }
408 splx(s);
409
410 DPRINTF(("%s: insertion event\n",
411 device_xname(h->sc->sc_dev)));
412 shpcmcia_attach_card(h);
413 break;
414
415 case SHPCMCIA_EVENT_REMOVE:
416 s = splhigh();
417 for (;;) {
418 struct shpcmcia_event *pe1, *pe2;
419
420 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
421 break;
422 if (pe1->pe_type != SHPCMCIA_EVENT_INSERT)
423 break;
424 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
425 break;
426 if (pe2->pe_type == SHPCMCIA_EVENT_REMOVE) {
427 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
428 free(pe1, M_TEMP);
429 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
430 free(pe2, M_TEMP);
431 }
432 }
433 splx(s);
434
435 DPRINTF(("%s: removal event\n",
436 device_xname(h->sc->sc_dev)));
437 shpcmcia_detach_card(h, DETACH_FORCE);
438 break;
439
440 default:
441 panic("shpcmcia_event_thread: unknown event %d",
442 pe->pe_type);
443 }
444 free(pe, M_TEMP);
445 }
446
447 h->event_thread = NULL;
448
449 /* In case parent is waiting for us to exit. */
450 wakeup(h->sc);
451
452 kthread_exit(0);
453 }
454
455 static void
456 shpcmcia_queue_event(struct shpcmcia_handle *h, int event)
457 {
458 struct shpcmcia_event *pe;
459 int s;
460
461 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
462 if (pe == NULL)
463 panic("shpcmcia_queue_event: can't allocate event");
464
465 pe->pe_type = event;
466 s = splhigh();
467 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
468 splx(s);
469 wakeup(&h->events);
470 }
471
472 static void
473 shpcmcia_attach_card(struct shpcmcia_handle *h)
474 {
475
476 DPRINTF(("%s\n", __func__));
477
478 if (!(h->flags & SHPCMCIA_FLAG_CARDP)) {
479 /* call the MI attach function */
480 pcmcia_card_attach(h->pcmcia);
481
482 h->flags |= SHPCMCIA_FLAG_CARDP;
483 } else {
484 DPRINTF(("shpcmcia_attach_card: already attached"));
485 }
486 }
487
488 static void
489 shpcmcia_detach_card(struct shpcmcia_handle *h, int flags)
490 {
491
492 DPRINTF(("%s\n", __func__));
493
494 if (h->flags & SHPCMCIA_FLAG_CARDP) {
495 h->flags &= ~SHPCMCIA_FLAG_CARDP;
496
497 /* call the MI detach function */
498 pcmcia_card_detach(h->pcmcia, flags);
499 } else {
500 DPRINTF(("shpcmcia_detach_card: already detached"));
501 }
502 }
503
504 static void
505 shpcmcia_deactivate_card(struct shpcmcia_handle *h)
506 {
507
508 DPRINTF(("%s\n", __func__));
509
510 /* call the MI deactivate function */
511 pcmcia_card_deactivate(h->pcmcia);
512
513 shpcmcia_chip_socket_disable(h);
514 }
515
516 #if 0
517 /*
518 * interrupt
519 */
520 static int
521 shpcmcia_card_detect_intr(void *arg)
522 {
523 struct shpcmcia_softc *sc = (struct shpcmcia_softc *)arg;
524 struct shpcmcia_handle *h = &sc->sc_handle[0];
525 uint16_t reg;
526
527 DPRINTF(("%s\n", __func__));
528
529 reg = _reg_read_2(SH4_PDTRA);
530 if (reg & (1 << GPIO_PIN_CARD_CD)) {
531 /* remove */
532 if (h->laststate == SHPCMCIA_LASTSTATE_PRESENT) {
533 /* Deactivate the card now. */
534 shpcmcia_deactivate_card(h);
535 shpcmcia_queue_event(h, SHPCMCIA_EVENT_REMOVE);
536 }
537 h->laststate = SHPCMCIA_LASTSTATE_EMPTY;
538 } else {
539 /* insert */
540 if (h->laststate != SHPCMCIA_LASTSTATE_PRESENT) {
541 shpcmcia_queue_event(h, SHPCMCIA_EVENT_INSERT);
542 }
543 h->laststate = SHPCMCIA_LASTSTATE_PRESENT;
544 }
545 return 1;
546 }
547 #else
548 /*
549 * card polling
550 */
551 static void
552 shpcmcia_card_detect_poll(void *arg)
553 {
554 struct shpcmcia_softc *sc = (struct shpcmcia_softc *)arg;
555 struct shpcmcia_handle *h = &sc->sc_handle[0];
556 uint16_t reg;
557
558 DPRINTF(("%s\n", __func__));
559
560 reg = _reg_read_2(SH4_PDTRA);
561 if (reg & (1 << GPIO_PIN_CARD_CD)) {
562 /* remove */
563 if (h->laststate == SHPCMCIA_LASTSTATE_PRESENT) {
564 /* Deactivate the card now. */
565 shpcmcia_deactivate_card(h);
566 shpcmcia_queue_event(h, SHPCMCIA_EVENT_REMOVE);
567 }
568 h->laststate = SHPCMCIA_LASTSTATE_EMPTY;
569 } else {
570 /* insert */
571 if (h->laststate != SHPCMCIA_LASTSTATE_PRESENT) {
572 shpcmcia_queue_event(h, SHPCMCIA_EVENT_INSERT);
573 }
574 h->laststate = SHPCMCIA_LASTSTATE_PRESENT;
575 }
576
577 callout_schedule(&sc->sc_detect_ch, hz);
578 }
579 #endif
580
581 /*
582 * pcmcia chip functions
583 */
584 /* Memory space functions. */
585 static int
586 shpcmcia_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size,
587 struct pcmcia_mem_handle *pmhp)
588 {
589 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
590 struct shpcmcia_softc *sc = h->sc;
591
592 DPRINTF(("%s: size=%d\n", __func__, (unsigned)size));
593
594 memset(pmhp, 0, sizeof(*pmhp));
595 pmhp->memt = sc->sc_memt;
596 pmhp->memh = sc->sc_memh;
597 pmhp->addr = 0;
598 pmhp->size = size;
599 pmhp->realsize = size;
600
601 return 0;
602 }
603
604 /*ARGSUSED*/
605 static void
606 shpcmcia_chip_mem_free(pcmcia_chipset_handle_t pch,
607 struct pcmcia_mem_handle *pmhp)
608 {
609
610 DPRINTF(("%s\n", __func__));
611 }
612
613 static int
614 shpcmcia_chip_mem_map(pcmcia_chipset_handle_t pch, int kind,
615 bus_addr_t card_addr, bus_size_t size, struct pcmcia_mem_handle *pmhp,
616 bus_size_t *offsetp, int *windowp)
617 {
618 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
619 struct shpcmcia_softc *sc = h->sc;
620 int win;
621 int i;
622 int s;
623
624 DPRINTF(("%s: kind=%#x, card_addr=%#x, size=%d\n",
625 __func__, kind, (unsigned)card_addr, (unsigned)size));
626
627 s = splbio();
628 win = -1;
629 for (i = 0; i < SHPCMCIA_MEM_WINS; i++) {
630 if ((h->memalloc & (1 << i)) == 0) {
631 win = i;
632 h->memalloc |= (1 << i);
633 break;
634 }
635 }
636 splx(s);
637 if (win == -1)
638 return 1;
639
640 *windowp = win;
641 *offsetp = 0;
642
643 h->mem[win].addr = pmhp->addr;
644 h->mem[win].size = size;
645 h->mem[win].offset = (((long)card_addr) - ((long)pmhp->addr));
646 h->mem[win].kind = kind;
647
648 switch (kind) {
649 case PCMCIA_MEM_ATTR:
650 DPRINTF(("%s:PCMCIA_MEM_ATTR\n",device_xname(sc->sc_dev)));
651 pmhp->memh = sc->sc_atth + card_addr;
652 break;
653
654 default:
655 pmhp->memh = sc->sc_memh + card_addr;
656 break;
657 }
658
659 return 0;
660 }
661
662 /*ARGSUSED*/
663 static void
664 shpcmcia_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window)
665 {
666 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
667 int s;
668
669 DPRINTF(("%s\n", __func__));
670
671 s = splbio();
672 h->memalloc &= ~(1 << window);
673 splx(s);
674 }
675
676 /* I/O space functions. */
677 static int
678 shpcmcia_chip_io_alloc(pcmcia_chipset_handle_t pch,
679 bus_addr_t start, bus_size_t size, bus_size_t align,
680 struct pcmcia_io_handle *pihp)
681 {
682 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
683 struct shpcmcia_softc *sc = h->sc;
684
685 DPRINTF(("%s\n", __func__));
686
687 memset(pihp, 0, sizeof(*pihp));
688 pihp->iot = sc->sc_iot;
689 pihp->ioh = sc->sc_ioh;
690 pihp->addr = start;
691 pihp->size = size;
692 pihp->flags |= PCMCIA_IO_ALLOCATED;
693
694 return 0;
695 }
696
697 /*ARGSUSED*/
698 static void
699 shpcmcia_chip_io_free(pcmcia_chipset_handle_t pch,
700 struct pcmcia_io_handle *pih)
701 {
702
703 DPRINTF(("%s\n", __func__));
704 }
705
706 /*ARGSUSED*/
707 static int
708 shpcmcia_chip_io_map(pcmcia_chipset_handle_t pch, int width,
709 bus_addr_t card_addr, bus_size_t size, struct pcmcia_io_handle *pihp,
710 int *windowp)
711 {
712 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
713 struct shpcmcia_softc *sc = h->sc;
714 bus_addr_t ioaddr = pihp->addr + card_addr;
715 int win;
716 int i;
717 int s;
718
719 DPRINTF(("%s\n", __func__));
720
721 s = splbio();
722 win = -1;
723 for (i = 0; i < SHPCMCIA_IO_WINS; i++) {
724 if ((h->ioalloc & (1 << i)) == 0) {
725 win = i;
726 h->ioalloc |= (1 << i);
727 break;
728 }
729 }
730 splx(s);
731 if (win == -1)
732 return 1;
733
734 *windowp = win;
735
736 /* XXX: IOS16 */
737
738 aprint_normal_dev(sc->sc_dev, "port 0x%0lx", (u_long)ioaddr);
739 if (size > 1)
740 aprint_normal("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
741 aprint_normal("\n");
742
743 h->io[win].addr = ioaddr;
744 h->io[win].size = size;
745 h->io[win].width = width;
746
747 return 0;
748 }
749
750 /*ARGSUSED*/
751 static void
752 shpcmcia_chip_io_unmap(pcmcia_chipset_handle_t pch, int window)
753 {
754 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
755 int s;
756
757 DPRINTF(("%s\n", __func__));
758
759 s = splbio();
760 h->ioalloc &= ~(1 << window);
761 splx(s);
762 }
763
764 /* Interrupt functions. */
765 static void *
766 shpcmcia_chip_intr_establish(pcmcia_chipset_handle_t pch,
767 struct pcmcia_function *pf, int ipl, int (*ih_func)(void *), void *ih_arg)
768 {
769 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
770 struct shpcmcia_softc *sc = h->sc;
771 int s;
772
773 KASSERT(sc->sc_ih == NULL);
774 DPRINTF(("%s\n", __func__));
775
776 s = splhigh();
777 sc->sc_ih = extintr_establish(EXTINTR_INTR_CFIREQ, IST_LEVEL, ipl,
778 ih_func, ih_arg);
779 if (sc->sc_ih == NULL) {
780 aprint_error_dev(sc->sc_dev,
781 "couldn't establish card interrupt\n");
782 }
783 splx(s);
784
785 return sc->sc_ih;
786 }
787
788 static void
789 shpcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *cookie)
790 {
791 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch;
792 struct shpcmcia_softc *sc = h->sc;
793 int s;
794
795 KASSERT(sc->sc_ih != NULL);
796 DPRINTF(("%s\n", __func__));
797
798 s = splhigh();
799 extintr_disestablish(sc->sc_ih);
800 sc->sc_ih = NULL;
801 splx(s);
802 }
803
804 /* Socket functions. */
805 static void
806 shpcmcia_chip_socket_enable(pcmcia_chipset_handle_t pch)
807 {
808 uint16_t reg;
809
810 DPRINTF(("%s\n", __func__));
811
812 /* power on the card */
813 reg = _reg_read_2(SH4_PDTRA);
814 reg &= ~(1 << GPIO_PIN_CARD_PON);
815 _reg_write_2(SH4_PDTRA, reg);
816
817 /* wait for card ready */
818 while (_reg_read_1(EXTINTR_STAT1) & MASK1_INT12)
819 continue;
820
821 /* enable bus buffer */
822 reg = _reg_read_2(SH4_PDTRA);
823 reg &= ~(1 << GPIO_PIN_CARD_ENABLE);
824 _reg_write_2(SH4_PDTRA, reg);
825
826 /* reset the card */
827 reg = _reg_read_2(SH4_PDTRA);
828 reg &= ~(1 << GPIO_PIN_CARD_RESET);
829 _reg_write_2(SH4_PDTRA, reg);
830 delay(100 * 1000);
831 }
832
833 /*ARGSUSED*/
834 static void
835 shpcmcia_chip_socket_disable(pcmcia_chipset_handle_t pch)
836 {
837 uint16_t reg;
838
839 DPRINTF(("%s\n", __func__));
840
841 /* reset the card */
842 reg = _reg_read_2(SH4_PDTRA);
843 reg |= (1 << GPIO_PIN_CARD_RESET);
844 _reg_write_2(SH4_PDTRA, reg);
845
846 /* power off the card */
847 reg = _reg_read_2(SH4_PDTRA);
848 reg |= (1 << GPIO_PIN_CARD_PON);
849 _reg_write_2(SH4_PDTRA, reg);
850
851 /* disable bus buffer */
852 reg = _reg_read_2(SH4_PDTRA);
853 reg |= (1 << GPIO_PIN_CARD_ENABLE);
854 _reg_write_2(SH4_PDTRA, reg);
855 }
856
857 /*ARGSUSED*/
858 static void
859 shpcmcia_chip_socket_settype(pcmcia_chipset_handle_t pch, int type)
860 {
861
862 DPRINTF(("%s\n", __func__));
863 }
864