Module Name: src
Committed By: hkenken
Date: Sat Mar 29 12:00:27 UTC 2014
Modified Files:
src/sys/arch/arm/imx: imxspi.c
src/sys/arch/evbarm/conf: NETWALKER files.netwalker
src/sys/arch/evbarm/netwalker: netwalker_machdep.c
Added Files:
src/sys/arch/evbarm/netwalker: netwalker_btn.c netwalker_spi.c
src/sys/dev/spi: oj6sh.c
Log Message:
Add optical joystick support for NetWalker.
+ OJ6SH-T25 (Sharp "Optical TOUCH CRUISER" sensor)
+ 2 Mouse buttons (GPIO)
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/imxspi.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/evbarm/conf/NETWALKER
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/conf/files.netwalker
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/netwalker/netwalker_btn.c \
src/sys/arch/evbarm/netwalker/netwalker_spi.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/evbarm/netwalker/netwalker_machdep.c
cvs rdiff -u -r0 -r1.1 src/sys/dev/spi/oj6sh.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/imx/imxspi.c
diff -u src/sys/arch/arm/imx/imxspi.c:1.1 src/sys/arch/arm/imx/imxspi.c:1.2
--- src/sys/arch/arm/imx/imxspi.c:1.1 Sat Mar 22 09:28:08 2014
+++ src/sys/arch/arm/imx/imxspi.c Sat Mar 29 12:00:27 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: imxspi.c,v 1.1 2014/03/22 09:28:08 hkenken Exp $ */
+/* $NetBSD: imxspi.c,v 1.2 2014/03/29 12:00:27 hkenken Exp $ */
/*-
* Copyright (c) 2014 Genetec Corporation. All rights reserved.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imxspi.c,v 1.1 2014/03/22 09:28:08 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imxspi.c,v 1.2 2014/03/29 12:00:27 hkenken Exp $");
#include "opt_imx.h"
#include "opt_imxspi.h"
@@ -391,7 +391,7 @@ imxspi_intr(void *arg)
/* RXFIFO ready */
if (sr & IMXSPI(INTR_RR_EN)) {
imxspi_recv(sc);
- if(sc->sc_wchunk == NULL &&sc->sc_rchunk == NULL)
+ if (sc->sc_wchunk == NULL && sc->sc_rchunk == NULL)
imxspi_done(sc, err);
}
@@ -408,7 +408,7 @@ imxspi_transfer(void *arg, struct spi_tr
int s;
/* make sure we select the right chip */
- s = splserial();
+ s = splbio();
spi_transq_enqueue(&sc->sc_q, st);
if (sc->sc_running == FALSE)
imxspi_sched(sc);
Index: src/sys/arch/evbarm/conf/NETWALKER
diff -u src/sys/arch/evbarm/conf/NETWALKER:1.24 src/sys/arch/evbarm/conf/NETWALKER:1.25
--- src/sys/arch/evbarm/conf/NETWALKER:1.24 Mon Mar 24 14:15:37 2014
+++ src/sys/arch/evbarm/conf/NETWALKER Sat Mar 29 12:00:27 2014
@@ -1,4 +1,4 @@
-# $NetBSD: NETWALKER,v 1.24 2014/03/24 14:15:37 szptvlfn Exp $
+# $NetBSD: NETWALKER,v 1.25 2014/03/29 12:00:27 hkenken Exp $
#
# NETWALKER -- http://www.sharp.co.jp/netwalker/
#
@@ -128,7 +128,7 @@ options NO_POWERSAVE # uncomment this t
# Development and Debugging options
#options PERFCTRS # performance counters
-options DIAGNOSTIC # internally consistency checks
+#options DIAGNOSTIC # internally consistency checks
#options DEBUG
#options KMEMSTATS # kernel memory statistics (vmstat -m)
options DDB # in-kernel debugger
@@ -151,6 +151,7 @@ makeoptions DEBUG="-g" # compile full sy
# Kernel root file system and dump configuration.
config netbsd root on ? type ?
+config netbsd-ld0 root on ld0 type ffs
# The main bus device
mainbus0 at root
@@ -175,6 +176,7 @@ imxuart0 at axi? addr 0x73fbc000 irq 31
# Clock Control
imxccm0 at axi? addr 0x73fd4000
options IMX51_CKIL_FREQ=32768
+#options IMXCCMDEBUG
# Enhanced Periodic Interrupt Timer
imxclock0 at axi? addr 0x73fac000 size 0x4000 irq 40
@@ -183,11 +185,46 @@ imxclock1 at axi? addr 0x73fb0000 size 0
# IOMUX
imxiomux0 at axi? addr 0x73fa8000
+# WatchDog
+imxwdog0 at axi? addr 0x73f98000 irq 58 flags 0
+
# GPIO
-imxgpio0 at axi? addr 0x73f84000
-imxgpio1 at axi? addr 0x73f88000
-imxgpio2 at axi? addr 0x73f8c000
-imxgpio3 at axi? addr 0x73f90000
+imxgpio0 at axi? addr 0x73f84000 irqbase 128 irq 50
+imxgpio1 at axi? addr 0x73f88000 irqbase 160 irq 52
+imxgpio2 at axi? addr 0x73f8c000 irqbase 192 irq 54
+imxgpio3 at axi? addr 0x73f90000 irqbase 224 irq 56
+gpio* at imxgpio?
+options IMX_GPIO_INTR_SPLIT
+
+# I2C
+#imxi2c0 at axi? addr 0x83fc8000 irq 62
+#imxi2c1 at axi? addr 0x83fc4000 irq 63
+
+# IIC
+#iic* at imxi2c?
+
+# SPI bus
+imxspi0 at axi? addr 0x70010000 irq 36 flags 1
+#imxspi1 at axi? addr 0x83fac000 irq 37 flags 1
+#imxspi2 at axi? addr 0x83fc0000 irq 38 flags 0
+spi0 at imxspi0 # eCSPI1
+#spi1 at imxspi1 # eCSPI2
+#spi2 at imxspi2 # CSPI1
+options IMXSPINSLAVES=3
+#options IMXSPI_DEBUG=10
+
+# Optical Joystick
+mousebtn0 at gpio1 offset 22 mask 0x03 # intr 182, 183
+#options MOUSEBTN_POLLING
+oj6sh0 at spi0 slave 2
+#options OJ6SH_DEBUG=4
+options OJ6SH_UP_X_LEFT_Y
+wsmouse* at oj6sh? mux 0
+wsmouse* at mousebtn? mux 0
+
+# SPI NOR-Flash
+#spiflash0 at spiflashbus?
+#m25p0 at spi0 slave 1
# SD/MMC
sdhc0 at axi? addr 0x70004000 irq 1 # eSDHC1
@@ -238,9 +275,9 @@ pseudo-device swcrypto # software crypt
# disk/mass storage pseudo-devices
#pseudo-device md # memory disk device (ramdisk)
-#pseudo-device vnd # disk-like interface to files
+pseudo-device vnd # disk-like interface to files
#pseudo-device fss # file system snapshot device
-#pseudo-device putter # for puffs and pud
+pseudo-device putter # for puffs and pud
# network pseudo-devices
pseudo-device bpfilter # Berkeley packet filter
@@ -250,12 +287,20 @@ pseudo-device loop # network loopback
# miscellaneous pseudo-devices
pseudo-device pty # pseudo-terminals
-pseudo-device ksyms # /dev/ksyms
pseudo-device clockctl # NTP clockctl
+pseudo-device ksyms # /dev/ksyms
+pseudo-device lockstat # lock profiling
# wscons pseudo-devices
pseudo-device wsmux # mouse & keyboard multiplexor
pseudo-device wsfont
+# data mover pseudo-devices
+#pseudo-device swdmover # software dmover(9) back-end
+#pseudo-device dmoverio # /dev/dmover dmover(9) interface
+
+# userland interface to drivers, including autoconf and properties retrieval
+pseudo-device drvctl
+
# local configuration
cinclude "arch/evbarm/conf/NETWALKER.local"
Index: src/sys/arch/evbarm/conf/files.netwalker
diff -u src/sys/arch/evbarm/conf/files.netwalker:1.4 src/sys/arch/evbarm/conf/files.netwalker:1.5
--- src/sys/arch/evbarm/conf/files.netwalker:1.4 Fri Jan 24 02:06:03 2014
+++ src/sys/arch/evbarm/conf/files.netwalker Sat Mar 29 12:00:27 2014
@@ -1,6 +1,6 @@
-# $NetBSD: files.netwalker,v 1.4 2014/01/24 02:06:03 hkenken Exp $
+# $NetBSD: files.netwalker,v 1.5 2014/03/29 12:00:27 hkenken Exp $
#
-# Sharp Netwalker
+# Sharp Netwalker configuration info
#
file arch/arm/arm32/arm32_boot.c
@@ -23,3 +23,23 @@ file arch/evbarm/netwalker/netwalker_u
attach ipu at axi with lcd_netwalker
file arch/evbarm/netwalker/netwalker_lcd.c lcd_netwalker
defflag opt_netwalker_lcd.h LCD_DEBUG
+
+# CSPI & eCSPI Controller
+attach imxspi at axi with spi_netwalker
+file arch/evbarm/netwalker/netwalker_spi.c spi_netwalker
+
+# Mouse button
+device mousebtn: wsmousedev
+attach mousebtn at gpio with btn_netwalker
+file arch/evbarm/netwalker/netwalker_btn.c btn_netwalker
+defflag opt_mousebtn.h MOUSEBTN_POLLING
+
+# OJ6SH-T25 Optical Joystick
+device oj6sh: wsmousedev
+attach oj6sh at spi
+file dev/spi/oj6sh.c oj6sh
+defflag opt_oj6sh.h OJ6SH_UP_Y_RIGHT_X
+ OJ6SH_DOWN_Y_LEFT_X
+ OJ6SH_UP_X_LEFT_Y
+ OJ6SH_DOWN_X_RIGHT_Y
+
Index: src/sys/arch/evbarm/netwalker/netwalker_machdep.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.13 src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.14
--- src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.13 Fri Jan 24 02:06:03 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_machdep.c Sat Mar 29 12:00:27 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: netwalker_machdep.c,v 1.13 2014/01/24 02:06:03 hkenken Exp $ */
+/* $NetBSD: netwalker_machdep.c,v 1.14 2014/03/29 12:00:27 hkenken Exp $ */
/*
* Copyright (c) 2002, 2003, 2005, 2010 Genetec Corporation.
@@ -102,8 +102,10 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.13 2014/01/24 02:06:03 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.14 2014/03/29 12:00:27 hkenken Exp $");
+#include "opt_evbarm_boardtype.h"
+#include "opt_cputypes.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_md.h"
@@ -467,6 +469,8 @@ const struct iomux_setup iomux_setup_dat
IOMUX_MP(EIM_D27, ALT3, KEEPER | PU_100K | DSEHIGH | SRE), /* RTS */
IOMUX_M(NANDF_D15, ALT3), /* GPIO3_25 */
IOMUX_MP(NANDF_D14, ALT3, HYS | PULL | PU_100K ), /* GPIO3_26 */
+
+ /* OJ6SH-T25 */
IOMUX_M(CSI1_D9, ALT3), /* GPIO3_13 */
IOMUX_M(CSI1_VSYNC, ALT3), /* GPIO3_14 */
IOMUX_M(CSI1_HSYNC, ALT3), /* GPIO3_15 */
@@ -488,13 +492,15 @@ const struct iomux_setup iomux_setup_dat
/* XXX more audio pins ? */
/* CSPI */
- /* ??? doesn't work ??? */
- IOMUX_P(CSPI1_MOSI, HYS | PULL | PD_100K | DSEHIGH | SRE),
- IOMUX_P(CSPI1_MISO, HYS | PULL | PD_100K | DSEHIGH | SRE),
- IOMUX_M(CSPI1_SS0, ALT3),
- IOMUX_MP(CSPI1_SS1, ALT0, HYS | KEEPER | DSEHIGH | SRE),
- IOMUX_MP(DI1_PIN11, ALT7, HYS | PULL | DSEHIGH | SRE),
- IOMUX_P(CSPI1_SCLK, HYS | KEEPER | DSEHIGH | SRE),
+ IOMUX_MP(CSPI1_MOSI, ALT0, HYS | PULL | PD_100K | DSEHIGH | SRE),
+ IOMUX_MP(CSPI1_MISO, ALT0, HYS | PULL | PD_100K | DSEHIGH | SRE),
+ IOMUX_MP(CSPI1_SCLK, ALT0, HYS | PULL | PD_100K | DSEHIGH | SRE),
+
+ /* SPI CS */
+ IOMUX_MP(CSPI1_SS0, ALT3, HYS | KEEPER | DSEHIGH | SRE), /* GPIO4[24] */
+ IOMUX_MP(CSPI1_SS1, ALT3, HYS | KEEPER | DSEHIGH | SRE), /* GPIO4[25] */
+ IOMUX_MP(DI1_PIN11, ALT4, HYS | PULL | DSEHIGH | SRE), /* GPIO3[0] */
+
/* 26M Osc */
IOMUX_MP(DI1_PIN12, ALT4, KEEPER | DSEHIGH | SRE), /* GPIO3_1 */
@@ -504,7 +510,7 @@ const struct iomux_setup iomux_setup_dat
IOMUX_MP(KEY_COL5, SION | ALT3, HYS | ODE | DSEHIGH | SRE),
IOMUX_DATA(IOMUXC_I2C2_IPP_SDA_IN_SELECT_INPUT, INPUT_DAISY_1),
IOMUX_DATA(IOMUXC_UART3_IPP_UART_RTS_B_SELECT_INPUT, INPUT_DAISY_3),
-#if 1
+
/* NAND */
IOMUX_MP(NANDF_WE_B, ALT0, HVE | DSEHIGH | PULL | PU_47K),
IOMUX_MP(NANDF_RE_B, ALT0, HVE | DSEHIGH | PULL | PU_47K),
@@ -521,7 +527,6 @@ const struct iomux_setup iomux_setup_dat
IOMUX_MP(NANDF_D2, ALT0, HVE | DSEHIGH | KEEPER | PU_100K),
IOMUX_MP(NANDF_D1, ALT0, HVE | DSEHIGH | KEEPER | PU_100K),
IOMUX_MP(NANDF_D0, ALT0, HVE | DSEHIGH | KEEPER | PU_100K),
-#endif
/* Batttery pins */
IOMUX_MP(NANDF_D13, ALT3, HYS | DSEHIGH),
Added files:
Index: src/sys/arch/evbarm/netwalker/netwalker_btn.c
diff -u /dev/null src/sys/arch/evbarm/netwalker/netwalker_btn.c:1.1
--- /dev/null Sat Mar 29 12:00:27 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_btn.c Sat Mar 29 12:00:27 2014
@@ -0,0 +1,325 @@
+/* $NetBSD: netwalker_btn.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $ */
+
+/*
+ * Copyright (c) 2014 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netwalker_btn.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $");
+
+#include "opt_imxspi.h"
+#include "opt_mousebtn.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/lock.h>
+#include <sys/callout.h>
+#include <sys/gpio.h>
+#include <sys/bus.h>
+#include <sys/mutex.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <dev/gpio/gpiovar.h>
+
+#define GPIO1_BASE 160
+
+#define MOUSEBTN_PIN_LEFT 0
+#define MOUSEBTN_PIN_RIGHT 1
+#define MOUSEBTN_NPINS 2
+
+#define POLLRATE (hz/10)
+
+struct mousebtn_softc
+{
+ device_t sc_dev;
+ void *sc_gpio;
+ void *sc_intr[MOUSEBTN_NPINS];
+
+ struct gpio_pinmap sc_map;
+ int sc_map_pins[MOUSEBTN_NPINS];
+
+ int sc_buttons;
+
+ struct callout sc_c;
+ kmutex_t sc_lock;
+
+ int sc_enabled;
+ struct device *sc_wsmousedev;
+};
+
+static int mousebtn_match(device_t, cfdata_t, void *);
+static void mousebtn_attach(device_t, device_t, void *);
+static int mousebtn_detach(device_t, int);
+
+CFATTACH_DECL_NEW(btn_netwalker, sizeof(struct mousebtn_softc),
+ mousebtn_match, mousebtn_attach, mousebtn_detach, NULL);
+
+static void mousebtn_poll(void *);
+static int mousebtn_intr(void *);
+
+static int mousebtn_enable(void *v);
+static void mousebtn_disable(void *v);
+static int mousebtn_ioctl(void *, u_long, void *, int, struct lwp *);
+
+static bool mousebtn_resume(device_t, const pmf_qual_t *);
+static bool mousebtn_suspend(device_t, const pmf_qual_t *);
+
+static const struct wsmouse_accessops mousebtn_accessops = {
+ .enable = mousebtn_enable,
+ .ioctl = mousebtn_ioctl,
+ .disable = mousebtn_disable
+};
+
+static int
+mousebtn_match(device_t parent, cfdata_t cf, void * aux)
+{
+ struct gpio_attach_args *ga = aux;
+
+ if (strcmp(ga->ga_dvname, cf->cf_name))
+ return 0;
+ if (ga->ga_offset == -1)
+ return 0;
+
+ /* check that we have enough pins */
+ if (gpio_npins(ga->ga_mask) != MOUSEBTN_NPINS) {
+ aprint_debug("%s: invalid pin mask 0x%02x\n", cf->cf_name,
+ ga->ga_mask);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+mousebtn_attach(device_t parent, device_t self, void *aux)
+{
+ struct mousebtn_softc *sc = device_private(self);
+ struct gpio_attach_args *ga = aux;
+ int caps;
+ struct wsmousedev_attach_args a;
+
+ sc->sc_dev = self;
+ sc->sc_gpio = ga->ga_gpio;
+
+ /* map pins */
+ sc->sc_map.pm_map = sc->sc_map_pins;
+ if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
+ &sc->sc_map)) {
+ aprint_error(": couldn't map the pins\n");
+ return;
+ }
+
+ /* configure left pin */
+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, MOUSEBTN_PIN_LEFT);
+ if (!(caps & GPIO_PIN_INPUT)) {
+ aprint_error(": pin is unable to read input\n");
+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
+ return;
+ }
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, MOUSEBTN_PIN_LEFT,
+ GPIO_PIN_INPUT);
+
+ /* configure right pin */
+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, MOUSEBTN_PIN_RIGHT);
+ if (!(caps & GPIO_PIN_INPUT)) {
+ aprint_error(": pin is unable to read input\n");
+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
+ return;
+ }
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, MOUSEBTN_PIN_RIGHT,
+ GPIO_PIN_INPUT);
+
+ /* interrupt settings */
+ sc->sc_intr[0] = intr_establish(GPIO1_BASE + ga->ga_offset,
+ IPL_VM, IST_EDGE_BOTH, mousebtn_intr, sc);
+ if (sc->sc_intr[0] == NULL) {
+ aprint_error(": couldn't establish interrupt\n");
+ return;
+ }
+ sc->sc_intr[1] = intr_establish(GPIO1_BASE + ga->ga_offset + 1,
+ IPL_VM, IST_EDGE_BOTH, mousebtn_intr, sc);
+ if (sc->sc_intr[1] == NULL) {
+ aprint_error(": couldn't establish interrupt\n");
+ intr_disestablish(sc->sc_intr[0]);
+ return;
+ }
+
+ aprint_normal(": NetWalker mouse button\n");
+ aprint_naive(": NetWalker mouse button\n");
+
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+ callout_init(&sc->sc_c, 0);
+
+ a.accessops = &mousebtn_accessops;
+ a.accesscookie = sc;
+
+ sc->sc_buttons = 0;
+ sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+}
+
+static int
+mousebtn_detach(device_t self, int flags)
+{
+ struct mousebtn_softc *sc = device_private(self);
+
+ if (sc->sc_intr[0] != NULL)
+ intr_disestablish(sc->sc_intr[0]);
+ if (sc->sc_intr[1] != NULL)
+ intr_disestablish(sc->sc_intr[1]);
+
+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
+
+ return 0;
+}
+
+static void
+mousebtn_poll(void *arg)
+{
+ struct mousebtn_softc *sc = (struct mousebtn_softc *)arg;
+ uint32_t buttons = 0;
+ int s;
+ int left;
+ int right;
+
+ mutex_enter(&sc->sc_lock);
+
+ left = !gpio_pin_read(sc->sc_gpio, &sc->sc_map, MOUSEBTN_PIN_LEFT);
+ right = !gpio_pin_read(sc->sc_gpio, &sc->sc_map, MOUSEBTN_PIN_RIGHT);
+ buttons = (right << 2) | left;
+
+ if (sc->sc_buttons != buttons) {
+ s = spltty();
+ wsmouse_input(sc->sc_wsmousedev, buttons, 0, 0, 0, 0,
+ WSMOUSE_INPUT_DELTA);
+ sc->sc_buttons = buttons;
+ splx(s);
+ }
+
+ mutex_exit(&sc->sc_lock);
+
+#if defined(MOUSEBTN_POLLING)
+ if (sc->sc_enabled)
+ callout_reset(&sc->sc_c, POLLRATE, mousebtn_poll, sc);
+#endif
+ return;
+}
+
+static int
+mousebtn_intr(void *v)
+{
+ struct mousebtn_softc *sc = v;
+
+ if (sc->sc_enabled)
+ callout_reset(&sc->sc_c, POLLRATE, mousebtn_poll, sc);
+
+ return 1;
+}
+
+
+int
+mousebtn_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
+{
+ struct wsmouse_id *id;
+
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_PS2;
+ return 0;
+ case WSMOUSEIO_GETID:
+ id = (struct wsmouse_id *)data;
+ if (id->type != WSMOUSE_ID_TYPE_UIDSTR)
+ return EINVAL;
+ strlcpy(id->data, "NetWalker Mouse Button", WSMOUSE_ID_MAXLEN);
+ id->length = strlen(id->data);
+ return 0;
+ }
+
+ return EPASSTHROUGH;
+}
+
+int
+mousebtn_enable(void *v)
+{
+ struct mousebtn_softc *sc = (struct mousebtn_softc *)v;
+
+ if (sc->sc_enabled)
+ return EBUSY;
+
+ if (!pmf_device_register(sc->sc_dev, mousebtn_suspend, mousebtn_resume))
+ aprint_error_dev(sc->sc_dev,
+ "couldn't establish power handler\n");
+
+ sc->sc_enabled = 1;
+#if defined(MOUSEBTN_POLLING)
+ callout_reset(&sc->sc_c, POLLRATE, mousebtn_poll, sc);
+#endif
+
+ return 0;
+}
+
+void
+mousebtn_disable(void *v)
+{
+ struct mousebtn_softc *sc = (struct mousebtn_softc *)v;
+
+ if (!sc->sc_enabled)
+ return;
+
+ pmf_device_deregister(sc->sc_dev);
+
+ sc->sc_enabled = 0;
+
+ return;
+}
+
+static bool
+mousebtn_suspend(device_t dv, const pmf_qual_t *qual)
+{
+ struct mousebtn_softc *sc = device_private(dv);
+
+#if defined(MOUSEBTN_POLLING)
+ callout_stop(&sc->sc_c);
+#endif
+ sc->sc_enabled = 0;
+
+ return true;
+}
+
+static bool
+mousebtn_resume(device_t dv, const pmf_qual_t *qual)
+{
+ struct mousebtn_softc *sc = device_private(dv);
+
+ sc->sc_enabled = 1;
+#if defined(MOUSEBTN_POLLING)
+ callout_reset(&sc->sc_c, POLLRATE, mousebtn_poll, sc);
+#endif
+ return true;
+}
+
Index: src/sys/arch/evbarm/netwalker/netwalker_spi.c
diff -u /dev/null src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.1
--- /dev/null Sat Mar 29 12:00:27 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_spi.c Sat Mar 29 12:00:27 2014
@@ -0,0 +1,152 @@
+/* $NetBSD: netwalker_spi.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $ */
+
+/*-
+ * Copyright (c) 2009 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netwalker_spi.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $");
+
+#include "opt_imxspi.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+#include <arm/imx/imx51_ccmvar.h>
+#include <arm/imx/imx51_ccmreg.h>
+#include <arm/imx/imx51_iomuxreg.h>
+#include <arm/imx/imxgpiovar.h>
+#include <arm/imx/imxspivar.h>
+
+struct imx51spi_softc {
+ struct imxspi_softc sc_spi;
+ struct spi_chipset_tag sc_tag;
+};
+
+CFATTACH_DECL_NEW(spi_netwalker, sizeof(struct imx51spi_softc),
+ imxspi_match, imxspi_attach, NULL, NULL);
+
+static int
+imxspi_cs_enable(void *arg, int slave)
+{
+ switch (slave) {
+ case 0:
+ gpio_data_write(GPIO_NO(4, 24), 0);
+ gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_OUT);
+ break;
+ case 1:
+ gpio_data_write(GPIO_NO(4, 25), 0);
+ gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_OUT);
+ break;
+ case 2:
+ gpio_data_write(GPIO_NO(3, 0), 0);
+ gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_OUT);
+ break;
+ }
+
+ return 0;
+}
+
+static int
+imxspi_cs_disable(void *arg, int slave)
+{
+ switch (slave) {
+ case 0:
+ gpio_data_write(GPIO_NO(4, 24), 1);
+ gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_IN);
+ break;
+ case 1:
+ gpio_data_write(GPIO_NO(4, 25), 1);
+ gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_IN);
+ break;
+ case 2:
+ gpio_data_write(GPIO_NO(3, 0), 1);
+ gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_IN);
+ break;
+ }
+
+ return 0;
+}
+
+int
+imxspi_match(device_t parent, cfdata_t cf, void *aux)
+{
+ if (strcmp(cf->cf_name, "imxspi") == 0)
+ return 1;
+ if (cf->cf_unit != 0)
+ return 1;
+
+ return 0;
+}
+
+void
+imxspi_attach(device_t parent, device_t self, void *aux)
+{
+ struct imx51spi_softc *sc = device_private(self);
+ struct axi_attach_args *aa = aux;
+ struct imxspi_attach_args saa;
+ int cf_flags = device_cfdata(self)->cf_flags;
+
+ sc->sc_tag.cookie = sc;
+
+ if (device_cfdata(self)->cf_unit == 0) {
+ /* CS 0 GPIO setting */
+ gpio_data_write(GPIO_NO(4, 24), 1);
+ gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_IN);
+
+ /* CS 1 GPIO setting */
+ gpio_data_write(GPIO_NO(4, 25), 1);
+ gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_IN);
+
+ /* CS 2 */
+ /* OJ6SH-T25 Shutdown */
+ gpio_data_write(GPIO_NO(3, 14), 0);
+ gpio_set_direction(GPIO_NO(3, 14), GPIO_DIR_OUT);
+
+ /* CS 2 GPIO setting */
+ gpio_data_write(GPIO_NO(3, 0), 1);
+ gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_IN);
+
+ sc->sc_tag.spi_cs_enable = imxspi_cs_enable;
+ sc->sc_tag.spi_cs_disable = imxspi_cs_disable;
+ }
+
+ saa.saa_iot = aa->aa_iot;
+ saa.saa_addr = aa->aa_addr;
+ saa.saa_size = aa->aa_size;
+ saa.saa_irq = aa->aa_irq;
+ saa.saa_enhanced = cf_flags;
+
+ saa.saa_nslaves = IMXSPINSLAVES;
+ saa.saa_freq = imx51_get_clock(IMX51CLK_CSPI_CLK_ROOT);
+ saa.saa_tag = &sc->sc_tag;
+
+ sc->sc_spi.sc_dev = self;
+
+ imxspi_attach_common(parent, &sc->sc_spi, &saa);
+}
Index: src/sys/dev/spi/oj6sh.c
diff -u /dev/null src/sys/dev/spi/oj6sh.c:1.1
--- /dev/null Sat Mar 29 12:00:27 2014
+++ src/sys/dev/spi/oj6sh.c Sat Mar 29 12:00:27 2014
@@ -0,0 +1,379 @@
+/* $NetBSD: oj6sh.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $ */
+
+/*
+ * Copyright (c) 2014 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Sharp NetWalker's Optical Joystick
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: oj6sh.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $");
+
+#include "opt_oj6sh.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/lock.h>
+#include <sys/callout.h>
+#include <sys/bus.h>
+#include <sys/mutex.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+#include <dev/hpc/hpcfbio.h>
+#include <dev/hpc/hpctpanelvar.h>
+
+#include <dev/spi/spivar.h>
+
+#ifdef OJ6SH_DEBUG
+int oj6sh_debug = OJ6SH_DEBUG;
+#define DPRINTF(n,x) if (oj6sh_debug>(n)) printf x;
+#else
+#define DPRINTF(n,x)
+#endif
+
+#define POLLRATE (hz/30)
+
+/* register address */
+#define OJ6SH_PRODUCT 0x00
+#define OJ6SH_REVISION 0x01
+#define OJ6SH_MOTION 0x02
+#define OJ6SH_DELTA_X 0x03
+#define OJ6SH_DELTA_Y 0x04
+#define OJ6SH_SQUAL 0x05
+#define OJ6SH_SHUTTER 0x06
+#define OJ6SH_CONFIG 0x11
+#define OJ6SH_RESET 0x3a
+#define POWERON_RESET 0x5a
+#define OJ6SH_N_REVISION 0x3e
+#define OJ6SH_N_PRODUCT 0x3f
+
+struct oj6sh_softc {
+ device_t sc_dev;
+
+ struct spi_handle *sc_sh;
+ struct callout sc_c;
+
+ kmutex_t sc_lock;
+ int sc_enabled;
+
+ device_t sc_wsmousedev;
+};
+
+struct oj6sh_delta {
+ int x;
+ int y;
+};
+
+static uint8_t oj6sh_read(struct spi_handle *, uint8_t);
+static void oj6sh_write(struct spi_handle *, uint8_t, uint8_t);
+
+static int oj6sh_match(device_t , cfdata_t , void *);
+static void oj6sh_attach(device_t , device_t , void *);
+
+CFATTACH_DECL_NEW(oj6sh, sizeof(struct oj6sh_softc),
+ oj6sh_match, oj6sh_attach, NULL, NULL);
+
+static bool oj6sh_motion(struct spi_handle *);
+static bool oj6sh_squal(struct spi_handle *);
+static bool oj6sh_shuttrer(struct spi_handle *);
+static int oj6sh_readdelta(struct spi_handle *, struct oj6sh_delta *);
+
+static void oj6sh_poll(void *);
+static int oj6sh_enable(void *v);
+static void oj6sh_disable(void *v);
+static int oj6sh_ioctl(void *, u_long, void *, int, struct lwp *);
+
+static bool oj6sh_resume(device_t, const pmf_qual_t *);
+static bool oj6sh_suspend(device_t, const pmf_qual_t *);
+
+static const struct wsmouse_accessops oj6sh_accessops = {
+ .enable = oj6sh_enable,
+ .ioctl = oj6sh_ioctl,
+ .disable = oj6sh_disable
+};
+
+static int
+oj6sh_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct spi_attach_args *sa = aux;
+
+ if (strcmp(match->cf_name, "oj6sh"))
+ return 0;
+ if (spi_configure(sa->sa_handle, SPI_MODE_0, 2500000))
+ return 0;
+
+ return 2;
+}
+
+static void
+oj6sh_doattach(device_t self)
+{
+ struct oj6sh_softc *sc = device_private(self);
+ uint8_t product;
+ uint8_t rev;
+ uint8_t product_inv;
+ uint8_t rev_inv;
+
+ /* reset */
+ oj6sh_write(sc->sc_sh, OJ6SH_RESET, POWERON_RESET);
+ delay(10000);
+
+ /* resolution */
+ oj6sh_write(sc->sc_sh, OJ6SH_CONFIG, 0x80);
+
+ product = oj6sh_read(sc->sc_sh, OJ6SH_PRODUCT);
+ rev = oj6sh_read(sc->sc_sh, OJ6SH_REVISION);
+ product_inv = oj6sh_read(sc->sc_sh, OJ6SH_N_PRODUCT);
+ rev_inv = oj6sh_read(sc->sc_sh, OJ6SH_N_REVISION);
+
+ if (((product | product_inv) != 0xff) || ((rev | rev_inv) != 0xff)) {
+ aprint_error_dev(self,
+ "mismatch product (%02x:%02x), rev (%02x:%02x)\n",
+ product, product_inv, rev, rev_inv);
+ return;
+ }
+
+ aprint_normal("%s: id 0x%02x, revision 0x%02x\n",
+ device_xname(sc->sc_dev), product, rev);
+
+ return;
+}
+
+static void
+oj6sh_attach(device_t parent, device_t self, void *aux)
+{
+ struct oj6sh_softc *sc = device_private(self);
+ struct spi_attach_args *sa = aux;
+ struct wsmousedev_attach_args a;
+
+ aprint_normal(": OJ6SH-T25 Optical Joystick\n");
+
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+
+ sc->sc_dev = self;
+ sc->sc_enabled = 0;
+
+ callout_init(&sc->sc_c, 0);
+
+ sc->sc_sh = sa->sa_handle;
+
+ a.accessops = &oj6sh_accessops;
+ a.accesscookie = sc;
+
+ sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+
+ config_interrupts(self, oj6sh_doattach);
+}
+
+static void
+oj6sh_poll(void *arg)
+{
+ struct oj6sh_softc *sc = (struct oj6sh_softc *)arg;
+ struct oj6sh_delta delta = {0, 0};
+ uint32_t buttons = 0;
+ int s;
+ int x, y;
+
+ mutex_enter(&sc->sc_lock);
+
+ if (oj6sh_motion(sc->sc_sh) == false)
+ goto out;
+ else if ((oj6sh_squal(sc->sc_sh) == true) &&
+ (oj6sh_shuttrer(sc->sc_sh) == true))
+ goto out;
+
+ oj6sh_readdelta(sc->sc_sh, &delta);
+ DPRINTF(3,("%s: x = %d, y = %d\n", device_xname(sc->sc_dev),
+ delta.x, delta.y));
+
+#if defined(J6SH_DOWN_Y_LEFT_X)
+ y = -delta.y;
+ x = -delta.x;
+#elif defined(OJ6SH_UP_X_LEFT_Y)
+ y = delta.x;
+ x = -delta.y;
+#elif defined(OJ6SH_DOWN_X_RIGHT_Y)
+ y = -delta.x;
+ x = delta.y;
+#else /* OJ6SH_UP_Y_RIGHT_X */
+ y = delta.y;
+ x = delta.x;
+#endif
+ s = spltty();
+ wsmouse_input(sc->sc_wsmousedev, buttons, x, y, 0, 0,
+ WSMOUSE_INPUT_DELTA);
+ splx(s);
+out:
+ mutex_exit(&sc->sc_lock);
+
+ if (sc->sc_enabled)
+ callout_reset(&sc->sc_c, POLLRATE, oj6sh_poll, sc);
+
+ return;
+}
+
+static uint8_t
+oj6sh_read(struct spi_handle *spi, uint8_t reg)
+{
+ uint8_t ret = 0;
+
+ spi_send_recv(spi, 1, ®, 1, &ret);
+ DPRINTF(4,("%s: 0x%02x = 0x%02x\n", __func__, reg, ret));
+ return ret;
+}
+
+static void
+oj6sh_write(struct spi_handle *spi, uint8_t reg, uint8_t val)
+{
+ uint8_t tmp[2] = {reg | 0x80, val};
+
+ spi_send(spi, 2, tmp);
+ DPRINTF(4,("%s: 0x%02x = 0x%02x\n", __func__, reg, val));
+ return;
+}
+
+static bool
+oj6sh_motion(struct spi_handle *spi)
+{
+ uint16_t motion;
+ motion = oj6sh_read(spi, OJ6SH_MOTION);
+ return (motion & __BIT(7) ? true : false);
+}
+
+static bool
+oj6sh_squal(struct spi_handle *spi)
+{
+ uint16_t squal;
+ squal = oj6sh_read(spi, OJ6SH_SQUAL);
+ return (squal < 25 ? true : false);
+}
+
+static bool
+oj6sh_shuttrer(struct spi_handle *spi)
+{
+ uint16_t shutter;
+ shutter = oj6sh_read(spi, OJ6SH_SHUTTER) << 8;
+ shutter |= oj6sh_read(spi, OJ6SH_SHUTTER + 1);
+ return (shutter > 600 ? true : false);
+}
+
+static int
+oj6sh_readdelta(struct spi_handle *spi, struct oj6sh_delta *delta)
+{
+ delta->x = (int8_t)oj6sh_read(spi, OJ6SH_DELTA_X);
+ delta->y = (int8_t)oj6sh_read(spi, OJ6SH_DELTA_Y);
+ return 0;
+}
+
+int
+oj6sh_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
+{
+ struct wsmouse_id *id;
+
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_PS2;
+ return 0;
+ case WSMOUSEIO_GETID:
+ id = (struct wsmouse_id *)data;
+ if (id->type != WSMOUSE_ID_TYPE_UIDSTR)
+ return EINVAL;
+ strlcpy(id->data, "OJ6SH-T25", WSMOUSE_ID_MAXLEN);
+ id->length = strlen(id->data);
+ return 0;
+ }
+
+ return EPASSTHROUGH;
+}
+
+int
+oj6sh_enable(void *v)
+{
+ struct oj6sh_softc *sc = (struct oj6sh_softc *)v;
+
+ DPRINTF(3,("%s: oj6sh_enable()\n", device_xname(sc->sc_dev)));
+ if (sc->sc_enabled) {
+ DPRINTF(3,("%s: already enabled\n", device_xname(sc->sc_dev)));
+ return EBUSY;
+ }
+
+ if (!pmf_device_register(sc->sc_dev, oj6sh_suspend, oj6sh_resume))
+ aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n");
+
+ sc->sc_enabled = 1;
+ callout_reset(&sc->sc_c, POLLRATE, oj6sh_poll, sc);
+
+ return 0;
+}
+
+void
+oj6sh_disable(void *v)
+{
+ struct oj6sh_softc *sc = (struct oj6sh_softc *)v;
+
+ DPRINTF(3,("%s: oj6sh_disable()\n", device_xname(sc->sc_dev)));
+ if (!sc->sc_enabled) {
+ DPRINTF(3,("%s: already disabled()\n", device_xname(sc->sc_dev)));
+ return;
+ }
+
+ pmf_device_deregister(sc->sc_dev);
+
+ sc->sc_enabled = 0;
+
+ return;
+}
+
+static bool
+oj6sh_suspend(device_t dv, const pmf_qual_t *qual)
+{
+ struct oj6sh_softc *sc = device_private(dv);
+
+ DPRINTF(3,("%s: oj6sh_suspend()\n", device_xname(sc->sc_dev)));
+ callout_stop(&sc->sc_c);
+ sc->sc_enabled = 0;
+
+ return true;
+}
+
+static bool
+oj6sh_resume(device_t dv, const pmf_qual_t *qual)
+{
+ struct oj6sh_softc *sc = device_private(dv);
+
+ DPRINTF(3,("%s: oj6sh_resume()\n", device_xname(sc->sc_dev)));
+ sc->sc_enabled = 1;
+ callout_reset(&sc->sc_c, POLLRATE, oj6sh_poll, sc);
+
+ return true;
+}
+