xref: /netbsd-src/sys/arch/evbsh3/ap_ms104_sh4/shpcmcia.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1 /*	$NetBSD: shpcmcia.c,v 1.7 2021/08/07 16:18:52 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (C) 2009 NONAKA Kimihiro <nonaka@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.7 2021/08/07 16:18:52 thorpej 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/kmem.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
shpcmcia_probe(device_t parent,cfdata_t cfp,void * aux)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
shpcmcia_attach(device_t parent,device_t self,void * aux)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
shpcmcia_attach_sockets(struct shpcmcia_softc * sc)294 shpcmcia_attach_sockets(struct shpcmcia_softc *sc)
295 {
296 
297 	shpcmcia_attach_socket(&sc->sc_handle[0]);
298 }
299 
300 static void
shpcmcia_attach_socket(struct shpcmcia_handle * h)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 =
316 	    config_found(h->sc->sc_dev, &paa, shpcmcia_print, CFARGS_NONE);
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
shpcmcia_print(void * arg,const char * pnp)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
shpcmcia_init_socket(struct shpcmcia_handle * h)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
shpcmcia_event_thread(void * arg)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 					kmem_free(pe1, sizeof(*pe1));
404 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
405 					kmem_free(pe2, sizeof(*pe2));
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 					kmem_free(pe1, sizeof(*pe1));
429 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
430 					kmem_free(pe2, sizeof(*pe2));
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 		kmem_free(pe, sizeof(*pe));
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
shpcmcia_queue_event(struct shpcmcia_handle * h,int event)456 shpcmcia_queue_event(struct shpcmcia_handle *h, int event)
457 {
458 	struct shpcmcia_event *pe;
459 	int s;
460 
461 	pe = kmem_intr_alloc(sizeof(*pe), KM_NOSLEEP);
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
shpcmcia_attach_card(struct shpcmcia_handle * h)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
shpcmcia_detach_card(struct shpcmcia_handle * h,int flags)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
shpcmcia_deactivate_card(struct shpcmcia_handle * h)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
shpcmcia_card_detect_poll(void * arg)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
shpcmcia_chip_mem_alloc(pcmcia_chipset_handle_t pch,bus_size_t size,struct pcmcia_mem_handle * pmhp)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
shpcmcia_chip_mem_free(pcmcia_chipset_handle_t pch,struct pcmcia_mem_handle * pmhp)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
shpcmcia_chip_mem_map(pcmcia_chipset_handle_t pch,int kind,bus_addr_t card_addr,bus_size_t size,struct pcmcia_mem_handle * pmhp,bus_size_t * offsetp,int * windowp)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
shpcmcia_chip_mem_unmap(pcmcia_chipset_handle_t pch,int window)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
shpcmcia_chip_io_alloc(pcmcia_chipset_handle_t pch,bus_addr_t start,bus_size_t size,bus_size_t align,struct pcmcia_io_handle * pihp)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
shpcmcia_chip_io_free(pcmcia_chipset_handle_t pch,struct pcmcia_io_handle * pih)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
shpcmcia_chip_io_map(pcmcia_chipset_handle_t pch,int width,bus_addr_t card_addr,bus_size_t size,struct pcmcia_io_handle * pihp,int * windowp)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
shpcmcia_chip_io_unmap(pcmcia_chipset_handle_t pch,int window)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 *
shpcmcia_chip_intr_establish(pcmcia_chipset_handle_t pch,struct pcmcia_function * pf,int ipl,int (* ih_func)(void *),void * ih_arg)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
shpcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t pch,void * cookie)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
shpcmcia_chip_socket_enable(pcmcia_chipset_handle_t pch)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
shpcmcia_chip_socket_disable(pcmcia_chipset_handle_t pch)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
shpcmcia_chip_socket_settype(pcmcia_chipset_handle_t pch,int type)859 shpcmcia_chip_socket_settype(pcmcia_chipset_handle_t pch, int type)
860 {
861 
862 	DPRINTF(("%s\n", __func__));
863 }
864