atkbd_atkbdc.c revision 83492
191396Stmm/*- 291396Stmm * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3108834Stmm * All rights reserved. 491396Stmm * 591396Stmm * Redistribution and use in source and binary forms, with or without 691396Stmm * modification, are permitted provided that the following conditions 791396Stmm * are met: 891396Stmm * 1. Redistributions of source code must retain the above copyright 991396Stmm * notice, this list of conditions and the following disclaimer as 1091396Stmm * the first lines of this file unmodified. 1191396Stmm * 2. Redistributions in binary form must reproduce the above copyright 1291396Stmm * notice, this list of conditions and the following disclaimer in the 1391396Stmm * documentation and/or other materials provided with the distribution. 1491396Stmm * 1591396Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1691396Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1791396Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1891396Stmm * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 1991396Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2091396Stmm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2191396Stmm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2291396Stmm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2391396Stmm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2491396Stmm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2591396Stmm * 2691396Stmm * $FreeBSD: head/sys/dev/atkbdc/atkbd_atkbdc.c 83492 2001-09-15 04:38:20Z yokota $ 2791396Stmm */ 2891396Stmm 2991396Stmm#include "opt_kbd.h" 3091396Stmm 3191396Stmm#include <sys/param.h> 3291396Stmm#include <sys/systm.h> 3391396Stmm#include <sys/kernel.h> 3491396Stmm#include <sys/bus.h> 3591396Stmm 3691396Stmm#include <machine/bus.h> 37178470Smarius#include <machine/resource.h> 3891396Stmm#include <sys/rman.h> 3991396Stmm 40119418Sobrien#include <sys/kbio.h> 41119418Sobrien#include <dev/kbd/kbdreg.h> 42119418Sobrien#include <dev/kbd/atkbdreg.h> 4391396Stmm#include <dev/kbd/atkbdcreg.h> 4491396Stmm 4591396Stmm#include <isa/isareg.h> 4691396Stmm#include <isa/isavar.h> 4791396Stmm 4891396Stmmtypedef struct { 4991396Stmm struct resource *intr; 5091396Stmm void *ih; 5191396Stmm} atkbd_softc_t; 5291396Stmm 5391396Stmmdevclass_t atkbd_devclass; 5491396Stmm 5591396Stmmstatic void atkbdidentify(driver_t *driver, device_t dev); 5691396Stmmstatic int atkbdprobe(device_t dev); 57133149Syongaristatic int atkbdattach(device_t dev); 58133149Syongaristatic int atkbdresume(device_t dev); 59133149Syongaristatic void atkbd_isa_intr(void *arg); 60133149Syongari 61133149Syongaristatic device_method_t atkbd_methods[] = { 6291396Stmm DEVMETHOD(device_identify, atkbdidentify), 63133149Syongari DEVMETHOD(device_probe, atkbdprobe), 64178470Smarius DEVMETHOD(device_attach, atkbdattach), 6591396Stmm DEVMETHOD(device_resume, atkbdresume), 66178470Smarius { 0, 0 } 67210334Sattilio}; 6891396Stmm 6991396Stmmstatic driver_t atkbd_driver = { 7091396Stmm ATKBD_DRIVER_NAME, 7191396Stmm atkbd_methods, 7295533Smike sizeof(atkbd_softc_t), 7391396Stmm}; 74130026Sphk 7591396Stmmstatic void 7691396Stmmatkbdidentify(driver_t *driver, device_t parent) 7791396Stmm{ 7891396Stmm 7991396Stmm /* always add at least one child */ 8091396Stmm BUS_ADD_CHILD(parent, KBDC_RID_KBD, driver->name, device_get_unit(parent)); 81100980Sfenner} 8291396Stmm 8391396Stmmstatic int 8491396Stmmatkbdprobe(device_t dev) 8591396Stmm{ 8691396Stmm struct resource *res; 87147256Sbrooks u_long irq; 88129006Sjoerg int flags; 8991396Stmm int rid; 90133149Syongari 91133149Syongari device_set_desc(dev, "AT Keyboard"); 92133149Syongari 93133149Syongari /* obtain parameters */ 94133149Syongari flags = device_get_flags(dev); 95133149Syongari 9691396Stmm /* see if IRQ is available */ 9791396Stmm rid = KBDC_RID_KBD; 9891396Stmm res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 9991396Stmm RF_SHAREABLE | RF_ACTIVE); 10091396Stmm if (res == NULL) { 101119351Smarcel if (bootverbose) 102119351Smarcel device_printf(dev, "unable to allocate IRQ\n"); 10391396Stmm return ENXIO; 104178470Smarius } 105178470Smarius irq = rman_get_start(res); 106178470Smarius bus_release_resource(dev, SYS_RES_IRQ, rid, res); 10791396Stmm 108137982Syongari /* probe the device */ 10991396Stmm return atkbd_probe_unit(device_get_unit(dev), 11091396Stmm device_get_unit(device_get_parent(dev)), 11191396Stmm irq, flags); 112164932Smarius} 11391396Stmm 114147256Sbrooksstatic int 11591396Stmmatkbdattach(device_t dev) 11691396Stmm{ 11791396Stmm atkbd_softc_t *sc; 11891396Stmm keyboard_t *kbd; 11991396Stmm u_long irq; 12091396Stmm int flags; 12191396Stmm int rid; 12291396Stmm int error; 123164864Smarius 12491396Stmm sc = device_get_softc(dev); 12591396Stmm 126151639Syongari rid = KBDC_RID_KBD; 127133149Syongari irq = bus_get_resource_start(dev, SYS_RES_IRQ, rid); 12891396Stmm flags = device_get_flags(dev); 12991396Stmm error = atkbd_attach_unit(device_get_unit(dev), &kbd, 13091396Stmm device_get_unit(device_get_parent(dev)), 131133149Syongari irq, flags); 13291396Stmm if (error) 13391396Stmm return error; 13491396Stmm 13591396Stmm /* declare our interrupt handler */ 13691396Stmm sc->intr = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 13791396Stmm RF_SHAREABLE | RF_ACTIVE); 13891396Stmm if (sc->intr == NULL) 13991396Stmm return ENXIO; 140108960Sobrien error = bus_setup_intr(dev, sc->intr, INTR_TYPE_TTY, atkbd_isa_intr, 14191396Stmm kbd, &sc->ih); 14291396Stmm if (error) 14391396Stmm bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr); 144133599Smarius 14591396Stmm return error; 14691396Stmm} 147133599Smarius 148178470Smariusstatic int 149178470Smariusatkbdresume(device_t dev) 150178470Smarius{ 15191396Stmm keyboard_t *kbd; 15291396Stmm 15391396Stmm kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME, 154178470Smarius device_get_unit(dev))); 155178470Smarius if (kbd) 15691396Stmm (*kbdsw[kbd->kb_index]->clear_state)(kbd); 15791396Stmm return 0; 158178470Smarius} 159178470Smarius 16091396Stmmstatic void 16191396Stmmatkbd_isa_intr(void *arg) 162178470Smarius{ 163178470Smarius keyboard_t *kbd; 16491396Stmm 16591396Stmm kbd = (keyboard_t *)arg; 166178470Smarius (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); 167178470Smarius} 16891396Stmm 16991396StmmDRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0); 170178470Smarius