Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: gamecube/wii: udbg support for usbgecko

Add support for using the USB Gecko adapter via the udbg facility on
the Nintendo GameCube and Wii video game consoles.
The USB Gecko is a 3rd party memory card interface adapter that provides
a EXI (External Interface) to USB serial converter.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
Acked-by: Segher Boessenkool <segher@kernel.crashing.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

authored by

Albert Herranz and committed by
Grant Likely
a166df08 bcc48591

+316
+13
arch/powerpc/platforms/embedded6xx/Kconfig
··· 94 94 config GAMECUBE_COMMON 95 95 bool 96 96 97 + config USBGECKO_UDBG 98 + bool "USB Gecko udbg console for the Nintendo GameCube/Wii" 99 + depends on GAMECUBE_COMMON 100 + help 101 + If you say yes to this option, support will be included for the 102 + USB Gecko adapter as an udbg console. 103 + The USB Gecko is a EXI to USB Serial converter that can be plugged 104 + into a memcard slot in the Nintendo GameCube/Wii. 105 + 106 + This driver bypasses the EXI layer completely. 107 + 108 + If in doubt, say N here. 109 +
+1
arch/powerpc/platforms/embedded6xx/Makefile
··· 7 7 obj-$(CONFIG_PPC_HOLLY) += holly.o 8 8 obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o 9 9 obj-$(CONFIG_PPC_C2K) += c2k.o 10 + obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o
+272
arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
··· 1 + /* 2 + * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c 3 + * 4 + * udbg serial input/output routines for the USB Gecko adapter. 5 + * Copyright (C) 2008-2009 The GameCube Linux Team 6 + * Copyright (C) 2008,2009 Albert Herranz 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * as published by the Free Software Foundation; either version 2 11 + * of the License, or (at your option) any later version. 12 + * 13 + */ 14 + 15 + #include <mm/mmu_decl.h> 16 + 17 + #include <asm/io.h> 18 + #include <asm/prom.h> 19 + #include <asm/udbg.h> 20 + 21 + #include "usbgecko_udbg.h" 22 + 23 + 24 + #define EXI_CLK_32MHZ 5 25 + 26 + #define EXI_CSR 0x00 27 + #define EXI_CSR_CLKMASK (0x7<<4) 28 + #define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4) 29 + #define EXI_CSR_CSMASK (0x7<<7) 30 + #define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */ 31 + 32 + #define EXI_CR 0x0c 33 + #define EXI_CR_TSTART (1<<0) 34 + #define EXI_CR_WRITE (1<<2) 35 + #define EXI_CR_READ_WRITE (2<<2) 36 + #define EXI_CR_TLEN(len) (((len)-1)<<4) 37 + 38 + #define EXI_DATA 0x10 39 + 40 + #define UG_READ_ATTEMPTS 100 41 + #define UG_WRITE_ATTEMPTS 100 42 + 43 + 44 + static void __iomem *ug_io_base; 45 + 46 + /* 47 + * Performs one input/output transaction between the exi host and the usbgecko. 48 + */ 49 + static u32 ug_io_transaction(u32 in) 50 + { 51 + u32 __iomem *csr_reg = ug_io_base + EXI_CSR; 52 + u32 __iomem *data_reg = ug_io_base + EXI_DATA; 53 + u32 __iomem *cr_reg = ug_io_base + EXI_CR; 54 + u32 csr, data, cr; 55 + 56 + /* select */ 57 + csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0; 58 + out_be32(csr_reg, csr); 59 + 60 + /* read/write */ 61 + data = in; 62 + out_be32(data_reg, data); 63 + cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART; 64 + out_be32(cr_reg, cr); 65 + 66 + while (in_be32(cr_reg) & EXI_CR_TSTART) 67 + barrier(); 68 + 69 + /* deselect */ 70 + out_be32(csr_reg, 0); 71 + 72 + /* result */ 73 + data = in_be32(data_reg); 74 + 75 + return data; 76 + } 77 + 78 + /* 79 + * Returns true if an usbgecko adapter is found. 80 + */ 81 + static int ug_is_adapter_present(void) 82 + { 83 + if (!ug_io_base) 84 + return 0; 85 + 86 + return ug_io_transaction(0x90000000) == 0x04700000; 87 + } 88 + 89 + /* 90 + * Returns true if the TX fifo is ready for transmission. 91 + */ 92 + static int ug_is_txfifo_ready(void) 93 + { 94 + return ug_io_transaction(0xc0000000) & 0x04000000; 95 + } 96 + 97 + /* 98 + * Tries to transmit a character. 99 + * If the TX fifo is not ready the result is undefined. 100 + */ 101 + static void ug_raw_putc(char ch) 102 + { 103 + ug_io_transaction(0xb0000000 | (ch << 20)); 104 + } 105 + 106 + /* 107 + * Transmits a character. 108 + * It silently fails if the TX fifo is not ready after a number of retries. 109 + */ 110 + static void ug_putc(char ch) 111 + { 112 + int count = UG_WRITE_ATTEMPTS; 113 + 114 + if (!ug_io_base) 115 + return; 116 + 117 + if (ch == '\n') 118 + ug_putc('\r'); 119 + 120 + while (!ug_is_txfifo_ready() && count--) 121 + barrier(); 122 + if (count) 123 + ug_raw_putc(ch); 124 + } 125 + 126 + /* 127 + * Returns true if the RX fifo is ready for transmission. 128 + */ 129 + static int ug_is_rxfifo_ready(void) 130 + { 131 + return ug_io_transaction(0xd0000000) & 0x04000000; 132 + } 133 + 134 + /* 135 + * Tries to receive a character. 136 + * If a character is unavailable the function returns -1. 137 + */ 138 + static int ug_raw_getc(void) 139 + { 140 + u32 data = ug_io_transaction(0xa0000000); 141 + if (data & 0x08000000) 142 + return (data >> 16) & 0xff; 143 + else 144 + return -1; 145 + } 146 + 147 + /* 148 + * Receives a character. 149 + * It fails if the RX fifo is not ready after a number of retries. 150 + */ 151 + static int ug_getc(void) 152 + { 153 + int count = UG_READ_ATTEMPTS; 154 + 155 + if (!ug_io_base) 156 + return -1; 157 + 158 + while (!ug_is_rxfifo_ready() && count--) 159 + barrier(); 160 + return ug_raw_getc(); 161 + } 162 + 163 + /* 164 + * udbg functions. 165 + * 166 + */ 167 + 168 + /* 169 + * Transmits a character. 170 + */ 171 + void ug_udbg_putc(char ch) 172 + { 173 + ug_putc(ch); 174 + } 175 + 176 + /* 177 + * Receives a character. Waits until a character is available. 178 + */ 179 + static int ug_udbg_getc(void) 180 + { 181 + int ch; 182 + 183 + while ((ch = ug_getc()) == -1) 184 + barrier(); 185 + return ch; 186 + } 187 + 188 + /* 189 + * Receives a character. If a character is not available, returns -1. 190 + */ 191 + static int ug_udbg_getc_poll(void) 192 + { 193 + if (!ug_is_rxfifo_ready()) 194 + return -1; 195 + return ug_getc(); 196 + } 197 + 198 + /* 199 + * Retrieves and prepares the virtual address needed to access the hardware. 200 + */ 201 + static void __iomem *ug_udbg_setup_exi_io_base(struct device_node *np) 202 + { 203 + void __iomem *exi_io_base = NULL; 204 + phys_addr_t paddr; 205 + const unsigned int *reg; 206 + 207 + reg = of_get_property(np, "reg", NULL); 208 + if (reg) { 209 + paddr = of_translate_address(np, reg); 210 + if (paddr) 211 + exi_io_base = ioremap(paddr, reg[1]); 212 + } 213 + return exi_io_base; 214 + } 215 + 216 + /* 217 + * Checks if a USB Gecko adapter is inserted in any memory card slot. 218 + */ 219 + static void __iomem *ug_udbg_probe(void __iomem *exi_io_base) 220 + { 221 + int i; 222 + 223 + /* look for a usbgecko on memcard slots A and B */ 224 + for (i = 0; i < 2; i++) { 225 + ug_io_base = exi_io_base + 0x14 * i; 226 + if (ug_is_adapter_present()) 227 + break; 228 + } 229 + if (i == 2) 230 + ug_io_base = NULL; 231 + return ug_io_base; 232 + 233 + } 234 + 235 + /* 236 + * USB Gecko udbg support initialization. 237 + */ 238 + void __init ug_udbg_init(void) 239 + { 240 + struct device_node *np; 241 + void __iomem *exi_io_base; 242 + 243 + if (ug_io_base) 244 + udbg_printf("%s: early -> final\n", __func__); 245 + 246 + np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi"); 247 + if (!np) { 248 + udbg_printf("%s: EXI node not found\n", __func__); 249 + goto done; 250 + } 251 + 252 + exi_io_base = ug_udbg_setup_exi_io_base(np); 253 + if (!exi_io_base) { 254 + udbg_printf("%s: failed to setup EXI io base\n", __func__); 255 + goto done; 256 + } 257 + 258 + if (!ug_udbg_probe(exi_io_base)) { 259 + udbg_printf("usbgecko_udbg: not found\n"); 260 + iounmap(exi_io_base); 261 + } else { 262 + udbg_putc = ug_udbg_putc; 263 + udbg_getc = ug_udbg_getc; 264 + udbg_getc_poll = ug_udbg_getc_poll; 265 + udbg_printf("usbgecko_udbg: ready\n"); 266 + } 267 + 268 + done: 269 + if (np) 270 + of_node_put(np); 271 + return; 272 + }
+30
arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
··· 1 + /* 2 + * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h 3 + * 4 + * udbg serial input/output routines for the USB Gecko adapter. 5 + * Copyright (C) 2008-2009 The GameCube Linux Team 6 + * Copyright (C) 2008,2009 Albert Herranz 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * as published by the Free Software Foundation; either version 2 11 + * of the License, or (at your option) any later version. 12 + * 13 + */ 14 + 15 + #ifndef __USBGECKO_UDBG_H 16 + #define __USBGECKO_UDBG_H 17 + 18 + #ifdef CONFIG_USBGECKO_UDBG 19 + 20 + extern void __init ug_udbg_init(void); 21 + 22 + #else 23 + 24 + static inline void __init ug_udbg_init(void) 25 + { 26 + } 27 + 28 + #endif /* CONFIG_USBGECKO_UDBG */ 29 + 30 + #endif /* __USBGECKO_UDBG_H */