xref: /netbsd/sys/arch/hpcsh/dev/hd64465/hd64465.c (revision c4a72b64)
1 /*	$NetBSD: hd64465.c,v 1.8 2002/10/21 17:07:36 uch Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by UCHIYAMA Yasushi.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/device.h>
42 #include <sys/boot_flag.h>
43 
44 #include <machine/bus.h>
45 #include <machine/intr.h>
46 #include <machine/debug.h>
47 
48 #include <sh3/intcreg.h>
49 #include <hpcsh/dev/hd64465/hd64465var.h>
50 #include <hpcsh/dev/hd64465/hd64465reg.h>
51 #include <hpcsh/dev/hd64465/hd64465intcreg.h>
52 
53 /* HD64465 modules. */
54 STATIC const struct hd64465_module {
55 	const char *name;
56 } hd64465_modules[] = {
57 	[HD64465_MODULE_PS2IF]		= { "hd64465ps2if" },
58 	[HD64465_MODULE_PCMCIA]		= { "hd64465pcmcia" },
59 	[HD64465_MODULE_AFE]		= { "hd64465afe" },
60 	[HD64465_MODULE_GPIO]		= { "hd64465gpio" },
61 	[HD64465_MODULE_KBC]		= { "hd64465kbc" },
62 	[HD64465_MODULE_IRDA]		= { "hd64465irda" },
63 	[HD64465_MODULE_UART]		= { "hd64465uart" },
64 	[HD64465_MODULE_PARALEL]	= { "hd64465paralel" },
65 	[HD64465_MODULE_CODEC]		= { "hd64465codec" },
66 	[HD64465_MODULE_OHCI]		= { "hd64465ohci" },
67 	[HD64465_MODULE_ADC]		= { "hd64465adc" }
68 };
69 #define HD64465_NMODULE							\
70 	(sizeof hd64465_modules / sizeof(struct hd64465_module))
71 
72 STATIC int hd64465_match(struct device *, struct cfdata *, void *);
73 STATIC void hd64465_attach(struct device *, struct device *, void *);
74 STATIC int hd64465_print(void *, const char *);
75 #ifdef DEBUG
76 STATIC void hd64465_info(void);
77 #endif
78 
79 CFATTACH_DECL(hd64465if, sizeof(struct device),
80     hd64465_match, hd64465_attach, NULL, NULL);
81 
82 int
83 hd64465_match(struct device *parent, struct cfdata *cf, void *aux)
84 {
85 
86 	if (strcmp("hd64465if", cf->cf_name))
87 		return (0);
88 
89 	if (hd64465_reg_read_2(HD64465_SDIDR) != 0x8122) {
90 		/* not HD64465 */
91 		return (0);
92 	}
93 
94 	return (1);
95 }
96 
97 void
98 hd64465_attach(struct device *parent, struct device *self, void *aux)
99 {
100 	const struct hd64465_module *module;
101 	struct hd64465_attach_args ha;
102 	u_int16_t r;
103 	int i;
104 
105 	printf("\n");
106 #ifdef DEBUG
107 	if (bootverbose)
108 		hd64465_info();
109 #endif
110 
111 	r = hd64465_reg_read_2(HD64465_SRR);
112 	printf("%s: HITACHI HD64465 rev. %d.%d\n", self->dv_xname,
113 	    (r >> 8) & 0xff, r & 0xff);
114 
115 	/* Mask all interrupt */
116 	hd64465_reg_write_2(HD64465_NIMR, 0xffff);
117 	/* Edge trigger mode to clear pending interrupt. */
118 	hd64465_reg_write_2(HD64465_NITR, 0xffff);
119 	/* Clear pending interrupt */
120 	hd64465_reg_write_2(HD64465_NIRR, 0x0000);
121 
122 	/* Attach all sub modules */
123 	for (i = 0, module = hd64465_modules; i < HD64465_NMODULE;
124 	    i++, module++) {
125 		if (module->name == 0)
126 			continue;
127 		ha.ha_module_id = i;
128 		config_found(self, &ha, hd64465_print);
129 	}
130 }
131 
132 int
133 hd64465_print(void *aux, const char *pnp)
134 {
135 	struct hd64465_attach_args *ha = aux;
136 
137 	if (pnp)
138 		printf("%s at %s", hd64465_modules[ha->ha_module_id].name, pnp);
139 
140 	return (UNCONF);
141 }
142 
143 void *
144 hd64465_intr_establish(int irq, int mode, int level,
145     int (*func)(void *), void *arg)
146 {
147 	u_int16_t r;
148 	int s;
149 
150 	s = splhigh();
151 	/* Trigger type */
152 	r = hd64465_reg_read_2(HD64465_NITR);
153 	switch (mode) {
154 	case IST_PULSE:
155 		/* FALLTHROUGH */
156 	case IST_EDGE:
157 		r |= irq;
158 		break;
159 	case IST_LEVEL:
160 		r &= ~irq;
161 		break;
162 	}
163 	hd64465_reg_write_2(HD64465_NITR, r);
164 
165 	hd6446x_intr_establish(irq, mode, level, func, arg);
166 	splx(s);
167 
168 	return (void *)irq;
169 }
170 
171 void
172 hd64465_intr_disestablish(void *handle)
173 {
174 
175 	hd6446x_intr_disestablish(handle);
176 }
177 
178 /* For the sake of Windows CE reboot clearly. */
179 void
180 hd64465_shutdown()
181 {
182 
183 	/* Enable all interrupt */
184 	hd64465_reg_write_2(HD64465_NIMR, 0x0000);
185 
186 	/* Level trigger mode */
187 	hd64465_reg_write_2(HD64465_NITR, 0x0000);
188 }
189 
190 void
191 hd64465_info()
192 {
193 	u_int16_t r;
194 
195 	dbg_bit_print_msg(_reg_read_2(SH4_ICR), "SH4_ICR");
196 	r = hd64465_reg_read_2(HD64465_NIMR);
197 	dbg_bit_print_msg(r, "NIMR");
198 	r = hd64465_reg_read_2(HD64465_NIRR);
199 	dbg_bit_print_msg(r, "NIRR");
200 	r = hd64465_reg_read_2(HD64465_NITR);
201 	dbg_bit_print_msg(r, "NITR");
202 }
203