Пример #1
0
static int
sunkbd_configure(int flags)
{
	struct sunkbd_softc *sc;

	/*
	 * We are only prepared to be used for the high-level console
	 * when the keyboard is both configured and attached.
	 */
	if (!(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_IS_INITIALIZED(&sunkbd_softc.sc_kbd))
			goto found;
		else
			return (0);
	}

	if (uart_cpu_getdev(UART_DEV_KEYBOARD, &uart_keyboard))
		return (0);
	if (uart_probe(&uart_keyboard))
		return (0);
	uart_init(&uart_keyboard);

	uart_keyboard.type = UART_DEV_KEYBOARD;
	uart_keyboard.attach = sunkbd_attach;
	uart_add_sysdev(&uart_keyboard);

	if (sunkbd_probe_keyboard(&uart_keyboard) != KB_SUN4)
		return (0);

	sc = &sunkbd_softc;
	callout_init(&sc->sc_repeat_callout, 0);
	sunkbd_clear_state(&sc->sc_kbd);

#if defined(SUNKBD_EMULATE_ATKBD)
	kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
	    sizeof(fkey_tab) / sizeof(fkey_tab[0]));
#else
	kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_OTHER, 0, 0, 0, 0);
	kbd_set_maps(&sc->sc_kbd, &keymap_sun_us_unix_kbd,
	    &accentmap_sun_us_unix_kbd, fkey_tab,
	    sizeof(fkey_tab) / sizeof(fkey_tab[0]));
#endif
	sc->sc_mode = K_XLATE;
	kbd_register(&sc->sc_kbd);

	sc->sc_sysdev = &uart_keyboard;

 found:
	/* Return number of found keyboards. */
	return (1);
}
Пример #2
0
/* reset and initialize the device */
static int
pckbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	pckbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	int *data = (int *)arg;

	if (unit != PC98KBD_DEFAULT)			/* shouldn't happen */
		return ENXIO;

	*kbdp = kbd = &default_kbd;
	state = &default_kbd_state;
	if (!KBD_IS_PROBED(kbd)) {
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size = nitems(default_fkeytab);

		state->kbdc = kbdc_open(data[0]);
		if (state->kbdc == NULL)
			return ENXIO;
		kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags,
				data[0], IO_KBDSIZE);
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		      imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;

		if (probe_keyboard(state->kbdc, flags)) {/* shouldn't happen */
			if (flags & KB_CONF_FAIL_IF_NO_KBD)
				return ENXIO;
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		pckbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_HAS_DEVICE(kbd)
		    && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
		    && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
			return ENXIO;
		pckbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0)
			return ENXIO;
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Пример #3
0
static int
sunkbd_configure(int flags)
{
	struct sunkbd_softc *sc;

	if (uart_cpu_getdev(UART_DEV_KEYBOARD, &uart_keyboard))
		return (0);
	if (uart_probe(&uart_keyboard))
		return (0);
	uart_init(&uart_keyboard);
	if (sunkbd_probe_keyboard(&uart_keyboard) == -1)
		return (0);
	uart_keyboard.type = UART_DEV_KEYBOARD;
	uart_keyboard.attach = sunkbd_attach;
	uart_add_sysdev(&uart_keyboard);

	sc = &sunkbd_softc;
	callout_init(&sc->sc_repeat_callout, 0);
	sc->sc_repeat_key = -1;
	sc->sc_repeating = 0;

	kbd_init_struct(&sc->sc_kbd, "sunkbd", KB_OTHER, 0, 0, 0, 0);
	kbd_set_maps(&sc->sc_kbd, &keymap_sun_us_unix_kbd,
	    &accentmap_sun_us_unix_kbd, fkey_tab,
	    sizeof(fkey_tab) / sizeof(fkey_tab[0]));
	sc->sc_mode = K_XLATE;
	kbd_register(&sc->sc_kbd);

	sc->sc_sysdev = &uart_keyboard;

	return (0);
}
Пример #4
0
/*
 * Reset and initialize the device.  Note that unit 0 (UKBD_DEFAULT) is an
 * always-connected device once it has been initially detected.  We do not
 * deregister it if the usb keyboard is unplugged to avoid losing the 
 * connection to the console.  This feature also handles the USB bus reset
 * which detaches and reattaches USB devices during boot.
 */
static int
ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	ukbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	void **data = (void **)arg;
	struct usb_attach_arg *uaa = (struct usb_attach_arg *)data[0];

	if (unit == UKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd)) {
			return 0;
		}
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size = NELEM(default_fkeytab);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = kmalloc(sizeof(*kbd), M_DEVBUF, M_INTWAIT | M_ZERO);
		state = kmalloc(sizeof(*state), M_DEVBUF, M_INTWAIT);
		keymap = kmalloc(sizeof(key_map), M_DEVBUF, M_INTWAIT);
		accmap = kmalloc(sizeof(accent_map), M_DEVBUF, M_INTWAIT);
		fkeymap = kmalloc(sizeof(fkey_tab), M_DEVBUF, M_INTWAIT);
		fkeymap_size = NELEM(fkey_tab);
		if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
		     || (fkeymap == NULL)) {
			if (state != NULL)
				kfree(state, M_DEVBUF);
			if (keymap != NULL)
				kfree(keymap, M_DEVBUF);
			if (accmap != NULL)
				kfree(accmap, M_DEVBUF);
			if (fkeymap != NULL)
				kfree(fkeymap, M_DEVBUF);
			kfree(kbd, M_DEVBUF);
			return ENOMEM;
		}
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (ukbd_state_t *)kbd->kb_data;
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER,
				unit, flags, KB_PRI_USB,
				0, 0);
		bzero(state, sizeof(*state));
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		      imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;

		if (probe_keyboard(uaa, flags)) {
			return ENXIO;
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		ukbd_clear_state(kbd);

		/*
		 * If reattatching to an already open keyboard (e.g. console),
		 * try to restore the translation mode.  Otherwise set the
		 * translation mode to, well, translation mode so we don't
		 * get garbage.
		 */
		state->ks_mode = K_XLATE;
		state->ks_iface = uaa->iface;
		state->ks_uaa = uaa;
		state->ks_ifstate = 0;
		callout_init_mp(&state->ks_timeout);
		/*
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_HAS_DEVICE(kbd)
		    && init_keyboard((ukbd_state_t *)kbd->kb_data,
				     &kbd->kb_type, kbd->kb_flags)) {
			return ENXIO;
		}
		ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0) {
			kbd->kb_flags = 0;
			/* XXX: Missing free()'s */
			return ENXIO;
		}
		if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
			ukbd_timeout((void *)kbd);
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Пример #5
0
static int
pl050_kmi_attach(device_t dev)
{
	struct kmi_softc *sc = device_get_softc(dev);
	keyboard_t *kbd;
	int rid;
	int i;

	kbd = &sc->sc_kbd;
	rid = 0;

	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (sc->sc_mem_res == NULL) {
		device_printf(dev, "could not allocate memory resource\n");
		return (ENXIO);
	}

	/* Request the IRQ resources */
	sc->sc_irq_res =  bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(dev, "Error: could not allocate irq resources\n");
		return (ENXIO);
	}

	/* Setup and enable the timer */
	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_CLK,
			NULL, pl050_kmi_intr, sc,
			&sc->sc_intr_hl) != 0) {
		bus_release_resource(dev, SYS_RES_IRQ, rid,
			sc->sc_irq_res);
		device_printf(dev, "Unable to setup the clock irq handler.\n");
		return (ENXIO);
	}

	/* TODO: clock & divisor */

	pl050_kmi_write_4(sc, KMICR, KMICR_EN | KMICR_RXINTREN);

	kbd_init_struct(kbd, KMI_DRIVER_NAME, KB_OTHER, 
			device_get_unit(dev), 0, 0, 0);
	kbd->kb_data = (void *)sc;

	sc->sc_keymap = key_map;
	sc->sc_accmap = accent_map;
	for (i = 0; i < KMI_NFKEY; i++) {
		sc->sc_fkeymap[i] = fkey_tab[i];
	}

	kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
	    sc->sc_fkeymap, KMI_NFKEY);

	KBD_FOUND_DEVICE(kbd);
	kmi_clear_state(kbd);
	KBD_PROBE_DONE(kbd);

	KBD_INIT_DONE(kbd);

	if (kbd_register(kbd) < 0) {
		goto detach;
	}
	KBD_CONFIG_DONE(kbd);

#ifdef KBD_INSTALL_CDEV
	if (kbd_attach(kbd)) {
		goto detach;
	}
#endif

	if (bootverbose) {
		genkbd_diag(kbd, bootverbose);
	}
	return (0);

detach:
	return (ENXIO);

}
Пример #6
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
    keyboard_t *kbd;
    atkbd_state_t *state;
    keymap_t *keymap;
    accentmap_t *accmap;
    fkeytab_t *fkeymap;
    int fkeymap_size;
    int delay[2];
    int *data = (int *)arg;	/* data[0]: controller, data[1]: irq */
    int error, needfree;

    /* XXX */
    if (unit == ATKBD_DEFAULT) {
        *kbdp = kbd = &default_kbd;
        if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
            return 0;
        state = &default_kbd_state;
        keymap = &default_keymap;
        accmap = &default_accentmap;
        fkeymap = default_fkeytab;
        fkeymap_size =
            sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
        needfree = 0;
    } else if (*kbdp == NULL) {
        *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT | M_ZERO);
        state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT | M_ZERO);
        /* NB: these will always be initialized 'cuz !KBD_IS_PROBED */
        keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
        accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
        fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
        fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
        needfree = 1;
        if ((kbd == NULL) || (state == NULL) || (keymap == NULL)
                || (accmap == NULL) || (fkeymap == NULL)) {
            error = ENOMEM;
            goto bad;
        }
    } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
        return 0;
    } else {
        kbd = *kbdp;
        state = (atkbd_state_t *)kbd->kb_data;
        bzero(state, sizeof(*state));
        keymap = kbd->kb_keymap;
        accmap = kbd->kb_accentmap;
        fkeymap = kbd->kb_fkeytab;
        fkeymap_size = kbd->kb_fkeytab_size;
        needfree = 0;
    }

    if (!KBD_IS_PROBED(kbd)) {
        state->kbdc = atkbdc_open(data[0]);
        if (state->kbdc == NULL) {
            error = ENXIO;
            goto bad;
        }
        kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
                        0, 0);
        bcopy(&key_map, keymap, sizeof(key_map));
        bcopy(&accent_map, accmap, sizeof(accent_map));
        bcopy(fkey_tab, fkeymap,
              imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
        kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
        kbd->kb_data = (void *)state;

        if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
            if (flags & KB_CONF_FAIL_IF_NO_KBD) {
                error = ENXIO;
                goto bad;
            }
        } else {
            KBD_FOUND_DEVICE(kbd);
        }
        atkbd_clear_state(kbd);
        state->ks_mode = K_XLATE;
        /*
         * FIXME: set the initial value for lock keys in ks_state
         * according to the BIOS data?
         */
        KBD_PROBE_DONE(kbd);
    }
    if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
        kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
        if (KBD_HAS_DEVICE(kbd)
                && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
                && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
            kbd_unregister(kbd);
            error = ENXIO;
            goto bad;
        }
        atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
        get_typematic(kbd);
        delay[0] = kbd->kb_delay1;
        delay[1] = kbd->kb_delay2;
        atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
        KBD_INIT_DONE(kbd);
    }
    if (!KBD_IS_CONFIGURED(kbd)) {
        if (kbd_register(kbd) < 0) {
            error = ENXIO;
            goto bad;
        }
        KBD_CONFIG_DONE(kbd);
    }

    return 0;
bad:
    if (needfree) {
        if (state != NULL)
            free(state, M_DEVBUF);
        if (keymap != NULL)
            free(keymap, M_DEVBUF);
        if (accmap != NULL)
            free(accmap, M_DEVBUF);
        if (fkeymap != NULL)
            free(fkeymap, M_DEVBUF);
        if (kbd != NULL) {
            free(kbd, M_DEVBUF);
            *kbdp = NULL;	/* insure ref doesn't leak to caller */
        }
    }
    return error;
}
Пример #7
0
static int
chrome_kb_attach(device_t dev)
{
	struct ckb_softc *sc;
	keyboard_t *kbd;
	int error;
	int rid;
	int i;

	sc = device_get_softc(dev);

	sc->dev = dev;

	if ((error = parse_dts(sc)) != 0)
		return error;

#if 0
	device_printf(sc->dev, "Keyboard matrix [%dx%d]\n",
	    sc->cols, sc->rows);
#endif

	/* TODO: take interrupt from DTS */
	pad_setup_intr(KB_GPIO_INT, ckb_ec_intr, sc);

	kbd = &sc->sc_kbd;
	rid = 0;

	sc->scan_local = malloc(sc->cols, M_DEVBUF, M_NOWAIT);
	sc->scan = malloc(sc->cols, M_DEVBUF, M_NOWAIT);

	for (i = 0; i < sc->cols; i++) {
		sc->scan_local[i] = 0;
		sc->scan[i] = 0;
	};

	kbd_init_struct(kbd, KBD_DRIVER_NAME, KB_OTHER,
	    device_get_unit(dev), 0, 0, 0);
	kbd->kb_data = (void *)sc;

	sc->sc_keymap = key_map;
        sc->sc_accmap = accent_map;
	for (i = 0; i < CKB_NFKEY; i++) {
		sc->sc_fkeymap[i] = fkey_tab[i];
        }

	kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
	    sc->sc_fkeymap, CKB_NFKEY);

	KBD_FOUND_DEVICE(kbd);
	ckb_clear_state(kbd);
	KBD_PROBE_DONE(kbd);

	callout_init(&sc->sc_repeat_callout, 0);

	KBD_INIT_DONE(kbd);

	if (kbd_register(kbd) < 0) {
		return (ENXIO);
	};
	KBD_CONFIG_DONE(kbd);

	return (0);
}
Пример #8
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	atkbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	int delay[2];
	int *data = (int *)arg;	/* data[0]: controller, data[1]: irq */

	/* XXX */
	if (unit == ATKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd)) {
			return 0;
		}
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size = NELEM(default_fkeytab);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = kmalloc(sizeof(*kbd), M_DEVBUF, M_WAITOK|M_ZERO);
		state = kmalloc(sizeof(*state), M_DEVBUF, M_WAITOK|M_ZERO);
		keymap = kmalloc(sizeof(key_map), M_DEVBUF, M_WAITOK);
		accmap = kmalloc(sizeof(accent_map), M_DEVBUF, M_WAITOK);
		fkeymap = kmalloc(sizeof(fkey_tab), M_DEVBUF, M_WAITOK);
		fkeymap_size = NELEM(fkey_tab);
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (atkbd_state_t *)kbd->kb_data;
		bzero(state, sizeof(*state));
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		state->kbdc = atkbdc_open(data[0]);
		if (state->kbdc == NULL) {
			return ENXIO;
		}
		kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
				KB_PRI_ATKBD, 0, 0);
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		      imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;
	
		if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
			if (flags & KB_CONF_FAIL_IF_NO_KBD) {
				return ENXIO;
			}
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		atkbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		/* 
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
		if (!KBD_HAS_DEVICE(kbd)
		    && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
		    && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
			return ENXIO;
		}
		atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		get_typematic(kbd);
		delay[0] = kbd->kb_delay1;
		delay[1] = kbd->kb_delay2;
		atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
		KBD_FOUND_DEVICE(kbd);
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0) {
			return ENXIO;
		}
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Пример #9
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	atkbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	int *data = (int *)arg;

	/* XXX */
	if (unit == ATKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
			return 0;
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size =
			sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT);
		if (kbd == NULL)
			return ENOMEM;
		bzero(kbd, sizeof(*kbd));
		state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
		keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
		accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
		fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
		if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
		     || (fkeymap == NULL)) {
			if (state != NULL)
				free(state, M_DEVBUF);
			if (keymap != NULL)
				free(keymap, M_DEVBUF);
			if (accmap != NULL)
				free(accmap, M_DEVBUF);
			if (fkeymap != NULL)
				free(fkeymap, M_DEVBUF);
			free(kbd, M_DEVBUF);
			return ENOMEM;
		}
		bzero(state, sizeof(*state));
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (atkbd_state_t *)kbd->kb_data;
		bzero(state, sizeof(*state));
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		state->kbdc = kbdc_open(data[0]);
		if (state->kbdc == NULL)
			return ENXIO;
		kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
				data[0], IO_KBDSIZE);
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		      imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;
	
		if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
			if (flags & KB_CONF_FAIL_IF_NO_KBD)
				return ENXIO;
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		atkbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		/* 
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_HAS_DEVICE(kbd)
	    	    && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
	    	    && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
			return ENXIO;
		atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0)
			return ENXIO;
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Пример #10
0
static int 
adb_kbd_attach(device_t dev) 
{
	struct adb_kbd_softc *sc;
	keyboard_switch_t *sw;
	uint32_t fkeys;
	phandle_t handle;

	sw = kbd_get_switch(KBD_DRIVER_NAME);
	if (sw == NULL) {
		return ENXIO;
	}

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_mode = K_RAW;
	sc->sc_state = 0;
	sc->have_led_control = 0;
	sc->buffers = 0;

	/* Try stepping forward to the extended keyboard protocol */
	adb_set_device_handler(dev,3);

	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
	callout_init(&sc->sc_repeater, 0);

#ifdef AKBD_EMULATE_ATKBD
	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
            sizeof(fkey_tab) / sizeof(fkey_tab[0]));
#else
	#error ADB raw mode not implemented
#endif

	KBD_FOUND_DEVICE(&sc->sc_kbd);
	KBD_PROBE_DONE(&sc->sc_kbd);
	KBD_INIT_DONE(&sc->sc_kbd);
	KBD_CONFIG_DONE(&sc->sc_kbd);

	(*sw->enable)(&sc->sc_kbd);

	kbd_register(&sc->sc_kbd);

#ifdef KBD_INSTALL_CDEV
	if (kbd_attach(&sc->sc_kbd)) {
		adb_kbd_detach(dev);
		return ENXIO;
	}
#endif

	/* Check if we can read out the LED state from 
	   this keyboard by reading the key state register */
	if (adb_read_register(dev, 2, NULL) == 2)
		sc->have_led_control = 1;

	adb_set_autopoll(dev,1);

	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
	    &fkeys, sizeof(fkeys)) != -1) {
		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
		struct sysctl_ctx_list *ctx;
		struct sysctl_oid *tree;
		int i;

		if (bootverbose)
			device_printf(dev, "Keyboard has embedded Fn keys\n");

		for (i = 0; i < 12; i++) {
			uint32_t keyval;
			char buf[3];
			if (OF_getprop(handle, key_names[i], &keyval,
			    sizeof(keyval)) < 0)
				continue;
			buf[0] = 1;
			buf[1] = i+1;
			buf[2] = keyval;
			adb_write_register(dev, 0, 3, buf);
		}
		adb_write_register(dev, 1, 2, &(uint16_t){0});

		ctx = device_get_sysctl_ctx(dev);
		tree = device_get_sysctl_tree(dev);

		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, adb_fn_keys, "I",
		    "Set the Fn keys to be their F-key type as default");
	}

	return (0);
}
Пример #11
0
/* reset and initialize the device */
static int
ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	ukbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	void **data = (void **)arg;
	struct usb_attach_arg *uaa = (struct usb_attach_arg *)data[0];

	/* XXX */
	if (unit == UKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
			return 0;
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size =
			sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT);
		if (kbd == NULL)
			return ENOMEM;
		bzero(kbd, sizeof(*kbd));
		state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
		keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
		accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
		fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
		if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
		     || (fkeymap == NULL)) {
			if (state != NULL)
				free(state, M_DEVBUF);
			if (keymap != NULL)
				free(keymap, M_DEVBUF);
			if (accmap != NULL)
				free(accmap, M_DEVBUF);
			if (fkeymap != NULL)
				free(fkeymap, M_DEVBUF);
			free(kbd, M_DEVBUF);
			return ENOMEM;
		}
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (ukbd_state_t *)kbd->kb_data;
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, 0, 0);
		bzero(state, sizeof(*state));
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		      imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;

		if (probe_keyboard(uaa, flags))
			return ENXIO;
		else
			KBD_FOUND_DEVICE(kbd);
		ukbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		state->ks_iface = uaa->iface;
		state->ks_uaa = uaa;
		state->ks_ifstate = 0;
		callout_handle_init(&state->ks_timeout_handle);
		/* 
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_HAS_DEVICE(kbd)
		    && init_keyboard((ukbd_state_t *)kbd->kb_data,
				     &kbd->kb_type, kbd->kb_flags))
			return ENXIO;
		ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0)
			return ENXIO;
		if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
			ukbd_timeout((void *)kbd);
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Пример #12
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	atkbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	int delay[2];
	int *data = (int *)arg;	/* data[0]: controller, data[1]: irq */
	int error, needfree;
#ifdef EVDEV_SUPPORT
	struct evdev_dev *evdev;
	char phys_loc[8];
#endif

	/* XXX */
	if (unit == ATKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
			return 0;
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size = nitems(default_fkeytab);
		needfree = 0;
	} else if (*kbdp == NULL) {
		*kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT | M_ZERO);
		state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT | M_ZERO);
		/* NB: these will always be initialized 'cuz !KBD_IS_PROBED */
		keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
		accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
		fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
		needfree = 1;
		if ((kbd == NULL) || (state == NULL) || (keymap == NULL)
		     || (accmap == NULL) || (fkeymap == NULL)) {
			error = ENOMEM;
			goto bad;
		}
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (atkbd_state_t *)kbd->kb_data;
		bzero(state, sizeof(*state));
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
		needfree = 0;
	}

	if (!KBD_IS_PROBED(kbd)) {
		state->kbdc = atkbdc_open(data[0]);
		if (state->kbdc == NULL) {
			error = ENXIO;
			goto bad;
		}
		kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
				0, 0);
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
		    imin(fkeymap_size * sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;
	
		if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
			if (flags & KB_CONF_FAIL_IF_NO_KBD) {
				error = ENXIO;
				goto bad;
			}
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		atkbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		/* 
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
		if (KBD_HAS_DEVICE(kbd)
		    && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
		    && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
			kbd_unregister(kbd);
			error = ENXIO;
			goto bad;
		}
		atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		set_typematic(kbd);
		delay[0] = kbd->kb_delay1;
		delay[1] = kbd->kb_delay2;
		atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);

#ifdef EVDEV_SUPPORT
		/* register as evdev provider on first init */
		if (state->ks_evdev == NULL) {
			snprintf(phys_loc, sizeof(phys_loc), "atkbd%d", unit);
			evdev = evdev_alloc();
			evdev_set_name(evdev, "AT keyboard");
			evdev_set_phys(evdev, phys_loc);
			evdev_set_id(evdev, BUS_I8042, PS2_KEYBOARD_VENDOR,
			    PS2_KEYBOARD_PRODUCT, 0);
			evdev_set_methods(evdev, kbd, &atkbd_evdev_methods);
			evdev_support_event(evdev, EV_SYN);
			evdev_support_event(evdev, EV_KEY);
			evdev_support_event(evdev, EV_LED);
			evdev_support_event(evdev, EV_REP);
			evdev_support_all_known_keys(evdev);
			evdev_support_led(evdev, LED_NUML);
			evdev_support_led(evdev, LED_CAPSL);
			evdev_support_led(evdev, LED_SCROLLL);

			if (evdev_register_mtx(evdev, &Giant))
				evdev_free(evdev);
			else
				state->ks_evdev = evdev;
			state->ks_evdev_state = 0;
		}
#endif

		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0) {
			error = ENXIO;
			goto bad;
		}
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
bad:
	if (needfree) {
		if (state != NULL)
			free(state, M_DEVBUF);
		if (keymap != NULL)
			free(keymap, M_DEVBUF);
		if (accmap != NULL)
			free(accmap, M_DEVBUF);
		if (fkeymap != NULL)
			free(fkeymap, M_DEVBUF);
		if (kbd != NULL) {
			free(kbd, M_DEVBUF);
			*kbdp = NULL;	/* insure ref doesn't leak to caller */
		}
	}
	return error;
}