Module Name: src Committed By: bouyer Date: Mon Apr 25 20:15:46 UTC 2016
Modified Files: src/sys/arch/arm/allwinner: awin_io.c awin_reg.h files.awin src/sys/arch/evbarm/awin: awin_machdep.c src/sys/arch/evbarm/conf: CUBIEBOARD Added Files: src/sys/arch/arm/allwinner: awin_lradc.c Log Message: Add a driver for the lradc device found in allwinner SoCs. The events are reported as hotkeys press/release to sysmon_power(9). The levels and associated event names are configured in the fex script (the channels remain disabled if no appropriate fex script is provided). To generate a diff of this commit: cvs rdiff -u -r1.44 -r1.45 src/sys/arch/arm/allwinner/awin_io.c cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/allwinner/awin_lradc.c cvs rdiff -u -r1.87 -r1.88 src/sys/arch/arm/allwinner/awin_reg.h cvs rdiff -u -r1.34 -r1.35 src/sys/arch/arm/allwinner/files.awin cvs rdiff -u -r1.47 -r1.48 src/sys/arch/evbarm/awin/awin_machdep.c cvs rdiff -u -r1.45 -r1.46 src/sys/arch/evbarm/conf/CUBIEBOARD 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/allwinner/awin_io.c diff -u src/sys/arch/arm/allwinner/awin_io.c:1.44 src/sys/arch/arm/allwinner/awin_io.c:1.45 --- src/sys/arch/arm/allwinner/awin_io.c:1.44 Sat Dec 26 16:56:41 2015 +++ src/sys/arch/arm/allwinner/awin_io.c Mon Apr 25 20:15:46 2016 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.44 2015/12/26 16:56:41 macallan Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.45 2016/04/25 20:15:46 bouyer Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -190,6 +190,7 @@ static const struct awin_locators awin_l { "awinir", OFFANDSIZE(IR1), 1, AWIN_IRQ_IR1, A10|A20 }, { "awinir", OFFANDSIZE(A31_CIR), NOPORT, AWIN_A31_IRQ_CIR, A31 }, { "awinir", OFFANDSIZE(A80_CIR), NOPORT, AWIN_A80_IRQ_R_CIR, A80 }, + { "awinlradc", OFFANDSIZE(LRADC), NOPORT, AWIN_IRQ_LRADC, A20 }, }; static int Index: src/sys/arch/arm/allwinner/awin_reg.h diff -u src/sys/arch/arm/allwinner/awin_reg.h:1.87 src/sys/arch/arm/allwinner/awin_reg.h:1.88 --- src/sys/arch/arm/allwinner/awin_reg.h:1.87 Tue Apr 12 10:54:29 2016 +++ src/sys/arch/arm/allwinner/awin_reg.h Mon Apr 25 20:15:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_reg.h,v 1.87 2016/04/12 10:54:29 bouyer Exp $ */ +/* $NetBSD: awin_reg.h,v 1.88 2016/04/25 20:15:46 bouyer Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -3030,4 +3030,44 @@ struct awin_a31_dma_desc { #define AWIN_A80_PIO_PN_PINS 2 +#define AWIN_LRADC_CTRL_REG 0x00 +#define AWIN_LRADC_CTRL_FIRSTCONV_MASK __BITS(31,24) +#define AWIN_LRADC_CTRL_FIRSTCONV_SHIFT 24 +#define AWIN_LRADC_CTRL_CHAN_MASK __BITS(23,22) +#define AWIN_LRADC_CTRL_CHAN_SHIFT 22 +#define AWIN_LRADC_CTRL_CONT_MASK __BITS(19,16) +#define AWIN_LRADC_CTRL_CONT_SHIFT 16 +#define AWIN_LRADC_CTRL_KMODE_MASK __BITS(13,12) +#define AWIN_LRADC_CTRL_KMODE_NORMAL (0 << 12) +#define AWIN_LRADC_CTRL_KMODE_SINGLE (1 << 12) +#define AWIN_LRADC_CTRL_KMODE_CONTINUE (2 << 12) +#define AWIN_LRADC_CTRL_LV_A_B_CNT_MASK __BITS(11,8) +#define AWIN_LRADC_CTRL_LV_A_B_CNT_SHIFT 8 +#define AWIN_LRADC_CTRL_HOLD_EN __BIT(6) +#define AWIN_LRADC_CTRL_LEVEL_B_MASK __BITS(5,4) +#define AWIN_LRADC_CTRL_LEVEL_B_3C (0 << 4) +#define AWIN_LRADC_CTRL_LEVEL_B_39 (1 << 4) +#define AWIN_LRADC_CTRL_LEVEL_B_36 (2 << 4) +#define AWIN_LRADC_CTRL_LEVEL_B_33 (3 << 4) +#define AWIN_LRADC_CTRL_RATE_MASK __BITS(3,2) +#define AWIN_LRADC_CTRL_RATE_250 (0 << 2) +#define AWIN_LRADC_CTRL_RATE_125 (1 << 2) +#define AWIN_LRADC_CTRL_RATE_62 (2 << 2) +#define AWIN_LRADC_CTRL_RATE_31 (3 << 2) +#define AWIN_LRADC_CTRL_EN __BIT(0) +#define AWIN_LRADC_INTC_REG 0x04 +#define AWIN_LRADC_INTS_REG 0x08 +#define AWIN_LRADC_INT_KEYUP1 __BIT(12) +#define AWIN_LRADC_INT_ALREADYHOLD1 __BIT(11) +#define AWIN_LRADC_INT_HOLD1 __BIT(10) +#define AWIN_LRADC_INT_KEY1 __BIT(9) +#define AWIN_LRADC_INT_DATA1 __BIT(8) +#define AWIN_LRADC_INT_KEYUP0 __BIT(4) +#define AWIN_LRADC_INT_ALREADYHOLD0 __BIT(3) +#define AWIN_LRADC_INT_HOLD0 __BIT(2) +#define AWIN_LRADC_INT_KEY0 __BIT(1) +#define AWIN_LRADC_INT_DATA0 __BIT(0) +#define AWIN_LRADC_DATA0_REG 0x0c +#define AWIN_LRADC_DATA1_REG 0x10 + #endif /* _ARM_ALLWINNER_AWIN_REG_H_ */ Index: src/sys/arch/arm/allwinner/files.awin diff -u src/sys/arch/arm/allwinner/files.awin:1.34 src/sys/arch/arm/allwinner/files.awin:1.35 --- src/sys/arch/arm/allwinner/files.awin:1.34 Sat Dec 26 16:56:41 2015 +++ src/sys/arch/arm/allwinner/files.awin Mon Apr 25 20:15:46 2016 @@ -1,4 +1,4 @@ -# $NetBSD: files.awin,v 1.34 2015/12/26 16:56:41 macallan Exp $ +# $NetBSD: files.awin,v 1.35 2016/04/25 20:15:46 bouyer Exp $ # # Configuration info for Allwinner ARM Peripherals # @@ -177,3 +177,8 @@ file arch/arm/allwinner/awin_fb.c awin_ device awinir: irbus attach awinir at awinio with awin_ir file arch/arm/allwinner/awin_ir.c awin_ir + +# A20 LRADC +device awinlradc +attach awinlradc at awinio with awin_lradc +file arch/arm/allwinner/awin_lradc.c awin_lradc Index: src/sys/arch/evbarm/awin/awin_machdep.c diff -u src/sys/arch/evbarm/awin/awin_machdep.c:1.47 src/sys/arch/evbarm/awin/awin_machdep.c:1.48 --- src/sys/arch/evbarm/awin/awin_machdep.c:1.47 Sun Nov 15 21:28:54 2015 +++ src/sys/arch/evbarm/awin/awin_machdep.c Mon Apr 25 20:15:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_machdep.c,v 1.47 2015/11/15 21:28:54 bouyer Exp $ */ +/* $NetBSD: awin_machdep.c,v 1.48 2016/04/25 20:15:46 bouyer Exp $ */ /* * Machine dependent functions for kernel setup for TI OSK5912 board. @@ -125,7 +125,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: awin_machdep.c,v 1.47 2015/11/15 21:28:54 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: awin_machdep.c,v 1.48 2016/04/25 20:15:46 bouyer Exp $"); #include "opt_machdep.h" #include "opt_ddb.h" @@ -264,6 +264,8 @@ static void awin_display_sysconfig(prop_ static void awin_hdmi_sysconfig(prop_dictionary_t); static void awin_tcon_sysconfig(device_t, prop_dictionary_t); static void awin_tcon_lcd_sysconfig(const char *, prop_dictionary_t); +static void awin_lradc_sysconfig(prop_dictionary_t); +static void awin_lradc_chan_sysconfig(int, prop_dictionary_t); #endif #if NCOM > 0 @@ -871,6 +873,11 @@ awin_device_register(device_t self, void awin_tcon_sysconfig(self, dict); } } + if (device_is_a(self, "awinlradc")) { + if (awin_sysconfig_p) { + awin_lradc_sysconfig(dict); + } + } #endif #if NAXP20X > 0 @@ -1195,4 +1202,54 @@ awin_tcon_lcd_sysconfig(const char *key, } } + +static void +awin_lradc_sysconfig(prop_dictionary_t dict) +{ + int chan; + int vref; + + switch(awin_sysconfig_get_int("lradc_para", "lradc_used")) { + case 0: + /* unused */ + return; + case 1: + /* used */ + break; + default: + /* error */ + return; + } + vref = awin_sysconfig_get_int("lradc_para", "lradc_vref"); + if (vref <= 0) + return; + prop_dictionary_set_int32(dict, "vref", vref); + for (chan = 0; chan < 2; chan++) + awin_lradc_chan_sysconfig(chan, dict); +} + +static void +awin_lradc_chan_sysconfig(int chan, prop_dictionary_t dict) +{ + int i; + char level_key[14]; + int level; + char name_key[13]; + const char *name; + + for (i = 0; i < 32; i++) { + snprintf(level_key, sizeof(level_key), "chan%d_level%d", + chan, i); + snprintf(name_key, sizeof(name_key), "chan%d_name%d", + chan, i); + level = awin_sysconfig_get_int("lradc_para", level_key); + if (level < 0) + break; + name = awin_sysconfig_get_string("lradc_para", name_key); + if (name == NULL) + break; + prop_dictionary_set_int32(dict, level_key, level); + prop_dictionary_set_cstring(dict, name_key, name); + } +} #endif Index: src/sys/arch/evbarm/conf/CUBIEBOARD diff -u src/sys/arch/evbarm/conf/CUBIEBOARD:1.45 src/sys/arch/evbarm/conf/CUBIEBOARD:1.46 --- src/sys/arch/evbarm/conf/CUBIEBOARD:1.45 Sat Dec 19 13:28:22 2015 +++ src/sys/arch/evbarm/conf/CUBIEBOARD Mon Apr 25 20:15:46 2016 @@ -1,5 +1,5 @@ # -# $NetBSD: CUBIEBOARD,v 1.45 2015/12/19 13:28:22 skrll Exp $ +# $NetBSD: CUBIEBOARD,v 1.46 2016/04/25 20:15:46 bouyer Exp $ # # CUBIEBOARD -- Allwinner A10/A20 Eval Board Kernel # @@ -121,6 +121,9 @@ awinwdt* at awinio? # RTC awinrtc* at awinio? +# Low res ADC +awinlradc* at awinio? + # onboard audio codec awinac0 at awinio0 audio0 at awinac0 Added files: Index: src/sys/arch/arm/allwinner/awin_lradc.c diff -u /dev/null src/sys/arch/arm/allwinner/awin_lradc.c:1.1 --- /dev/null Mon Apr 25 20:15:46 2016 +++ src/sys/arch/arm/allwinner/awin_lradc.c Mon Apr 25 20:15:46 2016 @@ -0,0 +1,346 @@ +/* $NetBSD: awin_lradc.c,v 1.1 2016/04/25 20:15:46 bouyer Exp $ */ + +/*- + * Copyright (c) 2016 Manuel Bouyer + * All rights reserved. + * + * 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 AUTHOR ``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 AUTHOR 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: awin_lradc.c,v 1.1 2016/04/25 20:15:46 bouyer Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/select.h> +#include <sys/mutex.h> +#include <sys/kmem.h> + +#include <dev/sysmon/sysmonvar.h> +#include <dev/sysmon/sysmon_taskq.h> + +#include <arm/allwinner/awin_reg.h> +#include <arm/allwinner/awin_var.h> + +struct awin_lradc_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + kmutex_t sc_lock; + void *sc_ih; + int sc_vref; + uint8_t sc_chans; + uint8_t sc_level[2][32]; + const char *sc_name[2][32]; + int sc_nlevels[2]; + int sc_lastlevel[2]; + struct sysmon_pswitch *sc_switches[2]; + uint32_t sc_ints; /* pending interrupts */ +}; + +#define ADC_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) +#define ADC_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) + +static int awin_lradc_match(device_t, cfdata_t, void *); +static void awin_lradc_attach(device_t, device_t, void *); +static int awin_lradc_intr(void *); +static void awin_lradc_get_levels(struct awin_lradc_softc *, + prop_dictionary_t, int); +static void awin_lradc_print_levels(struct awin_lradc_softc *, int); +static bool awin_lradc_register_switches(struct awin_lradc_softc *, int); + + +CFATTACH_DECL_NEW(awin_lradc, sizeof(struct awin_lradc_softc), + awin_lradc_match, awin_lradc_attach, NULL, NULL); + +static int +awin_lradc_match(device_t parent, cfdata_t cf, void *aux) +{ + struct awinio_attach_args * const aio = aux; + const struct awin_locators * const loc = &aio->aio_loc; + + if (strcmp(cf->cf_name, loc->loc_name)) + return 0; + + return 1; +} + +static void +awin_lradc_attach(device_t parent, device_t self, void *aux) +{ + struct awin_lradc_softc *sc = device_private(self); + struct awinio_attach_args * const aio = aux; + prop_dictionary_t dict = device_properties(self); + const struct awin_locators * const loc = &aio->aio_loc; + int i; + uint32_t vref; + uint32_t intc = 0; + + sc->sc_dev = self; + sc->sc_bst = aio->aio_core_bst; + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); + bus_space_subregion(sc->sc_bst, aio->aio_core_bsh, + loc->loc_offset, loc->loc_size, &sc->sc_bsh); + sc->sc_chans = -1; + aprint_naive("\n"); + aprint_normal(": LRADC, "); + if (!prop_dictionary_get_int32(dict, "vref", &vref)) { + aprint_normal("disabled (no vref)\n"); + return; + } + sc->sc_vref = vref; + for (i = 0; i < 2; i++) { + awin_lradc_get_levels(sc, dict, i); + } + switch (sc->sc_chans) { + case 0: + aprint_normal("channel 0 enabled\n"); + break; + case 1: + aprint_normal("channel 1 enabled\n"); + break; + case 2: + aprint_normal("channel 0 & 1 enabled\n"); + break; + default: + aprint_normal("no channel enabled\n"); + break; + } + + if (sc->sc_chans == 0 || sc->sc_chans == 2) { + awin_lradc_print_levels(sc, 0); + } + if (sc->sc_chans == 1 || sc->sc_chans == 2) { + awin_lradc_print_levels(sc, 1); + } + + sc->sc_ih = intr_establish(loc->loc_intr, IPL_VM, + IST_LEVEL | IST_MPSAFE, awin_lradc_intr, sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "couldn't establish interrupt %d\n", + loc->loc_intr); + return; + } + aprint_normal_dev(self, ": interrupting on irq %d\n", loc->loc_intr); + if (sc->sc_chans == 0 || sc->sc_chans == 2) { + if (!awin_lradc_register_switches(sc, 0)) { + aprint_error_dev(self, ": can't register switches\n"); + return; + } + } + if (sc->sc_chans == 1 || sc->sc_chans == 2) { + if (!awin_lradc_register_switches(sc, 1)) { + aprint_error_dev(self, ": can't register switches\n"); + return; + } + } + + /* + * init and enable LRADC + * 250Hz, wait 2 cycles (8ms) on key press and release + */ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_LRADC_CTRL_REG, + (2 << AWIN_LRADC_CTRL_FIRSTCONV_SHIFT) | + (1 << AWIN_LRADC_CTRL_LV_A_B_CNT_SHIFT) | + AWIN_LRADC_CTRL_HOLD_EN | + AWIN_LRADC_CTRL_RATE_250 | + (sc->sc_chans << AWIN_LRADC_CTRL_CHAN_SHIFT) | + AWIN_LRADC_CTRL_EN); + switch(sc->sc_chans) { + case 0: + intc = AWIN_LRADC_INT_KEY0 | AWIN_LRADC_INT_KEYUP0; + break; + case 1: + intc = AWIN_LRADC_INT_KEY1 | AWIN_LRADC_INT_KEYUP1; + break; + case 2: + intc = AWIN_LRADC_INT_KEY0 | AWIN_LRADC_INT_KEYUP0 | + AWIN_LRADC_INT_KEY1 | AWIN_LRADC_INT_KEYUP1; + break; + } + bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_LRADC_INTC_REG, intc); +} + +static void +awin_lradc_get_levels(struct awin_lradc_softc *sc, + prop_dictionary_t dict, int chan) +{ + int i; + char level_key[14]; + int32_t level; + char name_key[13]; + const char *name; + const int vref = sc->sc_vref * 2 / 3; + + for (i = 0; i < 32; i++) { + snprintf(level_key, sizeof(level_key), "chan%d_level%d", + chan, i); + snprintf(name_key, sizeof(name_key), "chan%d_name%d", + chan, i); + if (!prop_dictionary_get_int32(dict, level_key, &level)) + break; + if (level < 0) + break; + if (!prop_dictionary_get_cstring_nocopy(dict, name_key, &name)) + break; + + /* convert from millivolts to ADC value */ + sc->sc_level[chan][i] = level * 63 / vref; + sc->sc_name[chan][i] = name; + } + if (i > 0) { + switch(chan) { + case 0: + if (sc->sc_chans == 1) + sc->sc_chans = 2; + else + sc->sc_chans = 0; + break; + case 1: + if (sc->sc_chans == 0) + sc->sc_chans = 2; + else + sc->sc_chans = 1; + break; + default: + panic("lradc: chan %d", chan); + } + sc->sc_nlevels[chan] = i; + } +} + +static void +awin_lradc_print_levels(struct awin_lradc_softc *sc, int chan) +{ + int i; + + aprint_verbose_dev(sc->sc_dev, ": channel %d levels", chan); + for (i = 0; i < 32; i++) { + if (sc->sc_name[chan][i] == NULL) + break; + aprint_verbose(" %d(%s)", + sc->sc_level[chan][i], sc->sc_name[chan][i]); + } + aprint_verbose("\n"); +} + +static bool +awin_lradc_register_switches(struct awin_lradc_softc *sc, int chan) +{ + + KASSERT(sc->sc_nlevels[chan] > 0); + sc->sc_switches[chan] = kmem_zalloc( + sizeof(struct sysmon_pswitch) * sc->sc_nlevels[chan] , KM_SLEEP); + + if (sc->sc_switches[chan] == NULL) + return false; + + for (int i = 0; i < sc->sc_nlevels[chan]; i++) { + struct sysmon_pswitch *sw = &sc->sc_switches[chan][i]; + sw->smpsw_name = sc->sc_name[chan][i]; + sw->smpsw_type = PSWITCH_TYPE_HOTKEY; + sysmon_pswitch_register(sw); + } + return true; +} + +static void +awin_lradc_intr_ev(struct awin_lradc_softc *sc, int chan, int event) +{ + int32_t val; + int diff = 64; + + + if (event == PSWITCH_EVENT_RELEASED) { + sysmon_pswitch_event( + &sc->sc_switches[chan][sc->sc_lastlevel[chan]], event); + return; + } + + val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, + chan == 0 ? AWIN_LRADC_DATA0_REG : AWIN_LRADC_DATA1_REG); + + KASSERT(sc->sc_nlevels[chan] > 0); + for (int i = 0; i < sc->sc_nlevels[chan]; i++) { + int curdiff; + curdiff = val - sc->sc_level[chan][i]; + if (curdiff < 0) + curdiff = -curdiff; + if (diff > curdiff) { + diff = curdiff; + sc->sc_lastlevel[chan] = i; + } + } + sysmon_pswitch_event( + &sc->sc_switches[chan][sc->sc_lastlevel[chan]], event); +} + +static void +awin_lradc_intr_task(void *arg) +{ + struct awin_lradc_softc *sc = arg; + mutex_enter(&sc->sc_lock); + if (sc->sc_chans == 0 || sc->sc_chans == 2) { + if (sc->sc_ints & AWIN_LRADC_INT_KEY0) { + awin_lradc_intr_ev(sc, 0, PSWITCH_EVENT_PRESSED); + } + if (sc->sc_ints & AWIN_LRADC_INT_KEYUP0) { + awin_lradc_intr_ev(sc, 0, PSWITCH_EVENT_RELEASED); + } + } + if (sc->sc_chans == 1 || sc->sc_chans == 2) { + if (sc->sc_ints & AWIN_LRADC_INT_KEY1) { + awin_lradc_intr_ev(sc, 1, PSWITCH_EVENT_PRESSED); + } + if (sc->sc_ints & AWIN_LRADC_INT_KEYUP1) { + awin_lradc_intr_ev(sc, 1, PSWITCH_EVENT_RELEASED); + } + } + sc->sc_ints = 0; + mutex_exit(&sc->sc_lock); +} + +static int +awin_lradc_intr(void *arg) +{ + struct awin_lradc_softc *sc = arg; + int error; + + mutex_enter(&sc->sc_lock); + sc->sc_ints = bus_space_read_4(sc->sc_bst, sc->sc_bsh, + AWIN_LRADC_INTS_REG); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_LRADC_INTS_REG, + sc->sc_ints); + mutex_exit(&sc->sc_lock); + error = sysmon_task_queue_sched(0, awin_lradc_intr_task, sc); + if (error != 0) { + printf("%s: sysmon_task_queue_sched failed (%d)\n", + device_xname(sc->sc_dev), error); + } + return 1; +}