| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
1 | /*- |
| 2 | * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions | |
| 7 | * are met: | |
| 8 | * 1. Redistributions of source code must retain the above copyright | |
| 9 | * notice, this list of conditions and the following disclaimer as | |
| 10 | * the first lines of this file unmodified. | |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 12 | * notice, this list of conditions and the following disclaimer in the | |
| 13 | * documentation and/or other materials provided with the distribution. | |
| 14 | * | |
| 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR | |
| 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
| 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
| 18 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 25 | * | |
| 26 | * $FreeBSD: src/sys/isa/atkbd_isa.c,v 1.7.2.3 2001/08/01 10:42:28 yokota Exp $ | |
| 1f7ab7c9 | 27 | * $DragonFly: src/sys/dev/misc/atkbd/atkbd_isa.c,v 1.6 2006/10/25 20:55:54 dillon Exp $ |
| 984263bc MD |
28 | */ |
| 29 | ||
| 30 | #include "opt_kbd.h" | |
| 31 | ||
| 32 | #include <sys/param.h> | |
| 33 | #include <sys/systm.h> | |
| 34 | #include <sys/kernel.h> | |
| 35 | #include <sys/bus.h> | |
| 984263bc MD |
36 | #include <sys/rman.h> |
| 37 | ||
| 38 | #include <sys/kbio.h> | |
| 1f2de5d4 MD |
39 | #include <dev/misc/kbd/kbdreg.h> |
| 40 | #include <dev/misc/kbd/atkbdreg.h> | |
| 41 | #include <dev/misc/kbd/atkbdcreg.h> | |
| 984263bc | 42 | |
| 1f2de5d4 MD |
43 | #include <bus/isa/isareg.h> |
| 44 | #include <bus/isa/isavar.h> | |
| 984263bc MD |
45 | |
| 46 | typedef struct { | |
| 47 | struct resource *intr; | |
| 48 | void *ih; | |
| 49 | } atkbd_softc_t; | |
| 50 | ||
| 51 | devclass_t atkbd_devclass; | |
| 52 | ||
| 53 | static int atkbdprobe(device_t dev); | |
| 54 | static int atkbdattach(device_t dev); | |
| 55 | static int atkbdresume(device_t dev); | |
| 56 | static void atkbd_isa_intr(void *arg); | |
| 57 | ||
| 58 | static device_method_t atkbd_methods[] = { | |
| 59 | DEVMETHOD(device_probe, atkbdprobe), | |
| 60 | DEVMETHOD(device_attach, atkbdattach), | |
| 61 | DEVMETHOD(device_resume, atkbdresume), | |
| 62 | { 0, 0 } | |
| 63 | }; | |
| 64 | ||
| 65 | static driver_t atkbd_driver = { | |
| 66 | ATKBD_DRIVER_NAME, | |
| 67 | atkbd_methods, | |
| 68 | sizeof(atkbd_softc_t), | |
| 69 | }; | |
| 70 | ||
| 71 | static int | |
| 72 | atkbdprobe(device_t dev) | |
| 73 | { | |
| 74 | uintptr_t irq; | |
| 75 | uintptr_t flags; | |
| 76 | ||
| 77 | device_set_desc(dev, "AT Keyboard"); | |
| 78 | ||
| 79 | /* obtain parameters */ | |
| 80 | BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq); | |
| 81 | BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags); | |
| 82 | ||
| 83 | /* probe the device */ | |
| 84 | return atkbd_probe_unit(device_get_unit(dev), | |
| 85 | device_get_unit(device_get_parent(dev)), | |
| 86 | irq, flags); | |
| 87 | } | |
| 88 | ||
| 89 | static int | |
| 90 | atkbdattach(device_t dev) | |
| 91 | { | |
| 92 | atkbd_softc_t *sc; | |
| 93 | keyboard_t *kbd; | |
| 94 | uintptr_t irq; | |
| 95 | uintptr_t flags; | |
| 96 | int rid; | |
| 97 | int error; | |
| 98 | ||
| 99 | sc = device_get_softc(dev); | |
| 100 | ||
| 101 | BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_IRQ, &irq); | |
| 102 | BUS_READ_IVAR(device_get_parent(dev), dev, KBDC_IVAR_FLAGS, &flags); | |
| 103 | ||
| 104 | error = atkbd_attach_unit(device_get_unit(dev), &kbd, | |
| 105 | device_get_unit(device_get_parent(dev)), | |
| 106 | irq, flags); | |
| 107 | if (error) | |
| 108 | return error; | |
| 109 | ||
| 110 | /* declare our interrupt handler */ | |
| 111 | rid = 0; | |
| 112 | sc->intr = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, irq, 1, | |
| 113 | RF_SHAREABLE | RF_ACTIVE); | |
| ee61f228 | 114 | BUS_SETUP_INTR(device_get_parent(dev), dev, sc->intr, 0, |
| e9cb6d99 | 115 | atkbd_isa_intr, kbd, &sc->ih, NULL); |
| 984263bc MD |
116 | |
| 117 | return 0; | |
| 118 | } | |
| 119 | ||
| 120 | static int | |
| 121 | atkbdresume(device_t dev) | |
| 122 | { | |
| 1b96c0b6 AP |
123 | atkbd_softc_t *sc; |
| 124 | keyboard_t *kbd; | |
| 125 | int args[2]; | |
| 126 | ||
| 127 | sc = device_get_softc(dev); | |
| 128 | kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME, | |
| 129 | device_get_unit(dev))); | |
| 130 | if (kbd) { | |
| 131 | kbd->kb_flags &= ~KB_INITIALIZED; | |
| 132 | args[0] = device_get_unit(device_get_parent(dev)); | |
| 133 | args[1] = rman_get_start(sc->intr); | |
| 134 | (*kbdsw[kbd->kb_index]->init)(device_get_unit(dev), &kbd, | |
| 135 | args, device_get_flags(dev)); | |
| 136 | (*kbdsw[kbd->kb_index]->clear_state)(kbd); | |
| 137 | ||
| 138 | } | |
| 139 | return 0; | |
| 984263bc MD |
140 | } |
| 141 | ||
| 142 | static void | |
| 143 | atkbd_isa_intr(void *arg) | |
| 144 | { | |
| 145 | keyboard_t *kbd; | |
| 146 | ||
| 147 | kbd = (keyboard_t *)arg; | |
| bcc53404 | 148 | kbd_intr(kbd, NULL); |
| 984263bc MD |
149 | } |
| 150 | ||
| 151 | DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0); |