1*5f819ca3Schs /* $NetBSD: hd64465.c,v 1.17 2012/10/27 17:17:56 chs Exp $ */ 2b67fd34cSuch 3b67fd34cSuch /*- 4b67fd34cSuch * Copyright (c) 2002 The NetBSD Foundation, Inc. 5b67fd34cSuch * All rights reserved. 6b67fd34cSuch * 7b67fd34cSuch * This code is derived from software contributed to The NetBSD Foundation 8b67fd34cSuch * by UCHIYAMA Yasushi. 9b67fd34cSuch * 10b67fd34cSuch * Redistribution and use in source and binary forms, with or without 11b67fd34cSuch * modification, are permitted provided that the following conditions 12b67fd34cSuch * are met: 13b67fd34cSuch * 1. Redistributions of source code must retain the above copyright 14b67fd34cSuch * notice, this list of conditions and the following disclaimer. 15b67fd34cSuch * 2. Redistributions in binary form must reproduce the above copyright 16b67fd34cSuch * notice, this list of conditions and the following disclaimer in the 17b67fd34cSuch * documentation and/or other materials provided with the distribution. 18b67fd34cSuch * 19b67fd34cSuch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20b67fd34cSuch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21b67fd34cSuch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22b67fd34cSuch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23b67fd34cSuch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24b67fd34cSuch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25b67fd34cSuch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26b67fd34cSuch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27b67fd34cSuch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28b67fd34cSuch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29b67fd34cSuch * POSSIBILITY OF SUCH DAMAGE. 30b67fd34cSuch */ 31b67fd34cSuch 320c82163cSlukem #include <sys/cdefs.h> 33*5f819ca3Schs __KERNEL_RCSID(0, "$NetBSD: hd64465.c,v 1.17 2012/10/27 17:17:56 chs Exp $"); 340c82163cSlukem 35b67fd34cSuch #include <sys/param.h> 36b67fd34cSuch #include <sys/systm.h> 37b67fd34cSuch #include <sys/device.h> 38b67fd34cSuch #include <sys/boot_flag.h> 3902411c48Sdyoung #include <sys/bus.h> 40b67fd34cSuch 41b67fd34cSuch #include <machine/intr.h> 42b67fd34cSuch #include <machine/debug.h> 43b67fd34cSuch 44260c29f0Such #include <sh3/intcreg.h> 45b67fd34cSuch #include <hpcsh/dev/hd64465/hd64465var.h> 46b67fd34cSuch #include <hpcsh/dev/hd64465/hd64465reg.h> 47b67fd34cSuch #include <hpcsh/dev/hd64465/hd64465intcreg.h> 48b67fd34cSuch 49b67fd34cSuch /* HD64465 modules. */ 50b67fd34cSuch STATIC const struct hd64465_module { 51b67fd34cSuch const char *name; 52b67fd34cSuch } hd64465_modules[] = { 53b67fd34cSuch [HD64465_MODULE_PS2IF] = { "hd64465ps2if" }, 54b67fd34cSuch [HD64465_MODULE_PCMCIA] = { "hd64465pcmcia" }, 55b67fd34cSuch [HD64465_MODULE_AFE] = { "hd64465afe" }, 56b67fd34cSuch [HD64465_MODULE_GPIO] = { "hd64465gpio" }, 57b67fd34cSuch [HD64465_MODULE_KBC] = { "hd64465kbc" }, 58b67fd34cSuch [HD64465_MODULE_IRDA] = { "hd64465irda" }, 59b67fd34cSuch [HD64465_MODULE_UART] = { "hd64465uart" }, 60b67fd34cSuch [HD64465_MODULE_PARALEL] = { "hd64465paralel" }, 61b67fd34cSuch [HD64465_MODULE_CODEC] = { "hd64465codec" }, 62b67fd34cSuch [HD64465_MODULE_OHCI] = { "hd64465ohci" }, 63b67fd34cSuch [HD64465_MODULE_ADC] = { "hd64465adc" } 64b67fd34cSuch }; 65b67fd34cSuch 66d96321d6Smatt STATIC int hd64465_match(device_t, cfdata_t, void *); 67d96321d6Smatt STATIC void hd64465_attach(device_t, device_t, void *); 68b67fd34cSuch STATIC int hd64465_print(void *, const char *); 69260c29f0Such #ifdef DEBUG 70260c29f0Such STATIC void hd64465_info(void); 71260c29f0Such #endif 72b67fd34cSuch 73d96321d6Smatt CFATTACH_DECL_NEW(hd64465if, 0, 747e96d571Such hd64465_match, hd64465_attach, NULL, NULL); 75b67fd34cSuch 76b67fd34cSuch int 77d96321d6Smatt hd64465_match(device_t parent, cfdata_t cf, void *aux) 78b67fd34cSuch { 79b67fd34cSuch 80d1ad2ac4Sthorpej if (strcmp("hd64465if", cf->cf_name)) 81b67fd34cSuch return (0); 82b67fd34cSuch 83b67fd34cSuch if (hd64465_reg_read_2(HD64465_SDIDR) != 0x8122) { 84b67fd34cSuch /* not HD64465 */ 85b67fd34cSuch return (0); 86b67fd34cSuch } 87b67fd34cSuch 88b67fd34cSuch return (1); 89b67fd34cSuch } 90b67fd34cSuch 91b67fd34cSuch void 92d96321d6Smatt hd64465_attach(device_t parent, device_t self, void *aux) 93b67fd34cSuch { 94b67fd34cSuch const struct hd64465_module *module; 95b67fd34cSuch struct hd64465_attach_args ha; 96970e24eeSuwe uint16_t r; 97d96321d6Smatt size_t i; 98b67fd34cSuch 99b67fd34cSuch printf("\n"); 100260c29f0Such #ifdef DEBUG 101260c29f0Such if (bootverbose) 102260c29f0Such hd64465_info(); 103260c29f0Such #endif 104b67fd34cSuch 105b67fd34cSuch r = hd64465_reg_read_2(HD64465_SRR); 106*5f819ca3Schs printf("%s: HITACHI HD64465 rev. %d.%d\n", device_xname(self), 107b67fd34cSuch (r >> 8) & 0xff, r & 0xff); 108b67fd34cSuch 109260c29f0Such /* Mask all interrupt */ 110260c29f0Such hd64465_reg_write_2(HD64465_NIMR, 0xffff); 111260c29f0Such /* Edge trigger mode to clear pending interrupt. */ 112260c29f0Such hd64465_reg_write_2(HD64465_NITR, 0xffff); 113260c29f0Such /* Clear pending interrupt */ 114260c29f0Such hd64465_reg_write_2(HD64465_NIRR, 0x0000); 115b67fd34cSuch 116b67fd34cSuch /* Attach all sub modules */ 117d96321d6Smatt for (i = 0, module = hd64465_modules; 118d96321d6Smatt i < __arraycount(hd64465_modules); 119b67fd34cSuch i++, module++) { 120b67fd34cSuch if (module->name == 0) 121b67fd34cSuch continue; 122b67fd34cSuch ha.ha_module_id = i; 123b67fd34cSuch config_found(self, &ha, hd64465_print); 124b67fd34cSuch } 125b67fd34cSuch } 126b67fd34cSuch 127b67fd34cSuch int 128b67fd34cSuch hd64465_print(void *aux, const char *pnp) 129b67fd34cSuch { 130b67fd34cSuch struct hd64465_attach_args *ha = aux; 131b67fd34cSuch 132b67fd34cSuch if (pnp) 13372a2c879Sthorpej aprint_normal("%s at %s", 13472a2c879Sthorpej hd64465_modules[ha->ha_module_id].name, pnp); 135b67fd34cSuch 136b67fd34cSuch return (UNCONF); 137b67fd34cSuch } 138b67fd34cSuch 139b67fd34cSuch void * 140260c29f0Such hd64465_intr_establish(int irq, int mode, int level, 141b67fd34cSuch int (*func)(void *), void *arg) 142b67fd34cSuch { 143970e24eeSuwe uint16_t r; 144b67fd34cSuch int s; 145b67fd34cSuch 146b67fd34cSuch s = splhigh(); 147b67fd34cSuch /* Trigger type */ 148b67fd34cSuch r = hd64465_reg_read_2(HD64465_NITR); 149b67fd34cSuch switch (mode) { 150b67fd34cSuch case IST_PULSE: 151b67fd34cSuch /* FALLTHROUGH */ 152b67fd34cSuch case IST_EDGE: 153260c29f0Such r |= irq; 154b67fd34cSuch break; 155b67fd34cSuch case IST_LEVEL: 156260c29f0Such r &= ~irq; 157b67fd34cSuch break; 158b67fd34cSuch } 159b67fd34cSuch hd64465_reg_write_2(HD64465_NITR, r); 160b67fd34cSuch 161260c29f0Such hd6446x_intr_establish(irq, mode, level, func, arg); 162b67fd34cSuch splx(s); 163b67fd34cSuch 164b67fd34cSuch return (void *)irq; 165b67fd34cSuch } 166b67fd34cSuch 167b67fd34cSuch void 168b67fd34cSuch hd64465_intr_disestablish(void *handle) 169b67fd34cSuch { 170b67fd34cSuch 171260c29f0Such hd6446x_intr_disestablish(handle); 172b67fd34cSuch } 173b67fd34cSuch 174b67fd34cSuch /* For the sake of Windows CE reboot clearly. */ 175b67fd34cSuch void 17641ba3596Smatt hd64465_shutdown(void) 177b67fd34cSuch { 178b67fd34cSuch 179b67fd34cSuch /* Enable all interrupt */ 180b67fd34cSuch hd64465_reg_write_2(HD64465_NIMR, 0x0000); 181b67fd34cSuch 182b67fd34cSuch /* Level trigger mode */ 183b67fd34cSuch hd64465_reg_write_2(HD64465_NITR, 0x0000); 184b67fd34cSuch } 185260c29f0Such 186260c29f0Such void 18741ba3596Smatt hd64465_info(void) 188260c29f0Such { 189970e24eeSuwe uint16_t r; 190260c29f0Such 191260c29f0Such dbg_bit_print_msg(_reg_read_2(SH4_ICR), "SH4_ICR"); 192260c29f0Such r = hd64465_reg_read_2(HD64465_NIMR); 193260c29f0Such dbg_bit_print_msg(r, "NIMR"); 194260c29f0Such r = hd64465_reg_read_2(HD64465_NIRR); 195260c29f0Such dbg_bit_print_msg(r, "NIRR"); 196260c29f0Such r = hd64465_reg_read_2(HD64465_NITR); 197260c29f0Such dbg_bit_print_msg(r, "NITR"); 198260c29f0Such } 199