boards: add the Adafruit Trinket M0.

The Trinket M0 is a tiny SAMD21 based board with USB, UART, SPI, and
an on-board RGB LED.

Signed-off-by: Michael Hope <mlhx@google.com>
diff --git a/boards/arm/adafruit_trinket_m0/CMakeLists.txt b/boards/arm/adafruit_trinket_m0/CMakeLists.txt
new file mode 100644
index 0000000..96ab6ca
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/CMakeLists.txt
@@ -0,0 +1,4 @@
+if(CONFIG_PINMUX_SAM0)
+  zephyr_library()
+  zephyr_library_sources(pinmux.c)
+endif()
diff --git a/boards/arm/adafruit_trinket_m0/Kconfig.board b/boards/arm/adafruit_trinket_m0/Kconfig.board
new file mode 100644
index 0000000..8369b64
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/Kconfig.board
@@ -0,0 +1,8 @@
+# Kconfig - Adafruit Trinket M0 board configuration
+#
+# Copyright (c) 2018 Google LLC.
+# SPDX-License-Identifier: Apache-2.0
+
+config BOARD_ADAFRUIT_TRINKET_M0
+	bool "Adafruit Trinket M0"
+	depends on SOC_PART_NUMBER_SAMD21E18A
diff --git a/boards/arm/adafruit_trinket_m0/Kconfig.defconfig b/boards/arm/adafruit_trinket_m0/Kconfig.defconfig
new file mode 100644
index 0000000..3d909fb
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/Kconfig.defconfig
@@ -0,0 +1,11 @@
+# Kconfig - Adafruit Trinket M0 board configuration
+#
+# Copyright (c) 2018 Google LLC.
+# SPDX-License-Identifier: Apache-2.0
+
+if BOARD_ADAFRUIT_TRINKET_M0
+
+config BOARD
+	default adafruit_trinket_m0
+
+endif
diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts
new file mode 100644
index 0000000..787ecd8
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 Google LLC.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/dts-v1/;
+#include <atmel/samd21.dtsi>
+
+/ {
+	model = "Adafruit Trinket M0";
+	compatible = "adafruit,trinket-m0", "atmel,samd21e18a", "atmel,samd21";
+
+	chosen {
+		zephyr,console = &sercom0;
+		zephyr,sram = &sram0;
+		zephyr,flash = &flash0;
+		zephyr,code-partition = &code_partition;
+	};
+};
+
+&sercom0 {
+	status = "ok";
+	current-speed = <115200>;
+};
+
+&sercom2 {
+	status = "ok";
+	current-speed = <115200>;
+};
+
+/* Drives the on-board DotStar LED */
+&spi1 {
+	status = "ok";
+};
+
+&flash0 {
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		boot_partition: partition@0 {
+			label = "uf2";
+			reg = <0x00000000 0x2000>;
+			read-only;
+		};
+
+		code_partition: partition@2000 {
+			label = "code";
+			reg = <0x2000 0x3A000>;
+			read-only;
+		};
+
+		/*
+		 * The final 16 KiB is reserved for the application
+		 * and is used by NFFS if enabled.
+		 */
+
+#if defined(CONFIG_FILE_SYSTEM_NFFS)
+		nffs_partition: partition@3c000 {
+			label = "nffs";
+			reg = <0x0003c000 0x00004000>;
+		};
+#endif
+	};
+};
diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml
new file mode 100644
index 0000000..23a3ada
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml
@@ -0,0 +1,9 @@
+identifier: adafruit_trinket_m0
+name: Adafruit Trinket M0
+type: mcu
+arch: arm
+ram: 32
+flash: 256
+toolchain:
+  - zephyr
+  - gccarmemb
diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig
new file mode 100644
index 0000000..b24a20e
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig
@@ -0,0 +1,23 @@
+CONFIG_ARM=y
+CONFIG_SOC_FAMILY_SAM0=y
+CONFIG_SOC_SERIES_SAMD21=y
+CONFIG_SOC_PART_NUMBER_SAMD21E18A=y
+CONFIG_BOARD_ADAFRUIT_TRINKET_M0=y
+CONFIG_SOC_ATMEL_SAMD_OSC8M_AS_MAIN=y
+CONFIG_CORTEX_M_SYSTICK=y
+CONFIG_CONSOLE=y
+CONFIG_UART_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_UART_SAM0=y
+CONFIG_UART_INTERRUPT_DRIVEN=y
+CONFIG_GPIO=y
+CONFIG_GPIO_SAM0=y
+CONFIG_WATCHDOG=y
+CONFIG_WDT_SAM0=y
+CONFIG_SPI=y
+CONFIG_SPI_SAM0=y
+CONFIG_SPI_1=y
+CONFIG_SPI_1_IRQ_PRI=0
+CONFIG_SPI_LEGACY_API=n
+CONFIG_PINMUX=y
+CONFIG_PINMUX_SAM0=y
diff --git a/boards/arm/adafruit_trinket_m0/board.cmake b/boards/arm/adafruit_trinket_m0/board.cmake
new file mode 100644
index 0000000..9525725
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/board.cmake
@@ -0,0 +1,4 @@
+# Copyright (c) 2018 Google LLC.
+# SPDX-License-Identifier: Apache-2.0
+
+include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake)
diff --git a/boards/arm/adafruit_trinket_m0/board.h b/boards/arm/adafruit_trinket_m0/board.h
new file mode 100644
index 0000000..391aa68
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/board.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Google LLC.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __INC_BOARD_H
+#define __INC_BOARD_H
+
+#include <soc.h>
+
+/* LED on PA10 */
+#define LED0_GPIO_PORT	CONFIG_GPIO_SAM0_PORTA_LABEL
+#define LED0_GPIO_PIN	10
+
+#define CONFIG_UART_SAM0_SERCOM0_PADS \
+	(SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1))
+#define CONFIG_UART_SAM0_SERCOM2_PADS \
+	(SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(0))
+
+#define CONFIG_SPI_SAM0_SERCOM0_PADS \
+	(SERCOM_SPI_CTRLA_DIPO(0) | SERCOM_SPI_CTRLA_DOPO(1))
+
+#define CONFIG_SPI_SAM0_SERCOM1_PADS \
+	(SERCOM_SPI_CTRLA_DIPO(2) | SERCOM_SPI_CTRLA_DOPO(0))
+
+#endif /* __INC_BOARD_H */
diff --git a/boards/arm/adafruit_trinket_m0/doc/adafruit_trinket_m0.rst b/boards/arm/adafruit_trinket_m0/doc/adafruit_trinket_m0.rst
new file mode 100644
index 0000000..c2dcc21
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/doc/adafruit_trinket_m0.rst
@@ -0,0 +1,149 @@
+.. _adafruit_trinket_m0:
+
+Adafruit Trinket M0
+###################
+
+Overview
+********
+
+The Adafruit Trinket M0 is a tiny (27 mm x 15 mm) ARM development
+board with an onboard RGB LED, USB port, and range of I/O broken out
+onto 5 pins.
+
+.. image:: img/adafruit_trinket_m0.png
+     :width: 500px
+     :align: center
+     :alt: Adafruit Trinket M0
+
+Hardware
+********
+
+- ATSAMD21E18A ARM Cortex-M0+ processor at 48 MHz
+- 256 KiB flash memory and 32 KiB of RAM
+- Internal trimmed 8 MHz oscillator
+- A user LED
+- An RGB DotStar LED
+- Native USB port
+- One reset button
+
+Supported Features
+==================
+
+The adafruit_trinket_m0 board configuration supports the following hardware
+features:
+
++-----------+------------+--------------------------------------+
+| Interface | Controller | Driver/Component                     |
++===========+============+======================================+
+| NVIC      | on-chip    | nested vector interrupt controller   |
++-----------+------------+--------------------------------------+
+| Flash     | on-chip    | Can be used with NFFS to store files |
++-----------+------------+--------------------------------------+
+| SYSTICK   | on-chip    | systick                              |
++-----------+------------+--------------------------------------+
+| WDT       | on-chip    | Watchdog                             |
++-----------+------------+--------------------------------------+
+| GPIO      | on-chip    | I/O ports                            |
++-----------+------------+--------------------------------------+
+| USART     | on-chip    | Serial ports                         |
++-----------+------------+--------------------------------------+
+| SPI       | on-chip    | Serial Peripheral Interface ports    |
++-----------+------------+--------------------------------------+
+
+Other hardware features are not currently supported by Zephyr.
+
+The default configuration can be found in the Kconfig file
+:file:`boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig`.
+
+Connections and IOs
+===================
+
+The `Adafruit Trinket M0 Learn site`_ has detailed information about
+the board including `pinouts`_ and the `schematic`_.
+
+System Clock
+============
+
+The SAMD21 MCU is configured to use the 8 MHz internal oscillator
+with the on-chip PLL generating the 48 MHz system clock.  The internal
+APB and GCLK unit are set up in the same way as the upstream Arduino
+libraries.
+
+Serial Port
+===========
+
+The SAMD21 MCU has 6 SERCOM based USARTs.  On the Trinket, SERCOM0 is
+the Zephyr console and is available on pins 3 (RX) and 4 (TX).
+SERCOM2 is available on pins 2 (RX) and 0 (TX).
+
+SPI Port
+========
+
+The SAMD21 MCU has 6 SERCOM based SPIs.  On the Trinket, SPI1 is used
+to drive the DotStar RGB LED.  SERCOM0 can be put into SPI mode and
+used to connect to devices over pin 2 (MISO), pin 4 (MOSI), and pin 3
+(SCK).
+
+Programming and Debugging
+*************************
+
+The Trinket M0 ships the BOSSA compatible UF2 bootloader.  The
+bootloader can be entered by quickly tapping the reset button twice.
+
+Flashing
+========
+
+#. Build the Zephyr kernel and the :ref:`hello_world` sample application:
+
+   .. zephyr-app-commands::
+      :zephyr-app: samples/hello_world
+      :board: adafruit_trinket_m0
+      :goals: build
+      :compact:
+
+#. Connect the Trinket M0 to your host computer using USB
+
+#. Connect a 3.3 V USB to serial adapter to the board and to the
+   host.  See the `Serial Port`_ section above for the board's pin
+   connections.
+
+#. Run your favorite terminal program to listen for output. Under Linux the
+   terminal should be :code:`/dev/ttyACM0`. For example:
+
+   .. code-block:: console
+
+      $ minicom -D /dev/ttyACM0 -o
+
+   The -o option tells minicom not to send the modem initialization
+   string. Connection should be configured as follows:
+
+   - Speed: 115200
+   - Data: 8 bits
+   - Parity: None
+   - Stop bits: 1
+
+#. Tap the reset button twice quickly to enter bootloader mode
+
+#. Flash the image:
+
+   .. zephyr-app-commands::
+      :zephyr-app: samples/hello_world
+      :board: adafruit_trinket_m0
+      :goals: flash
+      :compact:
+
+   You should see "Hello World! arm" in your terminal.
+
+References
+**********
+
+.. target-notes::
+
+.. _Adafruit Trinket M0 Learn site:
+    https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino
+
+.. _pinouts:
+    https://learn.adafruit.com/assets/49778
+
+.. _schematic:
+    https://learn.adafruit.com/assets/45723
diff --git a/boards/arm/adafruit_trinket_m0/doc/img/adafruit_trinket_m0.png b/boards/arm/adafruit_trinket_m0/doc/img/adafruit_trinket_m0.png
new file mode 100644
index 0000000..f4e3037
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/doc/img/adafruit_trinket_m0.png
Binary files differ
diff --git a/boards/arm/adafruit_trinket_m0/pinmux.c b/boards/arm/adafruit_trinket_m0/pinmux.c
new file mode 100644
index 0000000..d4f9fe1
--- /dev/null
+++ b/boards/arm/adafruit_trinket_m0/pinmux.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018 Google LLC.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <init.h>
+#include <pinmux.h>
+
+static int board_pinmux_init(struct device *dev)
+{
+	struct device *muxa = device_get_binding(CONFIG_PINMUX_SAM0_A_LABEL);
+
+	ARG_UNUSED(dev);
+
+#if CONFIG_UART_SAM0_SERCOM0_BASE_ADDRESS
+	/* SERCOM0 on RX=PA7/pad 3, TX=PA6/pad 2 */
+	pinmux_pin_set(muxa, 7, PINMUX_FUNC_D);
+	pinmux_pin_set(muxa, 6, PINMUX_FUNC_D);
+#endif
+
+#if CONFIG_UART_SAM0_SERCOM2_BASE_ADDRESS
+	/* SERCOM2 on RX=PA9/pad 1, TX=PA8/pad 0 */
+	pinmux_pin_set(muxa, 9, PINMUX_FUNC_D);
+	pinmux_pin_set(muxa, 8, PINMUX_FUNC_D);
+#endif
+
+#if CONFIG_UART_SAM0_SERCOM1_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+#if CONFIG_UART_SAM0_SERCOM3_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+#if CONFIG_UART_SAM0_SERCOM4_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+#if CONFIG_UART_SAM0_SERCOM5_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+
+#if CONFIG_SPI_SAM0_SERCOM0_BASE_ADDRESS
+	/* SPI SERCOM0 on MISO=PA9/pad 1, MOSI=PA6/pad 2, SCK=PA7/pad 3 */
+	pinmux_pin_set(muxa, 9, PINMUX_FUNC_D);
+	pinmux_pin_set(muxa, 6, PINMUX_FUNC_D);
+	pinmux_pin_set(muxa, 7, PINMUX_FUNC_D);
+#endif
+
+#if CONFIG_SPI_SAM0_SERCOM1_BASE_ADDRESS
+	/* SPI SERCOM1 on MOSI=PA0/pad 0, SCK=PA1/pad 1 */
+	pinmux_pin_set(muxa, 0, PINMUX_FUNC_D);
+	pinmux_pin_set(muxa, 1, PINMUX_FUNC_D);
+#endif
+
+#if CONFIG_SPI_SAM0_SERCOM2_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+#if CONFIG_SPI_SAM0_SERCOM3_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+#if CONFIG_SPI_SAM0_SERCOM4_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+#if CONFIG_SPI_SAM0_SERCOM5_BASE_ADDRESS
+#error Pin mapping is not configured
+#endif
+
+	return 0;
+}
+
+SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY);