1 1.28 andvar /* $NetBSD: it8368.c,v 1.28 2023/12/08 22:11:15 andvar Exp $ */ 2 1.1 uch 3 1.10 uch /*- 4 1.10 uch * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. 5 1.1 uch * All rights reserved. 6 1.1 uch * 7 1.10 uch * This code is derived from software contributed to The NetBSD Foundation 8 1.10 uch * by UCHIYAMA Yasushi. 9 1.10 uch * 10 1.1 uch * Redistribution and use in source and binary forms, with or without 11 1.1 uch * modification, are permitted provided that the following conditions 12 1.1 uch * are met: 13 1.1 uch * 1. Redistributions of source code must retain the above copyright 14 1.1 uch * notice, this list of conditions and the following disclaimer. 15 1.10 uch * 2. Redistributions in binary form must reproduce the above copyright 16 1.10 uch * notice, this list of conditions and the following disclaimer in the 17 1.10 uch * documentation and/or other materials provided with the distribution. 18 1.1 uch * 19 1.10 uch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.10 uch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.10 uch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.10 uch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.10 uch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.10 uch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.10 uch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.10 uch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.10 uch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.10 uch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.10 uch * POSSIBILITY OF SUCH DAMAGE. 30 1.1 uch */ 31 1.18 lukem 32 1.18 lukem #include <sys/cdefs.h> 33 1.28 andvar __KERNEL_RCSID(0, "$NetBSD: it8368.c,v 1.28 2023/12/08 22:11:15 andvar Exp $"); 34 1.10 uch 35 1.8 uch #undef WINCE_DEFAULT_SETTING /* for debug */ 36 1.8 uch #undef IT8368DEBUG 37 1.1 uch 38 1.1 uch #include <sys/param.h> 39 1.1 uch #include <sys/systm.h> 40 1.1 uch #include <sys/device.h> 41 1.1 uch 42 1.1 uch #include <machine/bus.h> 43 1.1 uch 44 1.1 uch #include <dev/pcmcia/pcmciareg.h> 45 1.1 uch #include <dev/pcmcia/pcmciavar.h> 46 1.1 uch #include <dev/pcmcia/pcmciachip.h> 47 1.1 uch 48 1.1 uch #include <hpcmips/tx/tx39var.h> 49 1.1 uch #include <hpcmips/tx/txcsbusvar.h> 50 1.6 uch #include <hpcmips/tx/tx39biureg.h> /* legacy mode requires BIU access */ 51 1.6 uch #include <hpcmips/dev/it8368var.h> 52 1.1 uch #include <hpcmips/dev/it8368reg.h> 53 1.1 uch 54 1.1 uch #ifdef IT8368DEBUG 55 1.8 uch int it8368debug = 1; 56 1.8 uch #define DPRINTF(arg) if (it8368debug) printf arg; 57 1.8 uch #define DPRINTFN(n, arg) if (it8368debug > (n)) printf arg; 58 1.1 uch #else 59 1.1 uch #define DPRINTF(arg) 60 1.8 uch #define DPRINTFN(n, arg) 61 1.1 uch #endif 62 1.1 uch 63 1.24 chs int it8368e_match(device_t, cfdata_t, void *); 64 1.24 chs void it8368e_attach(device_t, device_t, void *); 65 1.10 uch int it8368_print(void *, const char *); 66 1.1 uch 67 1.4 uch #define IT8368_LASTSTATE_PRESENT 0x0002 68 1.4 uch #define IT8368_LASTSTATE_HALF 0x0001 69 1.7 uch #define IT8368_LASTSTATE_EMPTY 0x0000 70 1.4 uch 71 1.1 uch struct it8368e_softc { 72 1.24 chs device_t sc_dev; 73 1.24 chs device_t sc_pcmcia; 74 1.1 uch tx_chipset_tag_t sc_tc; 75 1.1 uch 76 1.1 uch /* Register space */ 77 1.4 uch bus_space_tag_t sc_csregt; 78 1.4 uch bus_space_handle_t sc_csregh; 79 1.1 uch /* I/O, attribute space */ 80 1.4 uch bus_space_tag_t sc_csiot; 81 1.4 uch bus_addr_t sc_csiobase; 82 1.4 uch bus_size_t sc_csiosize; 83 1.3 uch /* 84 1.3 uch * XXX theses means attribute memory. not memory space. 85 1.3 uch * memory space is 0x64000000. 86 1.3 uch */ 87 1.4 uch bus_space_tag_t sc_csmemt; 88 1.4 uch bus_addr_t sc_csmembase; 89 1.4 uch bus_size_t sc_csmemsize; 90 1.1 uch 91 1.1 uch /* Separate I/O and attribute space mode */ 92 1.1 uch int sc_fixattr; 93 1.1 uch 94 1.1 uch /* Card interrupt handler */ 95 1.10 uch int (*sc_card_fun)(void *); 96 1.4 uch void *sc_card_arg; 97 1.4 uch void *sc_card_ih; 98 1.4 uch int sc_card_irq; 99 1.4 uch 100 1.4 uch /* Card status change */ 101 1.4 uch int sc_irq; 102 1.4 uch void *sc_ih; 103 1.4 uch int sc_laststate; 104 1.1 uch }; 105 1.1 uch 106 1.10 uch void it8368_init_socket(struct it8368e_softc*); 107 1.10 uch void it8368_attach_socket(struct it8368e_softc *); 108 1.10 uch int it8368_intr(void *); 109 1.10 uch int it8368_chip_mem_alloc(pcmcia_chipset_handle_t, bus_size_t, 110 1.10 uch struct pcmcia_mem_handle *); 111 1.10 uch void it8368_chip_mem_free(pcmcia_chipset_handle_t, struct pcmcia_mem_handle *); 112 1.11 soren int it8368_chip_mem_map(pcmcia_chipset_handle_t, int, bus_size_t, bus_size_t, 113 1.10 uch struct pcmcia_mem_handle *, bus_addr_t *, int *); 114 1.10 uch void it8368_chip_mem_unmap(pcmcia_chipset_handle_t, int); 115 1.10 uch int it8368_chip_io_alloc(pcmcia_chipset_handle_t, bus_addr_t, bus_size_t, 116 1.10 uch bus_size_t, struct pcmcia_io_handle *); 117 1.10 uch void it8368_chip_io_free(pcmcia_chipset_handle_t, struct pcmcia_io_handle *); 118 1.10 uch int it8368_chip_io_map(pcmcia_chipset_handle_t, int, bus_addr_t, bus_size_t, 119 1.10 uch struct pcmcia_io_handle *, int *); 120 1.10 uch void it8368_chip_io_unmap(pcmcia_chipset_handle_t, int); 121 1.10 uch void it8368_chip_socket_enable(pcmcia_chipset_handle_t); 122 1.10 uch void it8368_chip_socket_disable(pcmcia_chipset_handle_t); 123 1.10 uch void *it8368_chip_intr_establish(pcmcia_chipset_handle_t, 124 1.10 uch struct pcmcia_function *, int, int (*) (void *), void *); 125 1.10 uch void it8368_chip_intr_disestablish(pcmcia_chipset_handle_t, void *); 126 1.1 uch 127 1.8 uch #ifdef IT8368DEBUG 128 1.10 uch void it8368_dump(struct it8368e_softc *); 129 1.8 uch #endif 130 1.8 uch 131 1.1 uch static struct pcmcia_chip_functions it8368_functions = { 132 1.1 uch it8368_chip_mem_alloc, 133 1.1 uch it8368_chip_mem_free, 134 1.1 uch it8368_chip_mem_map, 135 1.1 uch it8368_chip_mem_unmap, 136 1.1 uch it8368_chip_io_alloc, 137 1.1 uch it8368_chip_io_free, 138 1.1 uch it8368_chip_io_map, 139 1.1 uch it8368_chip_io_unmap, 140 1.1 uch it8368_chip_intr_establish, 141 1.1 uch it8368_chip_intr_disestablish, 142 1.1 uch it8368_chip_socket_enable, 143 1.1 uch it8368_chip_socket_disable 144 1.1 uch }; 145 1.1 uch 146 1.24 chs CFATTACH_DECL_NEW(it8368e, sizeof(struct it8368e_softc), 147 1.16 thorpej it8368e_match, it8368e_attach, NULL, NULL); 148 1.1 uch 149 1.1 uch /* 150 1.1 uch * IT8368 configuration register is big-endian. 151 1.1 uch */ 152 1.21 perry static inline u_int16_t it8368_reg_read(bus_space_tag_t, 153 1.10 uch bus_space_handle_t, int); 154 1.21 perry static inline void it8368_reg_write(bus_space_tag_t, bus_space_handle_t, 155 1.10 uch int, u_int16_t); 156 1.1 uch 157 1.8 uch #ifdef IT8368E_DESTRUCTIVE_CHECK 158 1.10 uch int it8368e_id_check(void *); 159 1.8 uch 160 1.8 uch /* 161 1.8 uch * IT8368E don't have identification method. this is destructive check. 162 1.8 uch */ 163 1.8 uch int 164 1.10 uch it8368e_id_check(void *aux) 165 1.8 uch { 166 1.8 uch struct cs_attach_args *ca = aux; 167 1.8 uch tx_chipset_tag_t tc; 168 1.8 uch bus_space_tag_t csregt; 169 1.8 uch bus_space_handle_t csregh; 170 1.8 uch u_int16_t oreg, reg; 171 1.8 uch int match = 0; 172 1.8 uch 173 1.8 uch tc = ca->ca_tc; 174 1.8 uch csregt = ca->ca_csreg.cstag; 175 1.8 uch 176 1.8 uch bus_space_map(csregt, ca->ca_csreg.csbase, ca->ca_csreg.cssize, 177 1.10 uch 0, &csregh); 178 1.8 uch reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG); 179 1.8 uch oreg = reg; 180 1.12 uch dbg_bit_print(reg); 181 1.8 uch 182 1.8 uch reg &= ~IT8368_CTRL_BYTESWAP; 183 1.8 uch it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg); 184 1.8 uch reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG); 185 1.8 uch if (reg & IT8368_CTRL_BYTESWAP) 186 1.8 uch goto nomatch; 187 1.8 uch 188 1.8 uch reg |= IT8368_CTRL_BYTESWAP; 189 1.8 uch it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg); 190 1.8 uch reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG); 191 1.8 uch if (!(reg & IT8368_CTRL_BYTESWAP)) 192 1.8 uch goto nomatch; 193 1.8 uch 194 1.8 uch match = 1; 195 1.8 uch nomatch: 196 1.8 uch it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, oreg); 197 1.8 uch bus_space_unmap(csregt, csregh, ca->ca_csreg.cssize); 198 1.8 uch 199 1.8 uch return (match); 200 1.8 uch } 201 1.8 uch #endif /* IT8368E_DESTRUCTIVE_CHECK */ 202 1.4 uch 203 1.1 uch int 204 1.24 chs it8368e_match(device_t parent, cfdata_t cf, void *aux) 205 1.1 uch { 206 1.8 uch #ifdef IT8368E_DESTRUCTIVE_CHECK 207 1.8 uch return (it8368e_id_check(aux)); 208 1.8 uch #else 209 1.8 uch return (1); 210 1.8 uch #endif 211 1.1 uch } 212 1.1 uch 213 1.1 uch void 214 1.24 chs it8368e_attach(device_t parent, device_t self, void *aux) 215 1.1 uch { 216 1.1 uch struct cs_attach_args *ca = aux; 217 1.24 chs struct it8368e_softc *sc = device_private(self); 218 1.1 uch tx_chipset_tag_t tc; 219 1.1 uch bus_space_tag_t csregt; 220 1.1 uch bus_space_handle_t csregh; 221 1.1 uch u_int16_t reg; 222 1.1 uch 223 1.24 chs sc->sc_dev = self; 224 1.1 uch sc->sc_tc = tc = ca->ca_tc; 225 1.1 uch sc->sc_csregt = csregt = ca->ca_csreg.cstag; 226 1.1 uch 227 1.1 uch bus_space_map(csregt, ca->ca_csreg.csbase, ca->ca_csreg.cssize, 228 1.10 uch 0, &sc->sc_csregh); 229 1.1 uch csregh = sc->sc_csregh; 230 1.1 uch sc->sc_csiot = ca->ca_csio.cstag; 231 1.1 uch sc->sc_csiobase = ca->ca_csio.csbase; 232 1.1 uch sc->sc_csiosize = ca->ca_csio.cssize; 233 1.1 uch 234 1.3 uch #ifdef IT8368DEBUG 235 1.4 uch printf("\n\t[Windows CE setting]\n"); 236 1.1 uch it8368_dump(sc); /* print WindowsCE setting */ 237 1.3 uch #endif 238 1.1 uch /* LHA[14:13] <= HA[14:13] */ 239 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG); 240 1.1 uch reg &= ~IT8368_CTRL_ADDRSEL; 241 1.1 uch it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg); 242 1.1 uch 243 1.1 uch /* Set all MFIO direction as LHA[23:13] output pins */ 244 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_MFIODIR_REG); 245 1.1 uch reg |= IT8368_MFIODIR_MASK; 246 1.1 uch it8368_reg_write(csregt, csregh, IT8368_MFIODIR_REG, reg); 247 1.1 uch 248 1.1 uch /* Set all MFIO functions as LHA */ 249 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_MFIOSEL_REG); 250 1.1 uch reg &= ~IT8368_MFIOSEL_MASK; 251 1.1 uch it8368_reg_write(csregt, csregh, IT8368_MFIOSEL_REG, reg); 252 1.1 uch 253 1.1 uch /* Disable MFIO interrupt */ 254 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_MFIOPOSINTEN_REG); 255 1.1 uch reg &= ~IT8368_MFIOPOSINTEN_MASK; 256 1.1 uch it8368_reg_write(csregt, csregh, IT8368_MFIOPOSINTEN_REG, reg); 257 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_MFIONEGINTEN_REG); 258 1.1 uch reg &= ~IT8368_MFIONEGINTEN_MASK; 259 1.1 uch it8368_reg_write(csregt, csregh, IT8368_MFIONEGINTEN_REG, reg); 260 1.1 uch 261 1.1 uch /* Port direction */ 262 1.1 uch reg = IT8368_PIN_CRDVCCON1 | IT8368_PIN_CRDVCCON0 | 263 1.10 uch IT8368_PIN_CRDVPPON1 | IT8368_PIN_CRDVPPON0 | 264 1.10 uch IT8368_PIN_BCRDRST; 265 1.1 uch it8368_reg_write(csregt, csregh, IT8368_GPIODIR_REG, reg); 266 1.5 uch printf("\n"); 267 1.5 uch 268 1.1 uch /* 269 1.1 uch * Separate I/O and attribute memory region 270 1.1 uch */ 271 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG); 272 1.8 uch 273 1.1 uch reg |= IT8368_CTRL_FIXATTRIO; 274 1.1 uch it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg); 275 1.8 uch 276 1.6 uch if (IT8368_CTRL_FIXATTRIO & 277 1.6 uch it8368_reg_read(csregt, csregh, IT8368_CTRL_REG)) { 278 1.1 uch sc->sc_fixattr = 1; 279 1.24 chs printf("%s: fix attr mode\n", device_xname(sc->sc_dev)); 280 1.1 uch } else { 281 1.1 uch sc->sc_fixattr = 0; 282 1.24 chs printf("%s: legacy attr mode\n", device_xname(sc->sc_dev)); 283 1.1 uch } 284 1.8 uch 285 1.6 uch sc->sc_csmemt = sc->sc_csiot; 286 1.6 uch sc->sc_csiosize /= 2; 287 1.6 uch sc->sc_csmemsize = sc->sc_csiosize; 288 1.6 uch sc->sc_csmembase = sc->sc_csiosize; 289 1.6 uch 290 1.7 uch #ifdef IT8368DEBUG 291 1.1 uch it8368_dump(sc); 292 1.7 uch #endif 293 1.4 uch /* Enable card and interrupt driving. */ 294 1.4 uch reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG); 295 1.4 uch reg |= (IT8368_CTRL_GLOBALEN | IT8368_CTRL_CARDEN); 296 1.4 uch if (sc->sc_fixattr) 297 1.4 uch reg |= IT8368_CTRL_FIXATTRIO; 298 1.4 uch it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg); 299 1.4 uch 300 1.4 uch sc->sc_irq = ca->ca_irq1; 301 1.1 uch sc->sc_card_irq = ca->ca_irq3; 302 1.1 uch 303 1.1 uch it8368_attach_socket(sc); 304 1.1 uch } 305 1.1 uch 306 1.21 perry inline u_int16_t 307 1.10 uch it8368_reg_read(bus_space_tag_t t, bus_space_handle_t h, int ofs) 308 1.1 uch { 309 1.1 uch u_int16_t val; 310 1.1 uch 311 1.1 uch val = bus_space_read_2(t, h, ofs); 312 1.10 uch return (0xffff & (((val >> 8) & 0xff)|((val << 8) & 0xff00))); 313 1.1 uch } 314 1.1 uch 315 1.21 perry inline void 316 1.10 uch it8368_reg_write(bus_space_tag_t t, bus_space_handle_t h, int ofs, u_int16_t v) 317 1.1 uch { 318 1.1 uch u_int16_t val; 319 1.1 uch 320 1.1 uch val = 0xffff & (((v >> 8) & 0xff)|((v << 8) & 0xff00)); 321 1.1 uch bus_space_write_2(t, h, ofs, val); 322 1.1 uch } 323 1.1 uch 324 1.1 uch int 325 1.10 uch it8368_intr(void *arg) 326 1.1 uch { 327 1.1 uch struct it8368e_softc *sc = arg; 328 1.4 uch bus_space_tag_t csregt = sc->sc_csregt; 329 1.4 uch bus_space_handle_t csregh = sc->sc_csregh; 330 1.4 uch u_int16_t reg; 331 1.3 uch 332 1.4 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIONEGINTSTAT_REG); 333 1.3 uch 334 1.4 uch if (reg & IT8368_PIN_BCRDRDY) { 335 1.4 uch if (sc->sc_card_fun) { 336 1.4 uch /* clear interrupt */ 337 1.4 uch it8368_reg_write(csregt, csregh, 338 1.10 uch IT8368_GPIONEGINTSTAT_REG, 339 1.10 uch IT8368_PIN_BCRDRDY); 340 1.4 uch 341 1.4 uch /* Dispatch card interrupt handler */ 342 1.4 uch (*sc->sc_card_fun)(sc->sc_card_arg); 343 1.4 uch } 344 1.4 uch } else if (reg & IT8368_PIN_CRDDET2) { 345 1.4 uch it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTSTAT_REG, 346 1.10 uch IT8368_PIN_CRDDET2); 347 1.4 uch printf("[CSC]\n"); 348 1.7 uch #ifdef IT8368DEBUG 349 1.4 uch it8368_dump(sc); 350 1.7 uch #endif 351 1.4 uch it8368_chip_socket_disable(sc); 352 1.4 uch } else { 353 1.7 uch #ifdef IT8368DEBUG 354 1.8 uch u_int16_t reg2; 355 1.8 uch reg2 = reg & ~(IT8368_PIN_BCRDRDY|IT8368_PIN_CRDDET2); 356 1.8 uch printf("unknown it8368 interrupt: "); 357 1.12 uch dbg_bit_print(reg2); 358 1.8 uch it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTSTAT_REG, 359 1.10 uch reg); 360 1.7 uch #endif 361 1.1 uch } 362 1.4 uch 363 1.10 uch return (0); 364 1.1 uch } 365 1.1 uch 366 1.1 uch int 367 1.10 uch it8368_print(void *arg, const char *pnp) 368 1.1 uch { 369 1.3 uch if (pnp) 370 1.17 thorpej aprint_normal("pcmcia at %s", pnp); 371 1.1 uch 372 1.10 uch return (UNCONF); 373 1.1 uch } 374 1.1 uch 375 1.1 uch void 376 1.10 uch it8368_attach_socket(struct it8368e_softc *sc) 377 1.1 uch { 378 1.1 uch struct pcmciabus_attach_args paa; 379 1.1 uch 380 1.1 uch paa.paa_busname = "pcmcia"; 381 1.1 uch paa.pct = (pcmcia_chipset_tag_t)&it8368_functions; 382 1.1 uch paa.pch = (pcmcia_chipset_handle_t)sc; 383 1.23 dyoung 384 1.26 thorpej if ((sc->sc_pcmcia = config_found(sc->sc_dev, &paa, it8368_print, 385 1.27 thorpej CFARGS_NONE))) { 386 1.4 uch it8368_init_socket(sc); 387 1.4 uch } 388 1.4 uch } 389 1.4 uch 390 1.4 uch void 391 1.10 uch it8368_init_socket(struct it8368e_softc *sc) 392 1.4 uch { 393 1.4 uch bus_space_tag_t csregt = sc->sc_csregt; 394 1.4 uch bus_space_handle_t csregh = sc->sc_csregh; 395 1.4 uch u_int16_t reg; 396 1.4 uch 397 1.4 uch /* 398 1.4 uch * set up the card to interrupt on card detect 399 1.4 uch */ 400 1.4 uch reg = IT8368_PIN_CRDDET2; /* CSC */ 401 1.4 uch /* enable negative edge */ 402 1.4 uch it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTEN_REG, reg); 403 1.4 uch /* disable positive edge */ 404 1.4 uch it8368_reg_write(csregt, csregh, IT8368_GPIOPOSINTEN_REG, 0); 405 1.4 uch 406 1.4 uch sc->sc_ih = tx_intr_establish(sc->sc_tc, sc->sc_irq, 407 1.10 uch IST_EDGE, IPL_BIO, it8368_intr, sc); 408 1.4 uch if (sc->sc_ih == NULL) { 409 1.4 uch printf("%s: can't establish interrupt\n", 410 1.24 chs device_xname(sc->sc_dev)); 411 1.4 uch return; 412 1.4 uch } 413 1.4 uch 414 1.4 uch /* 415 1.4 uch * if there's a card there, then attach it. 416 1.4 uch */ 417 1.4 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAIN_REG); 418 1.4 uch 419 1.4 uch if (reg & (IT8368_PIN_CRDDET2|IT8368_PIN_CRDDET1)) { 420 1.4 uch sc->sc_laststate = IT8368_LASTSTATE_EMPTY; 421 1.4 uch } else { 422 1.4 uch pcmcia_card_attach(sc->sc_pcmcia); 423 1.4 uch sc->sc_laststate = IT8368_LASTSTATE_PRESENT; 424 1.1 uch } 425 1.1 uch } 426 1.1 uch 427 1.1 uch void * 428 1.10 uch it8368_chip_intr_establish(pcmcia_chipset_handle_t pch, 429 1.10 uch struct pcmcia_function *pf, int ipl, int (*ih_fun)(void *), void *ih_arg) 430 1.1 uch { 431 1.1 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 432 1.4 uch bus_space_tag_t csregt = sc->sc_csregt; 433 1.4 uch bus_space_handle_t csregh = sc->sc_csregh; 434 1.4 uch u_int16_t reg; 435 1.1 uch 436 1.4 uch if (sc->sc_card_fun) 437 1.3 uch panic("it8368_chip_intr_establish: " 438 1.10 uch "duplicate card interrupt handler."); 439 1.4 uch 440 1.1 uch sc->sc_card_fun = ih_fun; 441 1.1 uch sc->sc_card_arg = ih_arg; 442 1.1 uch 443 1.4 uch sc->sc_card_ih = tx_intr_establish(sc->sc_tc, sc->sc_card_irq, 444 1.10 uch IST_EDGE, IPL_BIO, it8368_intr, 445 1.10 uch sc); 446 1.4 uch 447 1.4 uch /* enable card interrupt */ 448 1.4 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIONEGINTEN_REG); 449 1.4 uch reg |= IT8368_PIN_BCRDRDY; 450 1.4 uch it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTEN_REG, reg); 451 1.4 uch 452 1.10 uch return (sc->sc_card_ih); 453 1.1 uch } 454 1.1 uch 455 1.1 uch void 456 1.10 uch it8368_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih) 457 1.1 uch { 458 1.1 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 459 1.4 uch bus_space_tag_t csregt = sc->sc_csregt; 460 1.4 uch bus_space_handle_t csregh = sc->sc_csregh; 461 1.4 uch u_int16_t reg; 462 1.1 uch 463 1.4 uch if (!sc->sc_card_fun) 464 1.3 uch panic("it8368_chip_intr_disestablish:" 465 1.10 uch "no handler established."); 466 1.4 uch assert(ih == sc->sc_card_ih); 467 1.4 uch 468 1.1 uch sc->sc_card_fun = 0; 469 1.1 uch sc->sc_card_arg = 0; 470 1.1 uch 471 1.4 uch /* disable card interrupt */ 472 1.4 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIONEGINTEN_REG); 473 1.4 uch reg &= ~IT8368_PIN_BCRDRDY; 474 1.4 uch it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTEN_REG, reg); 475 1.4 uch 476 1.1 uch tx_intr_disestablish(sc->sc_tc, ih); 477 1.1 uch } 478 1.1 uch 479 1.1 uch int 480 1.10 uch it8368_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, 481 1.10 uch struct pcmcia_mem_handle *pcmhp) 482 1.1 uch { 483 1.1 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 484 1.1 uch 485 1.6 uch if (bus_space_alloc(sc->sc_csmemt, sc->sc_csmembase, 486 1.10 uch sc->sc_csmembase + sc->sc_csmemsize, size, 487 1.10 uch size, 0, 0, 0, &pcmhp->memh)) { 488 1.6 uch DPRINTF(("it8368_chip_mem_alloc: failed\n")); 489 1.10 uch return (1); 490 1.1 uch } 491 1.3 uch 492 1.6 uch if (!sc->sc_fixattr) /* XXX IT8368 brain damaged spec */ 493 1.6 uch pcmhp->memh -= sc->sc_csmembase; 494 1.6 uch 495 1.6 uch pcmhp->memt = sc->sc_csmemt; 496 1.1 uch pcmhp->addr = pcmhp->memh; 497 1.1 uch pcmhp->size = size; 498 1.1 uch pcmhp->realsize = size; 499 1.3 uch 500 1.8 uch DPRINTF(("it8368_chip_mem_alloc: %#x+%#x\n", 501 1.10 uch (unsigned)pcmhp->memh, (unsigned)size)); 502 1.1 uch 503 1.10 uch return (0); 504 1.1 uch } 505 1.1 uch 506 1.1 uch void 507 1.10 uch it8368_chip_mem_free(pcmcia_chipset_handle_t pch, 508 1.10 uch struct pcmcia_mem_handle *pcmhp) 509 1.1 uch { 510 1.6 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 511 1.6 uch 512 1.8 uch DPRINTF(("it8368_chip_mem_free: %#x+%#x\n", 513 1.10 uch (unsigned)pcmhp->memh, (unsigned)pcmhp->size)); 514 1.8 uch 515 1.6 uch if (!sc->sc_fixattr) /* XXX IT8368 brain damaged spec */ 516 1.6 uch pcmhp->memh += sc->sc_csmembase; 517 1.6 uch 518 1.1 uch bus_space_unmap(pcmhp->memt, pcmhp->memh, pcmhp->size); 519 1.1 uch } 520 1.1 uch 521 1.1 uch int 522 1.10 uch it8368_chip_mem_map(pcmcia_chipset_handle_t pch, int kind, 523 1.10 uch bus_addr_t card_addr, bus_size_t size, struct pcmcia_mem_handle *pcmhp, 524 1.11 soren bus_size_t *offsetp, int *windowp) 525 1.1 uch { 526 1.6 uch /* attribute mode */ 527 1.6 uch it8368_mode(pch, IT8368_ATTR_MODE, IT8368_WIDTH_16); 528 1.1 uch 529 1.3 uch *offsetp = card_addr; 530 1.8 uch DPRINTF(("it8368_chip_mem_map %#x+%#x\n", 531 1.10 uch (unsigned)pcmhp->memh, (unsigned)size)); 532 1.3 uch 533 1.10 uch return (0); 534 1.1 uch } 535 1.1 uch 536 1.1 uch void 537 1.10 uch it8368_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window) 538 1.1 uch { 539 1.6 uch /* return to I/O mode */ 540 1.6 uch it8368_mode(pch, IT8368_IO_MODE, IT8368_WIDTH_16); 541 1.1 uch } 542 1.1 uch 543 1.1 uch void 544 1.10 uch it8368_mode(pcmcia_chipset_handle_t pch, int io, int width) 545 1.1 uch { 546 1.6 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 547 1.1 uch txreg_t reg32; 548 1.1 uch 549 1.6 uch DPRINTF(("it8368_mode: change access space to ")); 550 1.8 uch DPRINTF((io ? "I/O (%dbit)\n" : "attribute (%dbit)...\n", 551 1.10 uch width == IT8368_WIDTH_8 ? 8 : 16)); 552 1.6 uch 553 1.1 uch reg32 = tx_conf_read(sc->sc_tc, TX39_MEMCONFIG3_REG); 554 1.8 uch 555 1.6 uch if (io) { 556 1.8 uch if (width == IT8368_WIDTH_8) 557 1.6 uch reg32 |= TX39_MEMCONFIG3_PORT8SEL; 558 1.6 uch else 559 1.6 uch reg32 &= ~TX39_MEMCONFIG3_PORT8SEL; 560 1.1 uch } 561 1.6 uch 562 1.1 uch if (!sc->sc_fixattr) { 563 1.6 uch if (io) 564 1.1 uch reg32 |= TX39_MEMCONFIG3_CARD1IOEN; 565 1.6 uch else 566 1.1 uch reg32 &= ~TX39_MEMCONFIG3_CARD1IOEN; 567 1.1 uch } 568 1.1 uch tx_conf_write(sc->sc_tc, TX39_MEMCONFIG3_REG, reg32); 569 1.1 uch 570 1.8 uch #ifdef IT8368DEBUG 571 1.8 uch if (sc->sc_fixattr) 572 1.8 uch return; /* No need to report BIU status */ 573 1.8 uch 574 1.8 uch /* check BIU status */ 575 1.1 uch reg32 = tx_conf_read(sc->sc_tc, TX39_MEMCONFIG3_REG); 576 1.8 uch if (reg32 & TX39_MEMCONFIG3_CARD1IOEN) { 577 1.8 uch DPRINTF(("it8368_mode: I/O space (%dbit) enabled\n", 578 1.10 uch reg32 & TX39_MEMCONFIG3_PORT8SEL ? 8 : 16)); 579 1.8 uch } else { 580 1.28 andvar DPRINTF(("it8368_mode: attribute space enabled\n")); 581 1.8 uch } 582 1.8 uch #endif /* IT8368DEBUG */ 583 1.1 uch } 584 1.1 uch 585 1.1 uch int 586 1.10 uch it8368_chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, 587 1.10 uch bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp) 588 1.1 uch { 589 1.1 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 590 1.1 uch 591 1.1 uch if (start) { 592 1.3 uch if (bus_space_map(sc->sc_csiot, start, size, 0, 593 1.10 uch &pcihp->ioh)) { 594 1.10 uch return (1); 595 1.1 uch } 596 1.1 uch DPRINTF(("it8368_chip_io_alloc map port %#x+%#x\n", 597 1.10 uch (unsigned)start, (unsigned)size)); 598 1.1 uch } else { 599 1.1 uch if (bus_space_alloc(sc->sc_csiot, sc->sc_csiobase, 600 1.10 uch sc->sc_csiobase + sc->sc_csiosize, 601 1.10 uch size, align, 0, 0, &pcihp->addr, 602 1.10 uch &pcihp->ioh)) { 603 1.3 uch 604 1.10 uch return (1); 605 1.1 uch } 606 1.1 uch pcihp->flags = PCMCIA_IO_ALLOCATED; 607 1.1 uch DPRINTF(("it8368_chip_io_alloc alloc %#x from %#x\n", 608 1.10 uch (unsigned)size, (unsigned)pcihp->addr)); 609 1.2 uch } 610 1.1 uch 611 1.1 uch pcihp->iot = sc->sc_csiot; 612 1.1 uch pcihp->size = size; 613 1.1 uch 614 1.10 uch return (0); 615 1.1 uch } 616 1.1 uch 617 1.1 uch int 618 1.10 uch it8368_chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, 619 1.10 uch bus_size_t size, struct pcmcia_io_handle *pcihp, int *windowp) 620 1.1 uch { 621 1.6 uch /* I/O mode */ 622 1.6 uch it8368_mode(pch, IT8368_IO_MODE, IT8368_WIDTH_16); 623 1.1 uch 624 1.8 uch DPRINTF(("it8368_chip_io_map %#x:%#x+%#x\n", 625 1.10 uch (unsigned)pcihp->ioh, (unsigned)offset, (unsigned)size)); 626 1.1 uch 627 1.10 uch return (0); 628 1.1 uch } 629 1.1 uch 630 1.1 uch void 631 1.10 uch it8368_chip_io_free(pcmcia_chipset_handle_t pch, 632 1.10 uch struct pcmcia_io_handle *pcihp) 633 1.1 uch { 634 1.6 uch if (pcihp->flags & PCMCIA_IO_ALLOCATED) 635 1.1 uch bus_space_free(pcihp->iot, pcihp->ioh, pcihp->size); 636 1.6 uch else 637 1.1 uch bus_space_unmap(pcihp->iot, pcihp->ioh, pcihp->size); 638 1.6 uch 639 1.8 uch DPRINTF(("it8368_chip_io_free %#x+%#x\n", 640 1.10 uch (unsigned)pcihp->ioh, (unsigned)pcihp->size)); 641 1.1 uch } 642 1.1 uch 643 1.1 uch void 644 1.10 uch it8368_chip_io_unmap(pcmcia_chipset_handle_t pch, int window) 645 1.1 uch { 646 1.10 uch 647 1.1 uch } 648 1.1 uch 649 1.1 uch void 650 1.10 uch it8368_chip_socket_enable(pcmcia_chipset_handle_t pch) 651 1.1 uch { 652 1.8 uch #ifndef WINCE_DEFAULT_SETTING 653 1.1 uch struct it8368e_softc *sc = (struct it8368e_softc*)pch; 654 1.1 uch bus_space_tag_t csregt = sc->sc_csregt; 655 1.1 uch bus_space_handle_t csregh = sc->sc_csregh; 656 1.1 uch volatile u_int16_t reg; 657 1.3 uch 658 1.1 uch /* Power off */ 659 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG); 660 1.1 uch reg &= ~(IT8368_PIN_CRDVCCMASK | IT8368_PIN_CRDVPPMASK); 661 1.1 uch reg |= (IT8368_PIN_CRDVCC_0V | IT8368_PIN_CRDVPP_0V); 662 1.1 uch it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg); 663 1.1 uch delay(20000); 664 1.1 uch 665 1.1 uch /* 666 1.1 uch * wait 300ms until power fails (Tpf). Then, wait 100ms since 667 1.1 uch * we are changing Vcc (Toff). 668 1.1 uch */ 669 1.1 uch delay((300 + 100) * 1000); 670 1.1 uch 671 1.1 uch /* Supply Vcc */ 672 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG); 673 1.1 uch reg &= ~(IT8368_PIN_CRDVCCMASK | IT8368_PIN_CRDVPPMASK); 674 1.1 uch reg |= IT8368_PIN_CRDVCC_5V; /* XXX */ 675 1.1 uch it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg); 676 1.1 uch 677 1.1 uch /* 678 1.1 uch * wait 100ms until power raise (Tpr) and 20ms to become 679 1.1 uch * stable (Tsu(Vcc)). 680 1.1 uch * 681 1.1 uch * some machines require some more time to be settled 682 1.1 uch * (300ms is added here). 683 1.1 uch */ 684 1.1 uch delay((100 + 20 + 300) * 1000); 685 1.1 uch 686 1.1 uch /* Assert reset signal */ 687 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG); 688 1.1 uch reg |= IT8368_PIN_BCRDRST; 689 1.1 uch it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg); 690 1.4 uch 691 1.1 uch /* 692 1.1 uch * hold RESET at least 10us. 693 1.1 uch */ 694 1.1 uch delay(10); 695 1.4 uch 696 1.8 uch /* deassert reset signal */ 697 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG); 698 1.1 uch reg &= ~IT8368_PIN_BCRDRST; 699 1.1 uch it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg); 700 1.1 uch delay(20000); 701 1.1 uch 702 1.6 uch DPRINTF(("it8368_chip_socket_enable: socket enabled\n")); 703 1.8 uch #endif /* !WINCE_DEFAULT_SETTING */ 704 1.1 uch } 705 1.1 uch 706 1.1 uch void 707 1.10 uch it8368_chip_socket_disable(pcmcia_chipset_handle_t pch) 708 1.1 uch { 709 1.8 uch #ifndef WINCE_DEFAULT_SETTING 710 1.1 uch struct it8368e_softc *sc = (struct it8368e_softc*) pch; 711 1.1 uch bus_space_tag_t csregt = sc->sc_csregt; 712 1.1 uch bus_space_handle_t csregh = sc->sc_csregh; 713 1.1 uch u_int16_t reg; 714 1.1 uch 715 1.1 uch /* Power down */ 716 1.1 uch reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG); 717 1.1 uch reg &= ~(IT8368_PIN_CRDVCCMASK | IT8368_PIN_CRDVPPMASK); 718 1.1 uch reg |= (IT8368_PIN_CRDVCC_0V | IT8368_PIN_CRDVPP_0V); 719 1.1 uch it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg); 720 1.1 uch delay(20000); 721 1.1 uch 722 1.1 uch /* 723 1.1 uch * wait 300ms until power fails (Tpf). 724 1.1 uch */ 725 1.1 uch delay(300 * 1000); 726 1.4 uch 727 1.6 uch DPRINTF(("it8368_chip_socket_disable: socket disabled\n")); 728 1.8 uch #endif /* !WINCE_DEFAULT_SETTING */ 729 1.1 uch } 730 1.1 uch 731 1.7 uch #ifdef IT8368DEBUG 732 1.12 uch #define PRINTGPIO(m) __dbg_bit_print(it8368_reg_read(csregt, csregh, \ 733 1.13 takemura IT8368_GPIO##m##_REG), 0, IT8368_GPIO_MAX, #m, DBG_BIT_PRINT_COUNT) 734 1.12 uch #define PRINTMFIO(m) __dbg_bit_print(it8368_reg_read(csregt, csregh, \ 735 1.13 takemura IT8368_MFIO##m##_REG), 0, IT8368_MFIO_MAX, #m, DBG_BIT_PRINT_COUNT) 736 1.1 uch void 737 1.10 uch it8368_dump(struct it8368e_softc *sc) 738 1.1 uch { 739 1.1 uch bus_space_tag_t csregt = sc->sc_csregt; 740 1.1 uch bus_space_handle_t csregh = sc->sc_csregh; 741 1.1 uch 742 1.1 uch printf("[GPIO]\n"); 743 1.1 uch PRINTGPIO(DIR); 744 1.1 uch PRINTGPIO(DATAIN); 745 1.1 uch PRINTGPIO(DATAOUT); 746 1.1 uch PRINTGPIO(POSINTEN); 747 1.1 uch PRINTGPIO(NEGINTEN); 748 1.1 uch PRINTGPIO(POSINTSTAT); 749 1.1 uch PRINTGPIO(NEGINTSTAT); 750 1.1 uch printf("[MFIO]\n"); 751 1.1 uch PRINTMFIO(SEL); 752 1.1 uch PRINTMFIO(DIR); 753 1.1 uch PRINTMFIO(DATAIN); 754 1.1 uch PRINTMFIO(DATAOUT); 755 1.1 uch PRINTMFIO(POSINTEN); 756 1.1 uch PRINTMFIO(NEGINTEN); 757 1.1 uch PRINTMFIO(POSINTSTAT); 758 1.1 uch PRINTMFIO(NEGINTSTAT); 759 1.12 uch __dbg_bit_print(it8368_reg_read(csregt, csregh, IT8368_CTRL_REG), 0, 15, 760 1.13 takemura "CTRL", DBG_BIT_PRINT_COUNT); 761 1.12 uch __dbg_bit_print(it8368_reg_read(csregt, csregh, IT8368_GPIODATAIN_REG), 762 1.13 takemura 8, 11, "]CRDDET/SENSE[", DBG_BIT_PRINT_COUNT); 763 1.1 uch } 764 1.7 uch #endif /* IT8368DEBUG */ 765