Index: head/sys/arm/allwinner/aw_cir.c =================================================================== --- head/sys/arm/allwinner/aw_cir.c (nonexistent) +++ head/sys/arm/allwinner/aw_cir.c (revision 307984) @@ -0,0 +1,535 @@ +/*- + * Copyright (c) 2016 Ganbold Tsagaankhuu + * 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 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 AUTHOR 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. + */ + +/* + * Allwinner Consumer IR controller + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define READ(_sc, _r) bus_read_4((_sc)->res[0], (_r)) +#define WRITE(_sc, _r, _v) bus_write_4((_sc)->res[0], (_r), (_v)) + +/* IR Control */ +#define AW_IR_CTL 0x00 +/* Global Enable */ +#define AW_IR_CTL_GEN (1 << 0) +/* RX enable */ +#define AW_IR_CTL_RXEN (1 << 1) +/* CIR mode enable */ +#define AW_IR_CTL_MD (1 << 4) | (1 << 5) + +/* RX Config Reg */ +#define AW_IR_RXCTL 0x10 +/* Pulse Polarity Invert flag */ +#define AW_IR_RXCTL_RPPI (1 << 2) + +/* RX Data */ +#define AW_IR_RXFIFO 0x20 + +/* RX Interrupt Control */ +#define AW_IR_RXINT 0x2C +/* RX FIFO Overflow */ +#define AW_IR_RXINT_ROI_EN (1 << 0) +/* RX Packet End */ +#define AW_IR_RXINT_RPEI_EN (1 << 1) +/* RX FIFO Data Available */ +#define AW_IR_RXINT_RAI_EN (1 << 4) +/* RX FIFO available byte level */ +#define AW_IR_RXINT_RAL(val) ((val) << 8) + +/* RX Interrupt Status Reg */ +#define AW_IR_RXSTA 0x30 +/* RX FIFO Get Available Counter */ +#define AW_IR_RXSTA_COUNTER(val) (((val) >> 8) & (sc->fifo_size * 2 - 1)) +/* Clear all interrupt status */ +#define AW_IR_RXSTA_CLEARALL 0xff + +/* IR Sample Configure Reg */ +#define AW_IR_CIR 0x34 +/* Filter Threshold = 8 * 21.3 = ~128us < 200us */ +#define AW_IR_RXFILT_VAL (((8) & 0x3f) << 2) +/* Idle Threshold = (2 + 1) * 128 * 42.7 = ~16.4ms > 9ms */ +#define AW_IR_RXIDLE_VAL (((2) & 0xff) << 8) + +/* Bit 15 - value (pulse/space) */ +#define VAL_MASK 0x80 +/* Bits 0:14 - sample duration */ +#define PERIOD_MASK 0x7f + +/* Clock rate for IR0 or IR1 clock in CIR mode */ +#define AW_IR_BASE_CLK 3000000 +/* Frequency sample 3MHz/64 = 46875Hz (21.3us) */ +#define AW_IR_SAMPLE_64 (0 << 0) +/* Frequency sample 3MHz/128 = 23437.5Hz (42.7us) */ +#define AW_IR_SAMPLE_128 (1 << 0) + +#define AW_IR_ERROR_CODE 0xffffffff +#define AW_IR_REPEAT_CODE 0x0 + +/* 80 * 42.7 = ~3.4ms, Lead1(4.5ms) > AW_IR_L1_MIN */ +#define AW_IR_L1_MIN 80 +/* 40 * 42.7 = ~1.7ms, Lead0(4.5ms) Lead0R(2.25ms) > AW_IR_L0_MIN */ +#define AW_IR_L0_MIN 40 +/* 26 * 42.7 = ~1109us ~= 561 * 2, Pulse < AW_IR_PMAX */ +#define AW_IR_PMAX 26 +/* 26 * 42.7 = ~1109us ~= 561 * 2, D1 > AW_IR_DMID, D0 <= AW_IR_DMID */ +#define AW_IR_DMID 26 +/* 53 * 42.7 = ~2263us ~= 561 * 4, D < AW_IR_DMAX */ +#define AW_IR_DMAX 53 + +/* Active Thresholds */ +#define AW_IR_ACTIVE_T ((0 & 0xff) << 16) +#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23) + +/* Code masks */ +#define CODE_MASK 0x00ff00ff +#define INV_CODE_MASK 0xff00ff00 +#define VALID_CODE_MASK 0x00ff0000 + +#define A10_IR 1 +#define A13_IR 2 + +#define AW_IR_RAW_BUF_SIZE 128 + +struct aw_ir_softc { + device_t dev; + struct resource *res[2]; + void * intrhand; + int fifo_size; + int dcnt; /* Packet Count */ + unsigned char buf[AW_IR_RAW_BUF_SIZE]; + struct evdev_dev *sc_evdev; +}; + +static struct resource_spec aw_ir_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, + { -1, 0 } +}; + +static struct ofw_compat_data compat_data[] = { + { "allwinner,sun4i-a10-ir", A10_IR }, + { "allwinner,sun5i-a13-ir", A13_IR }, + { NULL, 0 } +}; + +static void +aw_ir_buf_reset(struct aw_ir_softc *sc) +{ + + sc->dcnt = 0; +} + +static void +aw_ir_buf_write(struct aw_ir_softc *sc, unsigned char data) +{ + + if (sc->dcnt < AW_IR_RAW_BUF_SIZE) + sc->buf[sc->dcnt++] = data; + else + if (bootverbose) + device_printf(sc->dev, "IR RX Buffer Full!\n"); +} + +static int +aw_ir_buf_full(struct aw_ir_softc *sc) +{ + + return (sc->dcnt >= AW_IR_RAW_BUF_SIZE); +} + +static unsigned char +aw_ir_read_data(struct aw_ir_softc *sc) +{ + + return (unsigned char)(READ(sc, AW_IR_RXFIFO) & 0xff); +} + +static unsigned long +aw_ir_decode_packets(struct aw_ir_softc *sc) +{ + unsigned long len, code; + unsigned char val, last; + unsigned int active_delay; + int i, bitcount; + + if (bootverbose) + device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt); + + /* Find Lead 1 (bit separator) */ + active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C ? 128 : 1); + len = 0; + len += (active_delay >> 1); + if (bootverbose) + device_printf(sc->dev, "Initial len: %ld\n", len); + for (i = 0; i < sc->dcnt; i++) { + val = sc->buf[i]; + if (val & VAL_MASK) + len += val & PERIOD_MASK; + else { + if (len > AW_IR_L1_MIN) + break; + len = 0; + } + } + if (bootverbose) + device_printf(sc->dev, "len = %ld\n", len); + if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) { + if (bootverbose) + device_printf(sc->dev, "Bit separator error\n"); + goto error_code; + } + + /* Find Lead 0 (bit length) */ + len = 0; + for (; i < sc->dcnt; i++) { + val = sc->buf[i]; + if (val & VAL_MASK) { + if(len > AW_IR_L0_MIN) + break; + len = 0; + } else + len += val & PERIOD_MASK; + } + if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) { + if (bootverbose) + device_printf(sc->dev, "Bit length error\n"); + goto error_code; + } + + /* Start decoding */ + code = 0; + bitcount = 0; + last = 1; + len = 0; + for (; i < sc->dcnt; i++) { + val = sc->buf[i]; + if (last) { + if (val & VAL_MASK) + len += val & PERIOD_MASK; + else { + if (len > AW_IR_PMAX) { + if (bootverbose) + device_printf(sc->dev, + "Pulse error\n"); + goto error_code; + } + last = 0; + len = val & PERIOD_MASK; + } + } else { + if (val & VAL_MASK) { + if (len > AW_IR_DMAX) { + if (bootverbose) + device_printf(sc->dev, + "Distant error\n"); + goto error_code; + } else { + if (len > AW_IR_DMID) { + /* Decode */ + code |= 1 << bitcount; + } + bitcount++; + if (bitcount == 32) + break; /* Finish decoding */ + } + last = 1; + len = val & PERIOD_MASK; + } else + len += val & PERIOD_MASK; + } + } + return (code); + +error_code: + + return (AW_IR_ERROR_CODE); +} + +static int +aw_ir_validate_code(unsigned long code) +{ + unsigned long v1, v2; + + /* Don't check address */ + v1 = code & CODE_MASK; + v2 = (code & INV_CODE_MASK) >> 8; + + if (((v1 ^ v2) & VALID_CODE_MASK) == VALID_CODE_MASK) + return (0); /* valid */ + else + return (1); /* invalid */ +} + +static void +aw_ir_intr(void *arg) +{ + struct aw_ir_softc *sc; + uint32_t val; + int i, dcnt; + unsigned long ir_code; + int stat; + + sc = (struct aw_ir_softc *)arg; + + /* Read RX interrupt status */ + val = READ(sc, AW_IR_RXSTA); + + /* Clean all pending interrupt statuses */ + WRITE(sc, AW_IR_RXSTA, val | AW_IR_RXSTA_CLEARALL); + + /* When Rx FIFO Data available or Packet end */ + if (val & (AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RPEI_EN)) { + /* Get available message count in RX FIFO */ + dcnt = AW_IR_RXSTA_COUNTER(val); + /* Read FIFO */ + for (i = 0; i < dcnt; i++) { + if (aw_ir_buf_full(sc)) { + if (bootverbose) + device_printf(sc->dev, + "raw buffer full\n"); + break; + } else + aw_ir_buf_write(sc, aw_ir_read_data(sc)); + } + } + + if (val & AW_IR_RXINT_RPEI_EN) { + /* RX Packet end */ + if (bootverbose) + device_printf(sc->dev, "RX Packet end\n"); + ir_code = aw_ir_decode_packets(sc); + stat = aw_ir_validate_code(ir_code); + if (stat == 0) { + evdev_push_event(sc->sc_evdev, + EV_MSC, MSC_SCAN, ir_code); + evdev_sync(sc->sc_evdev); + } + if (bootverbose) { + device_printf(sc->dev, "Final IR code: %lx\n", + ir_code); + device_printf(sc->dev, "IR code status: %d\n", + stat); + } + sc->dcnt = 0; + } + if (val & AW_IR_RXINT_ROI_EN) { + /* RX FIFO overflow */ + if (bootverbose) + device_printf(sc->dev, "RX FIFO overflow\n"); + /* Flush raw buffer */ + aw_ir_buf_reset(sc); + } +} + +static int +aw_ir_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "Allwinner CIR controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +aw_ir_attach(device_t dev) +{ + struct aw_ir_softc *sc; + hwreset_t rst_apb; + clk_t clk_ir, clk_gate; + int err; + uint32_t val = 0; + + clk_ir = clk_gate = NULL; + + sc = device_get_softc(dev); + sc->dev = dev; + + if (bus_alloc_resources(dev, aw_ir_spec, sc->res) != 0) { + device_printf(dev, "could not allocate memory resource\n"); + return (ENXIO); + } + + switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { + case A10_IR: + sc->fifo_size = 16; + break; + case A13_IR: + sc->fifo_size = 64; + break; + } + + /* De-assert reset */ + if (hwreset_get_by_ofw_name(dev, 0, "apb", &rst_apb) == 0) { + err = hwreset_deassert(rst_apb); + if (err != 0) { + device_printf(dev, "cannot de-assert reset\n"); + goto error; + } + } + + /* Reset buffer */ + aw_ir_buf_reset(sc); + + /* Get clocks and enable them */ + err = clk_get_by_ofw_name(dev, 0, "apb", &clk_gate); + if (err != 0) { + device_printf(dev, "Cannot get gate clock\n"); + goto error; + } + err = clk_get_by_ofw_name(dev, 0, "ir", &clk_ir); + if (err != 0) { + device_printf(dev, "Cannot get IR clock\n"); + goto error; + } + /* Set clock rate */ + err = clk_set_freq(clk_ir, AW_IR_BASE_CLK, 0); + if (err != 0) { + device_printf(dev, "cannot set IR clock rate\n"); + goto error; + } + /* Enable clocks */ + err = clk_enable(clk_gate); + if (err != 0) { + device_printf(dev, "Cannot enable clk gate\n"); + goto error; + } + err = clk_enable(clk_ir); + if (err != 0) { + device_printf(dev, "Cannot enable IR clock\n"); + goto error; + } + + if (bus_setup_intr(dev, sc->res[1], + INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_ir_intr, sc, + &sc->intrhand)) { + bus_release_resources(dev, aw_ir_spec, sc->res); + device_printf(dev, "cannot setup interrupt handler\n"); + return (ENXIO); + } + + /* Enable CIR Mode */ + WRITE(sc, AW_IR_CTL, AW_IR_CTL_MD); + + /* + * Set clock sample, filter, idle thresholds. + * Frequency sample = 3MHz/128 = 23437.5Hz (42.7us) + */ + val = AW_IR_SAMPLE_128; + val |= (AW_IR_RXFILT_VAL | AW_IR_RXIDLE_VAL); + val |= (AW_IR_ACTIVE_T | AW_IR_ACTIVE_T_C); + WRITE(sc, AW_IR_CIR, val); + + /* Invert Input Signal */ + WRITE(sc, AW_IR_RXCTL, AW_IR_RXCTL_RPPI); + + /* Clear All RX Interrupt Status */ + WRITE(sc, AW_IR_RXSTA, AW_IR_RXSTA_CLEARALL); + + /* + * Enable RX interrupt in case of overflow, packet end + * and FIFO available. + * RX FIFO Threshold = FIFO size / 2 + */ + WRITE(sc, AW_IR_RXINT, AW_IR_RXINT_ROI_EN | AW_IR_RXINT_RPEI_EN | + AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RAL((sc->fifo_size >> 1) - 1)); + + /* Enable IR Module */ + val = READ(sc, AW_IR_CTL); + WRITE(sc, AW_IR_CTL, val | AW_IR_CTL_GEN | AW_IR_CTL_RXEN); + + sc->sc_evdev = evdev_alloc(); + evdev_set_name(sc->sc_evdev, device_get_desc(sc->dev)); + evdev_set_phys(sc->sc_evdev, device_get_nameunit(sc->dev)); + evdev_set_id(sc->sc_evdev, BUS_HOST, 0, 0, 0); + evdev_support_event(sc->sc_evdev, EV_SYN); + evdev_support_event(sc->sc_evdev, EV_MSC); + evdev_support_msc(sc->sc_evdev, MSC_SCAN); + + err = evdev_register(sc->sc_evdev); + if (err) { + device_printf(dev, + "failed to register evdev: error=%d\n", err); + goto error; + } + + return (0); +error: + if (clk_gate != NULL) + clk_release(clk_gate); + if (clk_ir != NULL) + clk_release(clk_ir); + if (rst_apb != NULL) + hwreset_release(rst_apb); + evdev_free(sc->sc_evdev); + sc->sc_evdev = NULL; /* Avoid double free */ + + bus_release_resources(dev, aw_ir_spec, sc->res); + return (ENXIO); +} + +static device_method_t aw_ir_methods[] = { + DEVMETHOD(device_probe, aw_ir_probe), + DEVMETHOD(device_attach, aw_ir_attach), + + DEVMETHOD_END +}; + +static driver_t aw_ir_driver = { + "aw_ir", + aw_ir_methods, + sizeof(struct aw_ir_softc), +}; +static devclass_t aw_ir_devclass; + +DRIVER_MODULE(aw_ir, simplebus, aw_ir_driver, aw_ir_devclass, 0, 0); +MODULE_DEPEND(aw_ir, evdev, 1, 1, 1); Property changes on: head/sys/arm/allwinner/aw_cir.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/arm/allwinner/files.allwinner =================================================================== --- head/sys/arm/allwinner/files.allwinner (revision 307983) +++ head/sys/arm/allwinner/files.allwinner (revision 307984) @@ -1,57 +1,58 @@ # $FreeBSD$ kern/kern_clocksource.c standard arm/allwinner/a10_ahci.c optional ahci arm/allwinner/a10_codec.c optional sound arm/allwinner/a10_common.c standard arm/allwinner/a10_dmac.c standard arm/allwinner/a10_ehci.c optional ehci arm/allwinner/aw_usbphy.c optional ehci arm/allwinner/a10_gpio.c optional gpio arm/allwinner/a10_mmc.c optional mmc arm/allwinner/a10_sramc.c standard arm/allwinner/aw_nmi.c optional intrng arm/allwinner/aw_if_dwc.c optional dwc arm/allwinner/aw_rsb.c optional rsb | p2wi arm/allwinner/aw_rtc.c standard arm/allwinner/aw_ts.c standard arm/allwinner/aw_wdog.c standard arm/allwinner/aw_machdep.c standard arm/allwinner/aw_mp.c optional smp arm/allwinner/axp209.c optional axp209 arm/allwinner/axp81x.c optional axp81x arm/allwinner/if_awg.c optional awg arm/allwinner/if_emac.c optional emac arm/allwinner/sunxi_dma_if.m standard dev/iicbus/twsi/a10_twsi.c optional twsi dev/usb/controller/generic_ohci.c optional ohci dev/usb/controller/generic_usb_if.m optional ohci arm/allwinner/aw_sid.c standard arm/allwinner/aw_thermal.c standard dev/iicbus/sy8106a.c optional sy8106a +arm/allwinner/aw_cir.c optional aw_cir evdev #arm/allwinner/console.c standard arm/allwinner/a10_fb.c optional vt arm/allwinner/a10_hdmi.c optional hdmi arm/allwinner/a10_hdmiaudio.c optional hdmi sound arm/arm/hdmi_if.m optional hdmi arm/allwinner/aw_reset.c standard arm/allwinner/aw_ccu.c standard arm/allwinner/clk/aw_ahbclk.c standard arm/allwinner/clk/aw_apbclk.c standard arm/allwinner/clk/aw_axiclk.c standard arm/allwinner/clk/aw_codecclk.c standard arm/allwinner/clk/aw_cpuclk.c standard arm/allwinner/clk/aw_cpusclk.c standard arm/allwinner/clk/aw_debeclk.c standard arm/allwinner/clk/aw_gate.c standard arm/allwinner/clk/aw_gmacclk.c standard arm/allwinner/clk/aw_hdmiclk.c standard arm/allwinner/clk/aw_lcdclk.c standard arm/allwinner/clk/aw_modclk.c standard arm/allwinner/clk/aw_mmcclk.c standard arm/allwinner/clk/aw_oscclk.c standard arm/allwinner/clk/aw_pll.c standard arm/allwinner/clk/aw_thsclk.c standard arm/allwinner/clk/aw_usbclk.c standard Index: head/sys/arm/conf/GENERIC =================================================================== --- head/sys/arm/conf/GENERIC (revision 307983) +++ head/sys/arm/conf/GENERIC (revision 307984) @@ -1,178 +1,184 @@ # # GENERICV6 -- Generic(ish) kernel config. # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. # If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ ident GENERIC cpu CPU_CORTEXA_MP machine arm armv6 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0000000 options KERNVIRTADDR=0xc0000000 include "std.armv6" files "../allwinner/files.allwinner" files "../allwinner/a20/files.a20" files "../allwinner/a31/files.a31" files "../allwinner/a83t/files.a83t" files "../allwinner/h3/files.h3" files "../broadcom/bcm2835/files.bcm2836" files "../broadcom/bcm2835/files.bcm283x" files "../nvidia/tegra124/files.tegra124" files "../qemu/files.qemu" options SOC_ALLWINNER_A20 options SOC_ALLWINNER_A31 options SOC_ALLWINNER_A31S options SOC_ALLWINNER_A83T options SOC_ALLWINNER_H3 options SOC_BCM2836 options SCHED_ULE # ULE scheduler options SMP # Enable multiple cores options PLATFORM options PLATFORM_SMP options MULTIDELAY options LINUX_BOOT_ABI # EXT_RESOURCES pseudo devices options EXT_RESOURCES device clk device phy device hwreset device regulator # CPU frequency control device cpufreq # Interrupt controller options INTRNG device gic # ARM Generic Timer device generic_timer # MMC/SD/SDIO Card slot support device sdhci # SD controller device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards # ATA controllers device ahci # AHCI-compatible SATA controllers #device ata # Legacy ATA/SATA controllers # PCI options NEW_PCIB device pci # PCI NICs device re # RealTek 8139C+/8169/8169S/8110S # VirtIO device virtio device virtio_mmio device virtio_blk device vtnet # Console and misc device uart device uart_ns8250 device uart_snps device pl011 device pty device snp device md # Memory "disks" device random # Entropy device device psci # I2C support device iicbus device iic device twsi device rsb # Allwinner Reduced Serial Bus device p2wi # Allwinner Push-Pull Two Wire device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc device icee device sy8106a # SY8106A Buck Regulator # GPIO device gpio device gpioled device gpioregulator +# EVDEV support +device evdev # input event device support +options EVDEV_SUPPORT # evdev support in legacy drivers +device uinput # install /dev/uinput cdev +device aw_cir + # SPI device spibus device bcm2835_spi device scbus # SCSI bus (required for ATA/SCSI) device da # Direct Access (disks) device cd # CD device pass # Passthrough device (direct ATA/SCSI access) # USB support options USB_HOST_ALIGN=64 # Align usb buffers to cache line size. device usb #device uhci device ohci device ehci device dwcotg # DWC OTG controller device umass # Disks/Mass storage - Requires scbus and da device uhid # "Human Interface Devices" device ukbd # Allow keyboard like HIDs to control console # Ethernet device loop device ether device vlan # 802.1Q VLAN support device mii device bpf #device emac # 10/100 integrated EMAC controller device dwc # 10/100/1000 integrated GMAC controller device awg # 10/100/1000 integrated EMAC controller # USB ethernet support, requires miibus device smcphy device smsc device miibus # Sound support device sound # Framebuffer support device vt device kbdmux device ums device videomode device hdmi device vchiq # Pinmux device fdt_pinctrl # Extensible Firmware Interface options EFI # Flattened Device Tree options FDT # Configure using FDT/DTB data makeoptions MODULES_EXTRA="dtb/allwinner dtb/nvidia dtb/rpi"