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).diff -r1.44 -r1.45 src/sys/arch/arm/allwinner/awin_io.c
(bouyer)
--- src/sys/arch/arm/allwinner/Attic/awin_io.c 2015/12/26 16:56:41 1.44
+++ src/sys/arch/arm/allwinner/Attic/awin_io.c 2016/04/25 20:15:46 1.45
@@ -21,27 +21,27 @@ | @@ -21,27 +21,27 @@ | |||
21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 | * POSSIBILITY OF SUCH DAMAGE. | 27 | * POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include "locators.h" | 30 | #include "locators.h" | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | 33 | |||
34 | __KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.44 2015/12/26 16:56:41 macallan Exp $"); | 34 | __KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.45 2016/04/25 20:15:46 bouyer Exp $"); | |
35 | 35 | |||
36 | #include <sys/param.h> | 36 | #include <sys/param.h> | |
37 | #include <sys/bus.h> | 37 | #include <sys/bus.h> | |
38 | #include <sys/cpu.h> | 38 | #include <sys/cpu.h> | |
39 | #include <sys/device.h> | 39 | #include <sys/device.h> | |
40 | #include <sys/intr.h> | 40 | #include <sys/intr.h> | |
41 | #include <sys/systm.h> | 41 | #include <sys/systm.h> | |
42 | 42 | |||
43 | #include <arm/locore.h> | 43 | #include <arm/locore.h> | |
44 | #include <arm/mainbus/mainbus.h> | 44 | #include <arm/mainbus/mainbus.h> | |
45 | 45 | |||
46 | #include <arm/allwinner/awin_reg.h> | 46 | #include <arm/allwinner/awin_reg.h> | |
47 | #include <arm/allwinner/awin_var.h> | 47 | #include <arm/allwinner/awin_var.h> | |
@@ -180,26 +180,27 @@ static const struct awin_locators awin_l | @@ -180,26 +180,27 @@ static const struct awin_locators awin_l | |||
180 | { "awge", OFFANDSIZE(A31_GMAC), NOPORT, AWIN_A31_IRQ_GMAC, A31 }, | 180 | { "awge", OFFANDSIZE(A31_GMAC), NOPORT, AWIN_A31_IRQ_GMAC, A31 }, | |
181 | { "awge", OFFANDSIZE(A80_GMAC), NOPORT, AWIN_A80_IRQ_EMAC, A80 }, | 181 | { "awge", OFFANDSIZE(A80_GMAC), NOPORT, AWIN_A80_IRQ_EMAC, A80 }, | |
182 | { "awincrypto", OFFANDSIZE(SS), NOPORT, AWIN_IRQ_SS, AANY }, | 182 | { "awincrypto", OFFANDSIZE(SS), NOPORT, AWIN_IRQ_SS, AANY }, | |
183 | { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_IRQ_AC, A10|A20 }, | 183 | { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_IRQ_AC, A10|A20 }, | |
184 | { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_A31_IRQ_AC, A31 }, | 184 | { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_A31_IRQ_AC, A31 }, | |
185 | { "awindaudio", OFFANDSIZE(A80_DAUDIO1), 1, AWIN_A80_IRQ_R_DAUDIO, A80 }, | 185 | { "awindaudio", OFFANDSIZE(A80_DAUDIO1), 1, AWIN_A80_IRQ_R_DAUDIO, A80 }, | |
186 | { "awinhdmiaudio", OFFANDSIZE(HDMI), NOPORT, NOINTR, A20 }, | 186 | { "awinhdmiaudio", OFFANDSIZE(HDMI), NOPORT, NOINTR, A20 }, | |
187 | { "awinhdmiaudio", OFFANDSIZE(HDMI), NOPORT, NOINTR, A31 }, | 187 | { "awinhdmiaudio", OFFANDSIZE(HDMI), NOPORT, NOINTR, A31 }, | |
188 | { "awinnand", OFFANDSIZE(NFC), NOPORT, AWIN_IRQ_NAND, A10|A20 }, | 188 | { "awinnand", OFFANDSIZE(NFC), NOPORT, AWIN_IRQ_NAND, A10|A20 }, | |
189 | { "awinir", OFFANDSIZE(IR0), 0, AWIN_IRQ_IR0, A10|A20 }, | 189 | { "awinir", OFFANDSIZE(IR0), 0, AWIN_IRQ_IR0, A10|A20 }, | |
190 | { "awinir", OFFANDSIZE(IR1), 1, AWIN_IRQ_IR1, A10|A20 }, | 190 | { "awinir", OFFANDSIZE(IR1), 1, AWIN_IRQ_IR1, A10|A20 }, | |
191 | { "awinir", OFFANDSIZE(A31_CIR), NOPORT, AWIN_A31_IRQ_CIR, A31 }, | 191 | { "awinir", OFFANDSIZE(A31_CIR), NOPORT, AWIN_A31_IRQ_CIR, A31 }, | |
192 | { "awinir", OFFANDSIZE(A80_CIR), NOPORT, AWIN_A80_IRQ_R_CIR, A80 }, | 192 | { "awinir", OFFANDSIZE(A80_CIR), NOPORT, AWIN_A80_IRQ_R_CIR, A80 }, | |
193 | { "awinlradc", OFFANDSIZE(LRADC), NOPORT, AWIN_IRQ_LRADC, A20 }, | |||
193 | }; | 194 | }; | |
194 | 195 | |||
195 | static int | 196 | static int | |
196 | awinio_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux) | 197 | awinio_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux) | |
197 | { | 198 | { | |
198 | const struct awinio_attach_args * const aio = aux; | 199 | const struct awinio_attach_args * const aio = aux; | |
199 | const struct awin_locators * const loc = &aio->aio_loc; | 200 | const struct awin_locators * const loc = &aio->aio_loc; | |
200 | const int port = cf->cf_loc[AWINIOCF_PORT]; | 201 | const int port = cf->cf_loc[AWINIOCF_PORT]; | |
201 | 202 | |||
202 | if (strcmp(cf->cf_name, loc->loc_name) | 203 | if (strcmp(cf->cf_name, loc->loc_name) | |
203 | || (port != AWINIOCF_PORT_DEFAULT && port != loc->loc_port)) | 204 | || (port != AWINIOCF_PORT_DEFAULT && port != loc->loc_port)) | |
204 | return 0; | 205 | return 0; | |
205 | 206 |
/* $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;
}
--- src/sys/arch/arm/allwinner/Attic/awin_reg.h 2016/04/12 10:54:29 1.87
+++ src/sys/arch/arm/allwinner/Attic/awin_reg.h 2016/04/25 20:15:46 1.88
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: awin_reg.h,v 1.87 2016/04/12 10:54:29 bouyer Exp $ */ | 1 | /* $NetBSD: awin_reg.h,v 1.88 2016/04/25 20:15:46 bouyer Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Matt Thomas of 3am Software Foundry. | 8 | * by Matt Thomas of 3am Software Foundry. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -3020,14 +3020,54 @@ struct awin_a31_dma_desc { | @@ -3020,14 +3020,54 @@ struct awin_a31_dma_desc { | |||
3020 | #define AWIN_A80_PIO_PH_UART0_FUNC 2 | 3020 | #define AWIN_A80_PIO_PH_UART0_FUNC 2 | |
3021 | #define AWIN_A80_PIO_PH_UART0_PINS 0x00003000 /* PH pins 13-12 */ | 3021 | #define AWIN_A80_PIO_PH_UART0_PINS 0x00003000 /* PH pins 13-12 */ | |
3022 | 3022 | |||
3023 | #define AWIN_A80_PIO_PL_PINS 14 | 3023 | #define AWIN_A80_PIO_PL_PINS 14 | |
3024 | #define AWIN_A80_PIO_PL_CIR_FUNC 3 | 3024 | #define AWIN_A80_PIO_PL_CIR_FUNC 3 | |
3025 | #define AWIN_A80_PIO_PL_CIR_PINS 0x00000040 /* PL pin 6 */ | 3025 | #define AWIN_A80_PIO_PL_CIR_PINS 0x00000040 /* PL pin 6 */ | |
3026 | 3026 | |||
3027 | #define AWIN_A80_PIO_PM_PINS 16 | 3027 | #define AWIN_A80_PIO_PM_PINS 16 | |
3028 | #define AWIN_A80_PIO_PM_DAUDIO1_FUNC 3 | 3028 | #define AWIN_A80_PIO_PM_DAUDIO1_FUNC 3 | |
3029 | #define AWIN_A80_PIO_PM_DAUDIO1_PINS 0x00007cf0 /* PM pins 14-10,7-4 */ | 3029 | #define AWIN_A80_PIO_PM_DAUDIO1_PINS 0x00007cf0 /* PM pins 14-10,7-4 */ | |
3030 | 3030 | |||
3031 | #define AWIN_A80_PIO_PN_PINS 2 | 3031 | #define AWIN_A80_PIO_PN_PINS 2 | |
3032 | 3032 | |||
3033 | #define AWIN_LRADC_CTRL_REG 0x00 | |||
3034 | #define AWIN_LRADC_CTRL_FIRSTCONV_MASK __BITS(31,24) | |||
3035 | #define AWIN_LRADC_CTRL_FIRSTCONV_SHIFT 24 | |||
3036 | #define AWIN_LRADC_CTRL_CHAN_MASK __BITS(23,22) | |||
3037 | #define AWIN_LRADC_CTRL_CHAN_SHIFT 22 | |||
3038 | #define AWIN_LRADC_CTRL_CONT_MASK __BITS(19,16) | |||
3039 | #define AWIN_LRADC_CTRL_CONT_SHIFT 16 | |||
3040 | #define AWIN_LRADC_CTRL_KMODE_MASK __BITS(13,12) | |||
3041 | #define AWIN_LRADC_CTRL_KMODE_NORMAL (0 << 12) | |||
3042 | #define AWIN_LRADC_CTRL_KMODE_SINGLE (1 << 12) | |||
3043 | #define AWIN_LRADC_CTRL_KMODE_CONTINUE (2 << 12) | |||
3044 | #define AWIN_LRADC_CTRL_LV_A_B_CNT_MASK __BITS(11,8) | |||
3045 | #define AWIN_LRADC_CTRL_LV_A_B_CNT_SHIFT 8 | |||
3046 | #define AWIN_LRADC_CTRL_HOLD_EN __BIT(6) | |||
3047 | #define AWIN_LRADC_CTRL_LEVEL_B_MASK __BITS(5,4) | |||
3048 | #define AWIN_LRADC_CTRL_LEVEL_B_3C (0 << 4) | |||
3049 | #define AWIN_LRADC_CTRL_LEVEL_B_39 (1 << 4) | |||
3050 | #define AWIN_LRADC_CTRL_LEVEL_B_36 (2 << 4) | |||
3051 | #define AWIN_LRADC_CTRL_LEVEL_B_33 (3 << 4) | |||
3052 | #define AWIN_LRADC_CTRL_RATE_MASK __BITS(3,2) | |||
3053 | #define AWIN_LRADC_CTRL_RATE_250 (0 << 2) | |||
3054 | #define AWIN_LRADC_CTRL_RATE_125 (1 << 2) | |||
3055 | #define AWIN_LRADC_CTRL_RATE_62 (2 << 2) | |||
3056 | #define AWIN_LRADC_CTRL_RATE_31 (3 << 2) | |||
3057 | #define AWIN_LRADC_CTRL_EN __BIT(0) | |||
3058 | #define AWIN_LRADC_INTC_REG 0x04 | |||
3059 | #define AWIN_LRADC_INTS_REG 0x08 | |||
3060 | #define AWIN_LRADC_INT_KEYUP1 __BIT(12) | |||
3061 | #define AWIN_LRADC_INT_ALREADYHOLD1 __BIT(11) | |||
3062 | #define AWIN_LRADC_INT_HOLD1 __BIT(10) | |||
3063 | #define AWIN_LRADC_INT_KEY1 __BIT(9) | |||
3064 | #define AWIN_LRADC_INT_DATA1 __BIT(8) | |||
3065 | #define AWIN_LRADC_INT_KEYUP0 __BIT(4) | |||
3066 | #define AWIN_LRADC_INT_ALREADYHOLD0 __BIT(3) | |||
3067 | #define AWIN_LRADC_INT_HOLD0 __BIT(2) | |||
3068 | #define AWIN_LRADC_INT_KEY0 __BIT(1) | |||
3069 | #define AWIN_LRADC_INT_DATA0 __BIT(0) | |||
3070 | #define AWIN_LRADC_DATA0_REG 0x0c | |||
3071 | #define AWIN_LRADC_DATA1_REG 0x10 | |||
3072 | ||||
3033 | #endif /* _ARM_ALLWINNER_AWIN_REG_H_ */ | 3073 | #endif /* _ARM_ALLWINNER_AWIN_REG_H_ */ |
--- src/sys/arch/arm/allwinner/Attic/files.awin 2015/12/26 16:56:41 1.34
+++ src/sys/arch/arm/allwinner/Attic/files.awin 2016/04/25 20:15:46 1.35
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | # $NetBSD: files.awin,v 1.34 2015/12/26 16:56:41 macallan Exp $ | 1 | # $NetBSD: files.awin,v 1.35 2016/04/25 20:15:46 bouyer Exp $ | |
2 | # | 2 | # | |
3 | # Configuration info for Allwinner ARM Peripherals | 3 | # Configuration info for Allwinner ARM Peripherals | |
4 | # | 4 | # | |
5 | 5 | |||
6 | include "arch/arm/pic/files.pic" | 6 | include "arch/arm/pic/files.pic" | |
7 | include "arch/arm/cortex/files.cortex" | 7 | include "arch/arm/cortex/files.cortex" | |
8 | 8 | |||
9 | file arch/arm/arm32/arm32_boot.c | 9 | file arch/arm/arm32/arm32_boot.c | |
10 | file arch/arm/arm32/arm32_kvminit.c | 10 | file arch/arm/arm32/arm32_kvminit.c | |
11 | file arch/arm/arm32/arm32_reboot.c | 11 | file arch/arm/arm32/arm32_reboot.c | |
12 | file arch/arm/arm32/irq_dispatch.S | 12 | file arch/arm/arm32/irq_dispatch.S | |
13 | 13 | |||
14 | file arch/arm/allwinner/awin_board.c | 14 | file arch/arm/allwinner/awin_board.c | |
@@ -167,13 +167,18 @@ file arch/arm/allwinner/awin_debe.c awi | @@ -167,13 +167,18 @@ file arch/arm/allwinner/awin_debe.c awi | |||
167 | # A10/A20/A31 Mixer processor (MP) | 167 | # A10/A20/A31 Mixer processor (MP) | |
168 | device awinmp | 168 | device awinmp | |
169 | attach awinmp at awinio with awin_mp | 169 | attach awinmp at awinio with awin_mp | |
170 | file arch/arm/allwinner/awin_mp.c awin_mp needs-flag | 170 | file arch/arm/allwinner/awin_mp.c awin_mp needs-flag | |
171 | 171 | |||
172 | # Framebuffer | 172 | # Framebuffer | |
173 | attach genfb at awindebe with awin_fb: edid | 173 | attach genfb at awindebe with awin_fb: edid | |
174 | file arch/arm/allwinner/awin_fb.c awin_fb needs-flag | 174 | file arch/arm/allwinner/awin_fb.c awin_fb needs-flag | |
175 | 175 | |||
176 | # A10/A20/A31 Consumer IR (CIR) | 176 | # A10/A20/A31 Consumer IR (CIR) | |
177 | device awinir: irbus | 177 | device awinir: irbus | |
178 | attach awinir at awinio with awin_ir | 178 | attach awinir at awinio with awin_ir | |
179 | file arch/arm/allwinner/awin_ir.c awin_ir | 179 | file arch/arm/allwinner/awin_ir.c awin_ir | |
180 | ||||
181 | # A20 LRADC | |||
182 | device awinlradc | |||
183 | attach awinlradc at awinio with awin_lradc | |||
184 | file arch/arm/allwinner/awin_lradc.c awin_lradc |
--- src/sys/arch/evbarm/awin/Attic/awin_machdep.c 2015/11/15 21:28:54 1.47
+++ src/sys/arch/evbarm/awin/Attic/awin_machdep.c 2016/04/25 20:15:46 1.48
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: awin_machdep.c,v 1.47 2015/11/15 21:28:54 bouyer Exp $ */ | 1 | /* $NetBSD: awin_machdep.c,v 1.48 2016/04/25 20:15:46 bouyer Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Machine dependent functions for kernel setup for TI OSK5912 board. | 4 | * Machine dependent functions for kernel setup for TI OSK5912 board. | |
5 | * Based on lubbock_machdep.c which in turn was based on iq80310_machhdep.c | 5 | * Based on lubbock_machdep.c which in turn was based on iq80310_machhdep.c | |
6 | * | 6 | * | |
7 | * Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved. | 7 | * Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved. | |
8 | * Written by Hiroyuki Bessho for Genetec Corporation. | 8 | * Written by Hiroyuki Bessho for Genetec Corporation. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -115,27 +115,27 @@ | @@ -115,27 +115,27 @@ | |||
115 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 115 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
116 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 116 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
117 | * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, | 117 | * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, | |
118 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 118 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
119 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 119 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
120 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 120 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
121 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 121 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
122 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 122 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
123 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 123 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
124 | * SUCH DAMAGE. | 124 | * SUCH DAMAGE. | |
125 | */ | 125 | */ | |
126 | 126 | |||
127 | #include <sys/cdefs.h> | 127 | #include <sys/cdefs.h> | |
128 | __KERNEL_RCSID(0, "$NetBSD: awin_machdep.c,v 1.47 2015/11/15 21:28:54 bouyer Exp $"); | 128 | __KERNEL_RCSID(0, "$NetBSD: awin_machdep.c,v 1.48 2016/04/25 20:15:46 bouyer Exp $"); | |
129 | 129 | |||
130 | #include "opt_machdep.h" | 130 | #include "opt_machdep.h" | |
131 | #include "opt_ddb.h" | 131 | #include "opt_ddb.h" | |
132 | #include "opt_kgdb.h" | 132 | #include "opt_kgdb.h" | |
133 | #include "opt_ipkdb.h" | 133 | #include "opt_ipkdb.h" | |
134 | #include "opt_md.h" | 134 | #include "opt_md.h" | |
135 | #include "opt_com.h" | 135 | #include "opt_com.h" | |
136 | #include "opt_allwinner.h" | 136 | #include "opt_allwinner.h" | |
137 | #include "opt_arm_debug.h" | 137 | #include "opt_arm_debug.h" | |
138 | 138 | |||
139 | #include "com.h" | 139 | #include "com.h" | |
140 | #include "ukbd.h" | 140 | #include "ukbd.h" | |
141 | #include "genfb.h" | 141 | #include "genfb.h" | |
@@ -254,26 +254,28 @@ int use_fb_console = true; | @@ -254,26 +254,28 @@ int use_fb_console = true; | |||
254 | void consinit(void); | 254 | void consinit(void); | |
255 | #ifdef KGDB | 255 | #ifdef KGDB | |
256 | static void kgdb_port_init(void); | 256 | static void kgdb_port_init(void); | |
257 | #endif | 257 | #endif | |
258 | 258 | |||
259 | static void awin_device_register(device_t, void *); | 259 | static void awin_device_register(device_t, void *); | |
260 | 260 | |||
261 | #ifdef AWIN_SYSCONFIG | 261 | #ifdef AWIN_SYSCONFIG | |
262 | static void awin_gpio_sysconfig(prop_dictionary_t); | 262 | static void awin_gpio_sysconfig(prop_dictionary_t); | |
263 | static void awin_display_sysconfig(prop_dictionary_t); | 263 | static void awin_display_sysconfig(prop_dictionary_t); | |
264 | static void awin_hdmi_sysconfig(prop_dictionary_t); | 264 | static void awin_hdmi_sysconfig(prop_dictionary_t); | |
265 | static void awin_tcon_sysconfig(device_t, prop_dictionary_t); | 265 | static void awin_tcon_sysconfig(device_t, prop_dictionary_t); | |
266 | static void awin_tcon_lcd_sysconfig(const char *, prop_dictionary_t); | 266 | static void awin_tcon_lcd_sysconfig(const char *, prop_dictionary_t); | |
267 | static void awin_lradc_sysconfig(prop_dictionary_t); | |||
268 | static void awin_lradc_chan_sysconfig(int, prop_dictionary_t); | |||
267 | #endif | 269 | #endif | |
268 | 270 | |||
269 | #if NCOM > 0 | 271 | #if NCOM > 0 | |
270 | #include <dev/ic/comreg.h> | 272 | #include <dev/ic/comreg.h> | |
271 | #include <dev/ic/comvar.h> | 273 | #include <dev/ic/comvar.h> | |
272 | #endif | 274 | #endif | |
273 | 275 | |||
274 | /* | 276 | /* | |
275 | * Static device mappings. These peripheral registers are mapped at | 277 | * Static device mappings. These peripheral registers are mapped at | |
276 | * fixed virtual addresses very early in initarm() so that we can use | 278 | * fixed virtual addresses very early in initarm() so that we can use | |
277 | * them while booting the kernel, and stay at the same address | 279 | * them while booting the kernel, and stay at the same address | |
278 | * throughout whole kernel's life time. | 280 | * throughout whole kernel's life time. | |
279 | * | 281 | * | |
@@ -861,26 +863,31 @@ awin_device_register(device_t self, void | @@ -861,26 +863,31 @@ awin_device_register(device_t self, void | |||
861 | } | 863 | } | |
862 | #ifdef AWIN_SYSCONFIG | 864 | #ifdef AWIN_SYSCONFIG | |
863 | if (awin_sysconfig_p) { | 865 | if (awin_sysconfig_p) { | |
864 | awin_hdmi_sysconfig(dict); | 866 | awin_hdmi_sysconfig(dict); | |
865 | } | 867 | } | |
866 | #endif | 868 | #endif | |
867 | } | 869 | } | |
868 | #ifdef AWIN_SYSCONFIG | 870 | #ifdef AWIN_SYSCONFIG | |
869 | if (device_is_a(self, "awintcon")) { | 871 | if (device_is_a(self, "awintcon")) { | |
870 | if (awin_sysconfig_p) { | 872 | if (awin_sysconfig_p) { | |
871 | awin_tcon_sysconfig(self, dict); | 873 | awin_tcon_sysconfig(self, dict); | |
872 | } | 874 | } | |
873 | } | 875 | } | |
876 | if (device_is_a(self, "awinlradc")) { | |||
877 | if (awin_sysconfig_p) { | |||
878 | awin_lradc_sysconfig(dict); | |||
879 | } | |||
880 | } | |||
874 | #endif | 881 | #endif | |
875 | 882 | |||
876 | #if NAXP20X > 0 | 883 | #if NAXP20X > 0 | |
877 | if (device_is_a(self, "axp20x")) { | 884 | if (device_is_a(self, "axp20x")) { | |
878 | pmic_dev = self; | 885 | pmic_dev = self; | |
879 | #if AWIN_board == AWIN_cubieboard || AWIN_board == AWIN_cubietruck || AWIN_board == AWIN_bpi || AWIN_board == AWIN_olimexlime2 | 886 | #if AWIN_board == AWIN_cubieboard || AWIN_board == AWIN_cubietruck || AWIN_board == AWIN_bpi || AWIN_board == AWIN_olimexlime2 | |
880 | pmic_cpu_dcdc = AXP20X_DCDC2; | 887 | pmic_cpu_dcdc = AXP20X_DCDC2; | |
881 | #endif | 888 | #endif | |
882 | } | 889 | } | |
883 | #endif | 890 | #endif | |
884 | 891 | |||
885 | #if NGENFB > 0 | 892 | #if NGENFB > 0 | |
886 | if (device_is_a(self, "genfb")) { | 893 | if (device_is_a(self, "genfb")) { | |
@@ -1185,14 +1192,64 @@ awin_tcon_lcd_sysconfig(const char *key, | @@ -1185,14 +1192,64 @@ awin_tcon_lcd_sysconfig(const char *key, | |||
1185 | int value = awin_sysconfig_get_int( key, lcdtimings[n]); | 1192 | int value = awin_sysconfig_get_int( key, lcdtimings[n]); | |
1186 | if (value >= 0) { | 1193 | if (value >= 0) { | |
1187 | prop_dictionary_set_int32(dict, lcdtimings[n], value); | 1194 | prop_dictionary_set_int32(dict, lcdtimings[n], value); | |
1188 | } | 1195 | } | |
1189 | } | 1196 | } | |
1190 | for (n = 0; n < __arraycount(lcdgpio); n++) { | 1197 | for (n = 0; n < __arraycount(lcdgpio); n++) { | |
1191 | cfg = awin_sysconfig_get_string(key, lcdgpio[n]); | 1198 | cfg = awin_sysconfig_get_string(key, lcdgpio[n]); | |
1192 | if (cfg != NULL) { | 1199 | if (cfg != NULL) { | |
1193 | prop_dictionary_set_cstring(dict, lcdgpio[n], cfg); | 1200 | prop_dictionary_set_cstring(dict, lcdgpio[n], cfg); | |
1194 | } | 1201 | } | |
1195 | } | 1202 | } | |
1196 | 1203 | |||
1197 | } | 1204 | } | |
1205 | ||||
1206 | static void | |||
1207 | awin_lradc_sysconfig(prop_dictionary_t dict) | |||
1208 | { | |||
1209 | int chan; | |||
1210 | int vref; | |||
1211 | ||||
1212 | switch(awin_sysconfig_get_int("lradc_para", "lradc_used")) { | |||
1213 | case 0: | |||
1214 | /* unused */ | |||
1215 | return; | |||
1216 | case 1: | |||
1217 | /* used */ | |||
1218 | break; | |||
1219 | default: | |||
1220 | /* error */ | |||
1221 | return; | |||
1222 | } | |||
1223 | vref = awin_sysconfig_get_int("lradc_para", "lradc_vref"); | |||
1224 | if (vref <= 0) | |||
1225 | return; | |||
1226 | prop_dictionary_set_int32(dict, "vref", vref); | |||
1227 | for (chan = 0; chan < 2; chan++) | |||
1228 | awin_lradc_chan_sysconfig(chan, dict); | |||
1229 | } | |||
1230 | ||||
1231 | static void | |||
1232 | awin_lradc_chan_sysconfig(int chan, prop_dictionary_t dict) | |||
1233 | { | |||
1234 | int i; | |||
1235 | char level_key[14]; | |||
1236 | int level; | |||
1237 | char name_key[13]; | |||
1238 | const char *name; | |||
1239 | ||||
1240 | for (i = 0; i < 32; i++) { | |||
1241 | snprintf(level_key, sizeof(level_key), "chan%d_level%d", | |||
1242 | chan, i); | |||
1243 | snprintf(name_key, sizeof(name_key), "chan%d_name%d", | |||
1244 | chan, i); | |||
1245 | level = awin_sysconfig_get_int("lradc_para", level_key); | |||
1246 | if (level < 0) | |||
1247 | break; | |||
1248 | name = awin_sysconfig_get_string("lradc_para", name_key); | |||
1249 | if (name == NULL) | |||
1250 | break; | |||
1251 | prop_dictionary_set_int32(dict, level_key, level); | |||
1252 | prop_dictionary_set_cstring(dict, name_key, name); | |||
1253 | } | |||
1254 | } | |||
1198 | #endif | 1255 | #endif |
--- src/sys/arch/evbarm/conf/Attic/CUBIEBOARD 2015/12/19 13:28:22 1.45
+++ src/sys/arch/evbarm/conf/Attic/CUBIEBOARD 2016/04/25 20:15:46 1.46
@@ -1,15 +1,15 @@ | @@ -1,15 +1,15 @@ | |||
1 | # | 1 | # | |
2 | # $NetBSD: CUBIEBOARD,v 1.45 2015/12/19 13:28:22 skrll Exp $ | 2 | # $NetBSD: CUBIEBOARD,v 1.46 2016/04/25 20:15:46 bouyer Exp $ | |
3 | # | 3 | # | |
4 | # CUBIEBOARD -- Allwinner A10/A20 Eval Board Kernel | 4 | # CUBIEBOARD -- Allwinner A10/A20 Eval Board Kernel | |
5 | # | 5 | # | |
6 | 6 | |||
7 | include "arch/evbarm/conf/std.awin" | 7 | include "arch/evbarm/conf/std.awin" | |
8 | 8 | |||
9 | # CPU options | 9 | # CPU options | |
10 | 10 | |||
11 | no makeoptions BOARDTYPE | 11 | no makeoptions BOARDTYPE | |
12 | makeoptions BOARDTYPE="cubieboard" | 12 | makeoptions BOARDTYPE="cubieboard" | |
13 | no makeoptions CPUFLAGS | 13 | no makeoptions CPUFLAGS | |
14 | makeoptions CPUFLAGS="-mcpu=cortex-a7 -mfpu=neon" | 14 | makeoptions CPUFLAGS="-mcpu=cortex-a7 -mfpu=neon" | |
15 | #options UVMHIST,UVMHIST_PRINT | 15 | #options UVMHIST,UVMHIST_PRINT | |
@@ -111,26 +111,29 @@ options CONADDR=0x01c28000, CONSPEED=11 | @@ -111,26 +111,29 @@ options CONADDR=0x01c28000, CONSPEED=11 | |||
111 | # Consumer IR | 111 | # Consumer IR | |
112 | awinir0 at awinio? | 112 | awinir0 at awinio? | |
113 | cir0 at awinir0 | 113 | cir0 at awinir0 | |
114 | 114 | |||
115 | # Operating System Timer (A10) | 115 | # Operating System Timer (A10) | |
116 | awintmr0 at awinio? | 116 | awintmr0 at awinio? | |
117 | 117 | |||
118 | # Watchdog timers | 118 | # Watchdog timers | |
119 | awinwdt* at awinio? | 119 | awinwdt* at awinio? | |
120 | 120 | |||
121 | # RTC | 121 | # RTC | |
122 | awinrtc* at awinio? | 122 | awinrtc* at awinio? | |
123 | 123 | |||
124 | # Low res ADC | |||
125 | awinlradc* at awinio? | |||
126 | ||||
124 | # onboard audio codec | 127 | # onboard audio codec | |
125 | awinac0 at awinio0 | 128 | awinac0 at awinio0 | |
126 | audio0 at awinac0 | 129 | audio0 at awinac0 | |
127 | 130 | |||
128 | # HDMI | 131 | # HDMI | |
129 | awinhdmi0 at awinio0 | 132 | awinhdmi0 at awinio0 | |
130 | awinhdmiaudio0 at awinio0 | 133 | awinhdmiaudio0 at awinio0 | |
131 | audio1 at awinhdmiaudio0 | 134 | audio1 at awinhdmiaudio0 | |
132 | 135 | |||
133 | # TCON | 136 | # TCON | |
134 | awintcon0 at awinio0 port 0 | 137 | awintcon0 at awinio0 port 0 | |
135 | awintcon1 at awinio0 port 1 | 138 | awintcon1 at awinio0 port 1 | |
136 | 139 |