xref: /netbsd-src/sys/arch/evbsh3/ap_ms104_sh4/ap_ms104_sh4.c (revision 2388feef6162e5f55bc0fbaaa9d32d8dfc8354a3)
1 /*	$NetBSD: ap_ms104_sh4.c,v 1.2 2012/01/21 19:44:29 nonaka 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: ap_ms104_sh4.c,v 1.2 2012/01/21 19:44:29 nonaka Exp $");
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/intr.h>
34 
35 #include <sh3/devreg.h>
36 #include <sh3/pfcreg.h>
37 #include <sh3/exception.h>
38 
39 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4reg.h>
40 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4var.h>
41 
42 static int gpio_intr(void *arg);
43 
44 struct gpio_intrhand {
45 	int ih_irq;
46 	int (*ih_func)(void *);
47 	void *ih_arg;
48 } gpio_intr_func_table[16];
49 
50 void
machine_init(void)51 machine_init(void)
52 {
53 
54 	extintr_init();
55 	gpio_intr_init();
56 }
57 
58 void
gpio_intr_init(void)59 gpio_intr_init(void)
60 {
61 	uint32_t reg;
62 
63 	_reg_write_2(SH4_GPIOIC, 0);
64 	_reg_write_2(SH4_PDTRA, 0);
65 	_reg_write_4(SH4_PCTRA, 0);
66 	_reg_write_2(SH4_PDTRB, 0);
67 	_reg_write_4(SH4_PCTRB, 0);
68 
69 	(void) intc_intr_establish(SH4_INTEVT_GPIO, IST_LEVEL, IPL_TTY,
70 	    gpio_intr, NULL);
71 
72 	/* setup for pc-card */
73 	_reg_write_2(SH4_PDTRA, (1 << GPIO_PIN_CARD_PON)
74 	                        | (1 << GPIO_PIN_CARD_RESET)
75 	                        | (1 << GPIO_PIN_CARD_ENABLE)); /* disable */
76 	reg = _reg_read_4(SH4_PCTRA);
77 	reg &= ~(3 << (GPIO_PIN_CARD_CD * 2));		/* input */
78 	reg &= ~(3 << (GPIO_PIN_CARD_PON * 2));
79 	reg |=  (1 << (GPIO_PIN_CARD_PON * 2));		/* output */
80 	reg &= ~(3 << (GPIO_PIN_CARD_RESET * 2));
81 	reg |=  (1 << (GPIO_PIN_CARD_RESET * 2));	/* output */
82 	reg &= ~(3 << (GPIO_PIN_CARD_ENABLE * 2));
83 	reg |=  (1 << (GPIO_PIN_CARD_ENABLE * 2));	/* output */
84 	_reg_write_4(SH4_PCTRA, reg);
85 }
86 
87 void *
gpio_intr_establish(int pin,int (* ih_func)(void *),void * ih_arg)88 gpio_intr_establish(int pin, int (*ih_func)(void *), void *ih_arg)
89 {
90 	uint32_t reg;
91 	int s;
92 
93 	KASSERT(pin >= 0 && pin <= 15);
94 	KASSERT(gpio_intr_func_table[pin].ih_func == NULL);
95 	KASSERT((_reg_read_4(SH4_PCTRA) & (1 << (pin * 2))) == 0); /*input*/
96 
97 	s = splhigh();
98 
99 	/* install interrupt handler */
100 	gpio_intr_func_table[pin].ih_irq = pin;
101 	gpio_intr_func_table[pin].ih_func = ih_func;
102 	gpio_intr_func_table[pin].ih_arg = ih_arg;
103 
104 	/* enable gpio interrupt */
105 	reg = _reg_read_2(SH4_GPIOIC);
106 	reg |= 1 << pin;
107 	_reg_write_2(SH4_GPIOIC, reg);
108 
109 	splx(s);
110 
111 	return &gpio_intr_func_table[pin];
112 }
113 
114 void
gpior_intr_disestablish(void * cookie)115 gpior_intr_disestablish(void *cookie)
116 {
117 	struct gpio_intrhand *ih = cookie;
118 	int pin = ih->ih_irq;
119 	uint16_t reg;
120 	int s;
121 
122 	KASSERT(pin >= 0 && pin <= 15);
123 
124 	s = splhigh();
125 
126 	/* disable gpio interrupt */
127 	reg = _reg_read_2(SH4_GPIOIC);
128 	reg &= ~(1 << pin);
129 	_reg_write_2(SH4_GPIOIC, reg);
130 
131 	/* deinstall interrupt handler */
132 	gpio_intr_func_table[pin].ih_irq = 0;
133 	gpio_intr_func_table[pin].ih_func = NULL;
134 	gpio_intr_func_table[pin].ih_arg = NULL;
135 
136 	splx(s);
137 }
138 
139 /*ARGSUSED*/
140 static int
gpio_intr(void * arg)141 gpio_intr(void *arg)
142 {
143 	struct gpio_intrhand *ih;
144 	uint32_t reg;
145 	int retval = 0;
146 	int pin;
147 
148 	reg = _reg_read_4(SH4_PCTRA);
149 	for (pin = 0; pin < 16; pin++) {
150 		if (reg & (1 << pin)) {
151 			ih = &gpio_intr_func_table[pin];
152 			if (ih->ih_func != NULL) {
153 				retval |= (*ih->ih_func)(ih->ih_arg);
154 			} else {
155 				uint16_t r;
156 				r = _reg_read_2(SH4_GPIOIC);
157 				r &= ~(1 << pin);
158 				_reg_write_2(SH4_GPIOIC, r);
159 			}
160 		}
161 	}
162 	return retval;
163 }
164