xref: /netbsd-src/sys/arch/evbsh3/ap_ms104_sh4/ap_ms104_sh4.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: ap_ms104_sh4.c,v 1.1 2010/04/06 15:54: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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: ap_ms104_sh4.c,v 1.1 2010/04/06 15:54:29 nonaka Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/intr.h>
35 
36 #include <sh3/devreg.h>
37 #include <sh3/pfcreg.h>
38 #include <sh3/exception.h>
39 
40 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4reg.h>
41 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4var.h>
42 
43 static int gpio_intr(void *arg);
44 
45 struct gpio_intrhand {
46 	int ih_irq;
47 	int (*ih_func)(void *);
48 	void *ih_arg;
49 } gpio_intr_func_table[16];
50 
51 void
52 machine_init(void)
53 {
54 
55 	extintr_init();
56 	gpio_intr_init();
57 }
58 
59 void
60 gpio_intr_init(void)
61 {
62 	uint32_t reg;
63 
64 	_reg_write_2(SH4_GPIOIC, 0);
65 	_reg_write_2(SH4_PDTRA, 0);
66 	_reg_write_4(SH4_PCTRA, 0);
67 	_reg_write_2(SH4_PDTRB, 0);
68 	_reg_write_4(SH4_PCTRB, 0);
69 
70 	(void) intc_intr_establish(SH4_INTEVT_GPIO, IST_LEVEL, IPL_TTY,
71 	    gpio_intr, NULL);
72 
73 	/* setup for pc-card */
74 	_reg_write_2(SH4_PDTRA, (1 << GPIO_PIN_CARD_PON)
75 	                        | (1 << GPIO_PIN_CARD_RESET)
76 	                        | (1 << GPIO_PIN_CARD_ENABLE)); /* disable */
77 	reg = _reg_read_4(SH4_PCTRA);
78 	reg &= ~(3 << (GPIO_PIN_CARD_CD * 2));		/* input */
79 	reg &= ~(3 << (GPIO_PIN_CARD_PON * 2));
80 	reg |=  (1 << (GPIO_PIN_CARD_PON * 2));		/* output */
81 	reg &= ~(3 << (GPIO_PIN_CARD_RESET * 2));
82 	reg |=  (1 << (GPIO_PIN_CARD_RESET * 2));	/* output */
83 	reg &= ~(3 << (GPIO_PIN_CARD_ENABLE * 2));
84 	reg |=  (1 << (GPIO_PIN_CARD_ENABLE * 2));	/* output */
85 	_reg_write_4(SH4_PCTRA, reg);
86 }
87 
88 void *
89 gpio_intr_establish(int pin, int (*ih_func)(void *), void *ih_arg)
90 {
91 	uint32_t reg;
92 	int s;
93 
94 	KASSERT(pin >= 0 && pin <= 15);
95 	KASSERT(gpio_intr_func_table[pin].ih_func == NULL);
96 	KASSERT((_reg_read_4(SH4_PCTRA) & (1 << (pin * 2))) == 0); /*input*/
97 
98 	s = splhigh();
99 
100 	/* install interrupt handler */
101 	gpio_intr_func_table[pin].ih_irq = pin;
102 	gpio_intr_func_table[pin].ih_func = ih_func;
103 	gpio_intr_func_table[pin].ih_arg = ih_arg;
104 
105 	/* enable gpio interrupt */
106 	reg = _reg_read_2(SH4_GPIOIC);
107 	reg |= 1 << pin;
108 	_reg_write_2(SH4_GPIOIC, reg);
109 
110 	splx(s);
111 
112 	return &gpio_intr_func_table[pin];
113 }
114 
115 void
116 gpior_intr_disestablish(void *cookie)
117 {
118 	struct gpio_intrhand *ih = cookie;
119 	int pin = ih->ih_irq;
120 	uint16_t reg;
121 	int s;
122 
123 	KASSERT(pin >= 0 && pin <= 15);
124 
125 	s = splhigh();
126 
127 	/* disable gpio interrupt */
128 	reg = _reg_read_2(SH4_GPIOIC);
129 	reg &= ~(1 << pin);
130 	_reg_write_2(SH4_GPIOIC, reg);
131 
132 	/* deinstall interrupt handler */
133 	gpio_intr_func_table[pin].ih_irq = 0;
134 	gpio_intr_func_table[pin].ih_func = NULL;
135 	gpio_intr_func_table[pin].ih_arg = NULL;
136 
137 	splx(s);
138 }
139 
140 /*ARGSUSED*/
141 static int
142 gpio_intr(void *arg)
143 {
144 	struct gpio_intrhand *ih;
145 	uint32_t reg;
146 	int retval = 0;
147 	int pin;
148 
149 	reg = _reg_read_4(SH4_PCTRA);
150 	for (pin = 0; pin < 16; pin++) {
151 		if (reg & (1 << pin)) {
152 			ih = &gpio_intr_func_table[pin];
153 			if (ih->ih_func != NULL) {
154 				retval |= (*ih->ih_func)(ih->ih_arg);
155 			} else {
156 				uint16_t r;
157 				r = _reg_read_2(SH4_GPIOIC);
158 				r &= ~(1 << pin);
159 				_reg_write_2(SH4_GPIOIC, r);
160 			}
161 		}
162 	}
163 	return retval;
164 }
165