xref: /netbsd/sys/arch/hpcsh/dev/hd64465/hd64465.c (revision bf9ec67e)
1 /*	$NetBSD: hd64465.c,v 1.3 2002/03/28 15:27:01 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 struct cfattach hd64465if_ca = {
80 	sizeof(struct device), hd64465_match, hd64465_attach
81 };
82 
83 int
84 hd64465_match(struct device *parent, struct cfdata *cf, void *aux)
85 {
86 
87 	if (strcmp("hd64465if", cf->cf_driver->cd_name))
88 		return (0);
89 
90 	if (hd64465_reg_read_2(HD64465_SDIDR) != 0x8122) {
91 		/* not HD64465 */
92 		return (0);
93 	}
94 
95 	return (1);
96 }
97 
98 void
99 hd64465_attach(struct device *parent, struct device *self, void *aux)
100 {
101 	const struct hd64465_module *module;
102 	struct hd64465_attach_args ha;
103 	u_int16_t r;
104 	int i;
105 
106 	printf("\n");
107 #ifdef DEBUG
108 	if (bootverbose)
109 		hd64465_info();
110 #endif
111 
112 	r = hd64465_reg_read_2(HD64465_SRR);
113 	printf("%s: HITACHI HD64465 rev. %d.%d\n", self->dv_xname,
114 	    (r >> 8) & 0xff, r & 0xff);
115 
116 	/* Mask all interrupt */
117 	hd64465_reg_write_2(HD64465_NIMR, 0xffff);
118 	/* Edge trigger mode to clear pending interrupt. */
119 	hd64465_reg_write_2(HD64465_NITR, 0xffff);
120 	/* Clear pending interrupt */
121 	hd64465_reg_write_2(HD64465_NIRR, 0x0000);
122 
123 	/* Attach all sub modules */
124 	for (i = 0, module = hd64465_modules; i < HD64465_NMODULE;
125 	    i++, module++) {
126 		if (module->name == 0)
127 			continue;
128 		ha.ha_module_id = i;
129 		config_found(self, &ha, hd64465_print);
130 	}
131 }
132 
133 int
134 hd64465_print(void *aux, const char *pnp)
135 {
136 	struct hd64465_attach_args *ha = aux;
137 
138 	if (pnp)
139 		printf("%s at %s", hd64465_modules[ha->ha_module_id].name, pnp);
140 
141 	return (UNCONF);
142 }
143 
144 void *
145 hd64465_intr_establish(int irq, int mode, int level,
146     int (*func)(void *), void *arg)
147 {
148 	u_int16_t r;
149 	int s;
150 
151 	s = splhigh();
152 	/* Trigger type */
153 	r = hd64465_reg_read_2(HD64465_NITR);
154 	switch (mode) {
155 	case IST_PULSE:
156 		/* FALLTHROUGH */
157 	case IST_EDGE:
158 		r |= irq;
159 		break;
160 	case IST_LEVEL:
161 		r &= ~irq;
162 		break;
163 	}
164 	hd64465_reg_write_2(HD64465_NITR, r);
165 
166 	hd6446x_intr_establish(irq, mode, level, func, arg);
167 	splx(s);
168 
169 	return (void *)irq;
170 }
171 
172 void
173 hd64465_intr_disestablish(void *handle)
174 {
175 
176 	hd6446x_intr_disestablish(handle);
177 }
178 
179 /* For the sake of Windows CE reboot clearly. */
180 void
181 hd64465_shutdown()
182 {
183 
184 	/* Enable all interrupt */
185 	hd64465_reg_write_2(HD64465_NIMR, 0x0000);
186 
187 	/* Level trigger mode */
188 	hd64465_reg_write_2(HD64465_NITR, 0x0000);
189 }
190 
191 void
192 hd64465_info()
193 {
194 	u_int16_t r;
195 
196 	dbg_bit_print_msg(_reg_read_2(SH4_ICR), "SH4_ICR");
197 	r = hd64465_reg_read_2(HD64465_NIMR);
198 	dbg_bit_print_msg(r, "NIMR");
199 	r = hd64465_reg_read_2(HD64465_NIRR);
200 	dbg_bit_print_msg(r, "NIRR");
201 	r = hd64465_reg_read_2(HD64465_NITR);
202 	dbg_bit_print_msg(r, "NITR");
203 }
204