adb_bt.c revision 1.3.4.1
11.3.4.1Syamt/* $NetBSD: adb_bt.c,v 1.3.4.1 2008/05/16 02:23:53 yamt Exp $ */ 21.1Smacallan 31.1Smacallan/*- 41.1Smacallan * Copyright (c) 2006 Michael Lorenz 51.1Smacallan * All rights reserved. 61.1Smacallan * 71.1Smacallan * Redistribution and use in source and binary forms, with or without 81.1Smacallan * modification, are permitted provided that the following conditions 91.1Smacallan * are met: 101.1Smacallan * 1. Redistributions of source code must retain the above copyright 111.1Smacallan * notice, this list of conditions and the following disclaimer. 121.1Smacallan * 2. Redistributions in binary form must reproduce the above copyright 131.1Smacallan * notice, this list of conditions and the following disclaimer in the 141.1Smacallan * documentation and/or other materials provided with the distribution. 151.1Smacallan * 161.1Smacallan * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Smacallan * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Smacallan * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Smacallan * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Smacallan * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Smacallan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Smacallan * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Smacallan * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Smacallan * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Smacallan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Smacallan * POSSIBILITY OF SUCH DAMAGE. 271.1Smacallan */ 281.1Smacallan 291.1Smacallan#include <sys/cdefs.h> 301.3.4.1Syamt__KERNEL_RCSID(0, "$NetBSD: adb_bt.c,v 1.3.4.1 2008/05/16 02:23:53 yamt Exp $"); 311.1Smacallan 321.1Smacallan#include <sys/param.h> 331.1Smacallan#include <sys/systm.h> 341.1Smacallan#include <sys/kernel.h> 351.1Smacallan#include <sys/device.h> 361.1Smacallan#include <sys/proc.h> 371.1Smacallan 381.1Smacallan#include <dev/wscons/wsconsio.h> 391.1Smacallan#include <dev/wscons/wskbdvar.h> 401.1Smacallan#include <dev/wscons/wsksymdef.h> 411.1Smacallan#include <dev/wscons/wsksymvar.h> 421.1Smacallan#include <dev/wscons/wsmousevar.h> 431.1Smacallan 441.1Smacallan#include <dev/sysmon/sysmonvar.h> 451.1Smacallan#include <dev/sysmon/sysmon_taskq.h> 461.1Smacallan 471.1Smacallan#include <machine/autoconf.h> 481.1Smacallan#include <machine/keyboard.h> 491.1Smacallan#include <machine/adbsys.h> 501.1Smacallan 511.1Smacallan#include <dev/adb/adbvar.h> 521.1Smacallan#include <dev/adb/adb_keymap.h> 531.1Smacallan 541.1Smacallan#include "opt_wsdisplay_compat.h" 551.1Smacallan#include "adbdebug.h" 561.1Smacallan 571.1Smacallan#ifdef ADBBT_DEBUG 581.1Smacallan#define DPRINTF printf 591.1Smacallan#else 601.1Smacallan#define DPRINTF while (0) printf 611.1Smacallan#endif 621.1Smacallan 631.1Smacallan#define BT_VOL_UP 0x06 641.1Smacallan#define BT_VOL_DOWN 0x07 651.1Smacallan#define BT_VOL_MUTE 0x08 661.1Smacallan#define BT_BRT_UP 0x09 671.1Smacallan#define BT_BRT_DOWN 0x0a 681.1Smacallan#define BT_EJECT 0x0b 691.1Smacallan#define BT_F7 0x0c 701.1Smacallan#define BT_NUMLOCK 0x7f 711.1Smacallan 721.2Smattstatic int adbbt_match(device_t, cfdata_t, void *); 731.2Smattstatic void adbbt_attach(device_t, device_t, void *); 741.1Smacallan 751.1Smacallanstruct adbbt_softc { 761.2Smatt device_t sc_dev; 771.1Smacallan struct adb_device *sc_adbdev; 781.1Smacallan struct adb_bus_accessops *sc_ops; 791.2Smatt device_t sc_wskbddev; 801.1Smacallan int sc_msg_len; 811.1Smacallan int sc_event; 821.1Smacallan int sc_poll; 831.1Smacallan int sc_polled_chars; 841.1Smacallan int sc_rawkbd; 851.1Smacallan uint8_t sc_buffer[16]; 861.1Smacallan uint8_t sc_pollbuf[16]; 871.1Smacallan uint8_t sc_trans[16]; 881.1Smacallan uint8_t sc_us; 891.1Smacallan}; 901.1Smacallan 911.1Smacallan/* Driver definition. */ 921.2SmattCFATTACH_DECL_NEW(adbbt, sizeof(struct adbbt_softc), 931.1Smacallan adbbt_match, adbbt_attach, NULL, NULL); 941.1Smacallan 951.1Smacallanextern struct cfdriver adbbt_cd; 961.1Smacallan 971.1Smacallanstatic int adbbt_enable(void *, int); 981.1Smacallanstatic void adbbt_set_leds(void *, int); 991.1Smacallanstatic int adbbt_ioctl(void *, u_long, void *, int, struct lwp *); 1001.1Smacallanstatic void adbbt_handler(void *, int, uint8_t *); 1011.1Smacallan 1021.1Smacallanstruct wskbd_accessops adbbt_accessops = { 1031.1Smacallan adbbt_enable, 1041.1Smacallan adbbt_set_leds, 1051.1Smacallan adbbt_ioctl, 1061.1Smacallan}; 1071.1Smacallan 1081.1Smacallanstruct wskbd_mapdata adbbt_keymapdata = { 1091.1Smacallan akbd_keydesctab, 1101.1Smacallan#ifdef AKBD_LAYOUT 1111.1Smacallan AKBD_LAYOUT, 1121.1Smacallan#else 1131.1Smacallan KB_US, 1141.1Smacallan#endif 1151.1Smacallan}; 1161.1Smacallan 1171.1Smacallanstatic int 1181.2Smattadbbt_match(device_t parent, cfdata_t cf, void *aux) 1191.1Smacallan{ 1201.1Smacallan struct adb_attach_args *aaa = aux; 1211.1Smacallan 1221.1Smacallan if ((aaa->dev->original_addr == ADBADDR_MISC) && 1231.1Smacallan (aaa->dev->handler_id == 0x1f)) 1241.1Smacallan return 100; 1251.1Smacallan else 1261.1Smacallan return 0; 1271.1Smacallan} 1281.1Smacallan 1291.1Smacallanstatic void 1301.2Smattadbbt_attach(device_t parent, device_t self, void *aux) 1311.1Smacallan{ 1321.2Smatt struct adbbt_softc *sc = device_private(self); 1331.1Smacallan struct adb_attach_args *aaa = aux; 1341.1Smacallan struct wskbddev_attach_args a; 1351.1Smacallan 1361.2Smatt sc->sc_dev = self; 1371.1Smacallan sc->sc_ops = aaa->ops; 1381.1Smacallan sc->sc_adbdev = aaa->dev; 1391.1Smacallan sc->sc_adbdev->cookie = sc; 1401.1Smacallan sc->sc_adbdev->handler = adbbt_handler; 1411.1Smacallan sc->sc_us = ADBTALK(sc->sc_adbdev->current_addr, 0); 1421.1Smacallan 1431.1Smacallan sc->sc_msg_len = 0; 1441.1Smacallan sc->sc_rawkbd = 0; 1451.1Smacallan sc->sc_trans[6] = 96; /* F5 */ 1461.1Smacallan sc->sc_trans[7] = 118; /* F4 */ 1471.1Smacallan sc->sc_trans[8] = 99; /* F3 */ 1481.1Smacallan sc->sc_trans[9] = 120; /* F2 */ 1491.1Smacallan sc->sc_trans[10] = 122; /* F1 */ 1501.1Smacallan sc->sc_trans[11] = 111; /* F12 */ 1511.1Smacallan 1521.1Smacallan printf(" addr %d: button device\n", sc->sc_adbdev->current_addr); 1531.1Smacallan 1541.1Smacallan a.console = 0; 1551.1Smacallan a.keymap = &adbbt_keymapdata; 1561.1Smacallan a.accessops = &adbbt_accessops; 1571.1Smacallan a.accesscookie = sc; 1581.1Smacallan 1591.1Smacallan sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint); 1601.1Smacallan} 1611.1Smacallan 1621.1Smacallanstatic void 1631.1Smacallanadbbt_handler(void *cookie, int len, uint8_t *data) 1641.1Smacallan{ 1651.1Smacallan struct adbbt_softc *sc = cookie; 1661.1Smacallan int type; 1671.1Smacallan uint8_t k, keyval, scancode; 1681.1Smacallan 1691.1Smacallan#ifdef ADBBT_DEBUG 1701.1Smacallan int i; 1711.3Scegger printf("%s: %02x - ", device_xname(&sc->sc_dev), sc->sc_us); 1721.1Smacallan for (i = 0; i < len; i++) { 1731.1Smacallan printf(" %02x", data[i]); 1741.1Smacallan } 1751.1Smacallan printf("\n"); 1761.1Smacallan#endif 1771.1Smacallan k = data[2]; 1781.1Smacallan keyval = ADBK_KEYVAL(k); 1791.1Smacallan if ((keyval < 6) || (keyval > 0x0c)) 1801.1Smacallan return; 1811.1Smacallan scancode = sc->sc_trans[keyval]; 1821.1Smacallan 1831.1Smacallan#ifdef WSDISPLAY_COMPAT_RAWKBD 1841.1Smacallan if (sc->sc_rawkbd) { 1851.1Smacallan char cbuf[2]; 1861.1Smacallan int s; 1871.1Smacallan 1881.1Smacallan cbuf[0] = scancode | (k & 0x80); 1891.1Smacallan 1901.1Smacallan s = spltty(); 1911.1Smacallan wskbd_rawinput(sc->sc_wskbddev, cbuf, 1); 1921.1Smacallan splx(s); 1931.1Smacallan } else { 1941.1Smacallan#endif 1951.1Smacallan 1961.1Smacallan /* normal event */ 1971.1Smacallan type = ADBK_PRESS(k) ? 1981.1Smacallan WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; 1991.1Smacallan wskbd_input(sc->sc_wskbddev, type, scancode); 2001.1Smacallan#ifdef WSDISPLAY_COMPAT_RAWKBD 2011.1Smacallan } 2021.1Smacallan#endif 2031.1Smacallan} 2041.1Smacallan 2051.1Smacallanstatic void 2061.1Smacallanadbbt_set_leds(void *cookie, int leds) 2071.1Smacallan{ 2081.1Smacallan /* we have no LEDs */ 2091.1Smacallan} 2101.1Smacallan 2111.1Smacallanstatic int 2121.1Smacallanadbbt_enable(void *v, int on) 2131.1Smacallan{ 2141.1Smacallan return 0; 2151.1Smacallan} 2161.1Smacallan 2171.1Smacallanstatic int 2181.1Smacallanadbbt_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) 2191.1Smacallan{ 2201.1Smacallan#ifdef WSDISPLAY_COMPAT_RAWKBD 2211.1Smacallan struct adbbt_softc *sc = (struct adbbt_softc *) v; 2221.1Smacallan#endif 2231.1Smacallan 2241.1Smacallan switch (cmd) { 2251.1Smacallan 2261.1Smacallan case WSKBDIO_GTYPE: 2271.1Smacallan *(int *)data = WSKBD_TYPE_ADB; 2281.1Smacallan return 0; 2291.1Smacallan#ifdef WSDISPLAY_COMPAT_RAWKBD 2301.1Smacallan case WSKBDIO_SETMODE: 2311.1Smacallan sc->sc_rawkbd = *(int *)data == WSKBD_RAW; 2321.1Smacallan return 0; 2331.1Smacallan#endif 2341.1Smacallan } 2351.1Smacallan 2361.1Smacallan return EPASSTHROUGH; 2371.1Smacallan} 238