summaryrefslogtreecommitdiff
path: root/docs/zephyr
diff options
context:
space:
mode:
Diffstat (limited to 'docs/zephyr')
-rw-r--r--docs/zephyr/project_config.md174
-rw-r--r--docs/zephyr/zephyr_build.md172
-rw-r--r--docs/zephyr/zephyr_i2c.md370
-rw-r--r--docs/zephyr/zephyr_init.md53
-rw-r--r--docs/zephyr/zephyr_new_board_checklist.md65
-rw-r--r--docs/zephyr/zephyr_poc_device_bringup.md52
-rw-r--r--docs/zephyr/zephyr_shim.md381
-rw-r--r--docs/zephyr/zephyr_template.md56
-rw-r--r--docs/zephyr/ztest.md200
9 files changed, 1523 insertions, 0 deletions
diff --git a/docs/zephyr/project_config.md b/docs/zephyr/project_config.md
new file mode 100644
index 0000000000..285e90dbdd
--- /dev/null
+++ b/docs/zephyr/project_config.md
@@ -0,0 +1,174 @@
+Project Configuration
+=====================
+
+[TOC]
+
+## Setting up a new program ("reference board" or "baseboard")
+
+Unlike the legacy EC codebase, Zephyr projects all live together in
+one big happy directory. The intent of this design is to encourage
+code-sharing between projects, and reduce the amount of copy/paste
+that is required to bring up a new project. This directory can, but
+does not have to, correlate to the unified build Chrome OS board,
+however firmware authors can always choose a different structure if it
+makes sense for the specific scenario. As a hypothetical example,
+similar Chromeboxes and Chromebooks may wish to share the Zephyr EC
+project directory instead of use separate directories, even if they
+are using a different unified build board.
+
+To set up a new EC program, create a new directory under
+[`zephyr/projects`](../../zephyr/projects) with the following files:
+
+- `BUILD.py` - specifies which builds can be made from this directory,
+ and what the device-tree overlays and Kconfig files are for each
+ build.
+- `CMakeLists.txt` - Baseboard-specific C files can be listed here.
+- `prj.conf` (optional) - Default Kconfig settings for all projects.
+- `Kconfig` (optional) - Set options for your reference design here,
+ which variants can use to install optional C sources.
+
+An in-depth example of each file is given below:
+
+### BUILD.py
+
+`BUILD.py` is a Python-based config file for setting up your reference
+board and the associated variants. The name `BUILD.py` is important
+and case-sensitive: `zmake` searches for files by this
+name.
+
+When `BUILD.py` is sourced, the following two globals are defined:
+
+- `here`: A `pathlib.Path` object containing the path to the directory
+ `BUILD.py` is located in.
+- `register_project`: A function which informs `zmake` of a new
+ project to be built. Your `BUILD.py` file needs to call this
+ function one or more times.
+
+`register_project` takes the following keyword arguments:
+
+- `project_name` (required): The name of the project (typically the
+ Google codename). This name must be unique amongst all projects
+ known to `zmake`, and `zmake` will error if you choose a conflicting
+ name.
+- `zephyr_board` (required): The name of the Zephyr board to use for
+ the project. The Zephyr build system expects a Zephyr board
+ directory under `boards/${ARCH}/${ZEPHYR_BOARD_NAME}`. **Note:**
+ the concept of a Zephyr board does not align with the Chrome OS
+ concept of a board: for most projects this will typically be the
+ name of the EC chip used, not the name of the model or overlay.
+- `supported_toolchains` (required): A list of the toolchain names
+ supported by the build. Valid values are `coreboot-sdk`, `host`,
+ `llvm`, and `zephyr`. Note that only `coreboot-sdk` and `llvm` are
+ supported in the chroot, and all projects must be able to build in
+ the chroot, so your project must at least list one of `coreboot-sdk`
+ or `llvm`.
+- `output_packer` (required): An output packer type which defines
+ which builds get generated, and how they get assembled together into
+ a binary.
+- `modules` (optional): A list of module names required by the
+ project. The default, if left unspecified, is to use all modules
+ known by `zmake`. Generally speaking, there is no harm to including
+ unnecessary modules as modules are typically guarded by Kconfig
+ options, so the only reason to set this is if your project needs to
+ build in a limited environment where not all modules are available.
+- `is_test` (optional): `True` if the code should be executed as a
+ test after compilation, `False` otherwise. Defaults to `False`.
+- `dts_overlays` (optional): A list of files which should be
+ concatenated together and applied as a Zephyr device-tree overlay.
+ Defaults to no overlays (empty list).
+- `project_dir` (optional): The path to where `CMakeLists.txt` and
+ `Kconfig` can be found for the project, defaulting to `here`.
+
+Note that most projects will not want to call `register_project`
+directly, but instead one of the helper functions, which sets even
+more defaults for you:
+
+- `register_host_project`: Define a project which runs in the chroot
+ (not on hardware).
+- `register_host_test`: Just like `register_host_project`, but
+ `is_test` gets set to `True`.
+- `register_raw_project`: Register a project which builds a single
+ `.bin` file, no RO+RW packing, no FMAP.
+- `register_binman_project`: Register a project which builds RO and RW
+ sections, packed together, and including FMAP.
+- `register_npcx_project`: Just like `register_binman_project`, but
+ expects a file generated named `zephyr.npcx.bin` for the RO section
+ with Nuvoton's header.
+
+You can find the implementation of these functions in
+[`zephyr/zmake/zmake/configlib.py`](../../zephyr/zmake/zmake/configlib.py).
+
+`BUILD.py` files are auto-formatted with `black`. After editing a
+`BUILD.py` file, please run `black BUILD.py` on it.
+
+### CMakeLists.txt
+
+This file, should at minimum contain the following:
+
+``` cmake
+cmake_minimum_required(VERSION 3.20.1)
+
+find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
+project(ec)
+```
+
+You may additionally want to specify any C files or include
+directories your project needs using `zephyr_library_sources` or
+`zephyr_library_include_directories`.
+
+### prj.conf and prj_${project_name}.conf
+
+`prj.conf` has default Kconfig settings for all projects, and
+`prj_${project_name}.conf` can contain overrides for certain projects.
+The format is `KEY=VALUE`, as typical for Kconfig.
+
+### Kconfig
+
+If certain projects need project-specific C files or ifdefs, the only
+way to do so is to create a `Kconfig` file with the options schema you
+want, and use it to toggle the inclusion of certain files.
+
+The file must end with a single line that reads
+`source "Kconfig.zephyr"`. Note that this file is optional, so it's
+recommended to only include it if you really need it.
+
+## Setting up a new variant of an EC program
+
+**Unlike our legacy EC, there are no files or directories to copy and
+paste to setup a new variant in Zephyr code.**
+
+Simply add a `register_project`-based call to the existing `BUILD.py`
+for your reference board.
+
+Below is an example of how programs may wish to structure this in
+`BUILD.py`:
+
+``` python
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+def register_variant(project_name, chip="it8xx2", extra_dts_overlays=()):
+ register_binman_project(
+ project_name=project_name,
+ zephyr_board=chip,
+ dts_overlays=[
+ here / "base_power_sequence.dts",
+ here / "i2c.dts",
+ **extra_dts_overlays,
+ ],
+ )
+
+
+# Reference board
+register_variant(
+ project_name="asurada",
+ extra_dts_overlays=[here / "reference_gpios.dts"],
+)
+
+# Variants
+register_variant(
+ project_name="hayato",
+ extra_dts_overlays=[here / "hayato_gpios.dts"],
+)
+```
diff --git a/docs/zephyr/zephyr_build.md b/docs/zephyr/zephyr_build.md
new file mode 100644
index 0000000000..60a9e1d97e
--- /dev/null
+++ b/docs/zephyr/zephyr_build.md
@@ -0,0 +1,172 @@
+# Building Zephyr OS
+
+[TOC]
+
+Chromium OS EC uses the `zmake` tool to build Zephyr.
+
+This section describes how to build and use zmake.
+
+## Syncing the source
+
+N.B. The Zephyr build relies on multiple repos and tools which get installed as
+packages into the chroot. This means that partial syncs are not supported
+(i.e. just doing `repo sync .` in platform/ec). You must run
+`~/trunk/src/scripts/update_chroot` frequently, ideally each time you do a full
+repo sync. This will update zmake and the repos in src/third_party/zephyr
+
+
+## Working inside the chroot
+
+### Install zmake
+
+The `zephyr-build-tools` ebuild builds and installed zmake. This should happen
+automatically, with the caveat above.
+
+To do this manually and run tests:
+
+```bash
+FEATURE=test sudo -E emerge zephyr-build-tools
+```
+
+
+### Building
+
+You can build zephyr with:
+
+```bash
+emerge-volteer chromeos-zephyr
+```
+
+For local development you can run zmake directly; see instruction below.
+
+## Working outside the chroot
+
+Running outside the Chromium OS chroot is useful for upstream work and for
+those using the EC outside the Chromium OS.
+
+
+### Remove west, if installed [b/184654974](http://b/184654974)
+
+Zephyr's Cmake system will try to attach itself to the west tool if it finds it
+installed, conflicting with manual cmake invocations. If you installed west,
+you'll need to remove it:
+
+```bash
+python3 -m pip uninstall west
+```
+
+
+### Install zmake
+
+You can install zmake with pip:
+
+```bash
+cd ~/chromiumos/src/platform/ec
+python3 -m pip install -e zephyr/zmake --user
+```
+
+Ensure that ~/.local/bin in on your PATH
+
+You may also need to install these items:
+
+```bash
+sudo apt-get install cmake ninja-build python3-pyelftools gcc-multilib \
+ python3-pykwalify python3-colorama python3-testfixtures
+```
+
+You must reinstall zmake after any `repo sync` since new features may have been
+added that are needed by the build.
+
+
+### Install binman
+
+First build pylibfdt:
+
+```bash
+cd somewhere
+sudo apt-get install flex bison swig
+git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git
+cd dtc
+make
+make install PREFIX=~/.local # You can install this where it suits
+```
+
+If you have a Chromium OS checkout then you should do:
+
+```bash
+cd ~/.local/bin
+ln -s ~/chromiumos/src/third_party/u-boot/files/tools/binman/binman
+```
+
+otherwise:
+
+```bash
+cd somewhere
+git clone https://source.denx.de/u-boot/u-boot.git
+cd ~/.local/bin
+ln -s somewhere/u-boot/tools/binman/binman
+```
+
+As above, ensure that `~/.local/bin` in on your PATH
+
+
+### Install Zephyr toolchain
+
+If using the Zephyr toolchain (`-t zephyr`), follow the [upstream
+documentation] to install the Zephyr build tools.
+
+[upstream documentation]: https://docs.zephyrproject.org/getting_started/index.html#install-a-toolchain
+
+
+### Building
+
+You can use `zmake help` to obtain help on how to use zmake. The following is
+a rough guide.
+
+First configure the build with the project you want:
+
+```bash
+# Use -t zephyr when running outside chroot
+
+zmake configure -B /tmp/z/vol zephyr/projects/volteer/volteer/ -t zephyr
+```
+
+If you are building for posix-ec, change the default toolchain to host to make
+it use the system toolchain instead of llvm. Make sure to start with a clean
+build directory if zmake returns any build error:
+
+```bash
+zmake configure -B /tmp/posix zephyr/projects/posix-ec -t host
+```
+
+Then build with just the target directory:
+
+```
+zmake build /tmp/z/vol
+```
+
+The output is in that directory:
+
+* `output/zephyr.bin` - output binary (read-only and read-write packed
+ together)
+* `output/zephyr.ro.elf` - read-only ELF for debugging
+* `output/zephyr.rw.elf` - read-write ELF for debugging
+
+You might also find these files useful (using read-only as an example):
+
+* `build-ro/zephyr/.config` - Kconfig options selected
+* `build-ro/zephyr/include/generated/devicetree_unfixed.h` - the (large)
+ header file that zephyr uses to provide devicetree information to the C code
+* `build-ro/zephyr/zephyr.dts` - devicetree that is used
+* `build-ro/zephyr/zephyr.dts` - map of image
+
+
+### Looking at the Kconfig
+
+It should be possible to do this with:
+
+```bash
+ninja -C /tmp/z/vol/build-ro menuconfig
+```
+
+However at present this does not work [b/184662866](http://b/184662866).
diff --git a/docs/zephyr/zephyr_i2c.md b/docs/zephyr/zephyr_i2c.md
new file mode 100644
index 0000000000..625efa98a5
--- /dev/null
+++ b/docs/zephyr/zephyr_i2c.md
@@ -0,0 +1,370 @@
+# Zephyr I2C Bus Configuration
+
+[TOC]
+
+## Overview
+
+The [I2C] buses provide access and control to on-board peripherals, including
+USB-C chips, battery, charging IC, and sensors.
+
+## Kconfig Options
+
+Kconfig Option | Default state | Documentation
+:--------------------------------- | :-----------: | :------------
+`CONFIG_PLATFORM_EC_I2C` | y | [EC I2C]
+
+The following options are available only when `CONFIG_PLATFORM_EC_I2C=y`.
+
+Kconfig sub-option | Default | Documentation
+:-------------------------------------------- | :-----: | :------------
+`CONFIG_I2C_SHELL` | y | [CONFIG_I2C_SHELL]
+`CONFIG_PLATFORM_EC_I2C_DEBUG` | n | [I2C Debug]
+`CONFIG_PLATFORM_EC_I2C_DEBUG_PASSTHRU` | n | [I2C Debug Passthru]
+`CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP` | n | [I2C Portmap]
+`CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_SPEED` | n | [I2C Speed]
+`CONFIG_PLATFORM_EC_HOSTCMD_I2C_CONTROL` | n | [I2C Control]
+`CONFIG_PLATFORM_EC_I2C_PASSTHRU_RESTRICTED` | n | [I2C Passthru Restricted]
+
+## Devicetree Nodes
+
+The EC chip disables all I2C buses by default. Enable the I2C buses used on
+your design by changing the chip-specific I2C bus `status` property to `"okay"`.
+
+I2C bus properties:
+
+Property | Description | Settings
+:------- | :---------- | :-------
+`status` | Enables or disables the I2C controller | `"okay"` <br> `"disabled"`
+`label` | Override the EC chip specific label. We recommend changing the label to match the net name of the I2C bus. The label must begin with `"I2C_"`. |`"I2C_<net_name>"`
+`clock-frequency` | Sets the initial I2C bus frequency in Hz. | `I2C_BITRATE_STANDARD` - 100 KHz <br> `I2C_BITRATE_FAST` - 400 KHz <br> `I2C_BITRATE_FAST_PLUS` - 1 MHz
+
+Example enabling I2C0 and I2C3 at 100 KHz and 1 MHz, respectively.
+```
+&i2c0 {
+ status = "okay";
+ label = "I2C_BATTERY";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+};
+&i2c3 {
+ status = "okay";
+ label = "I2C_USB_C0_PD";
+ clock-frequency = <I2C_BITRATE_FAST_PLUS>;
+};
+```
+
+### Nuvoton NPCX ECs
+
+Nuvoton ECs use two devicetree nodes to describe the I2C buses used, an I2C
+controller and an I2C port.
+
+Nuvoton I2C node labels use the following pattern:
+- I2C controller: `&i2c_ctrl<controller>`
+- I2C port: `&i2c<controller>_<port>`
+
+Where `<controller>` specifies the I2C controller number (0-7), and `<port>`
+specifies the port number (0-1). You can only enable one I2C port per
+controller, and not all I2C controllers support both ports.
+
+The Nuvoton I2C port contains the standard Zephyr I2C bus properties. The
+Nuvoton I2C controller contains only the `status` property.
+
+To enable a Nuvoton I2C bus, set both the I2C controller and I2C port `status`
+property to `"okay"`.Set the `clock-frequency` and `label` properties in the I2C
+port as shown below:
+
+```
+&i2c_ctrl4 {
+ status = "okay";
+};
+&i2c4_1 {
+ status = "okay";
+ label = "I2C_EEPROM";
+ clock-frequency = <I2C_BITRATE_FAST>;
+};
+```
+
+### ITE IT8xxx2 ECs
+
+ITE ECs use a single devicetree node, `&i2c<channel>` to enable an I2C bus.
+`<channel>` specifies the I2C/SMBus channel number (0-5).
+
+```
+&i2c3 {
+ status = "okay";
+ label = "I2C_USB_C0_PD";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+};
+```
+
+### Mapping legacy I2C port numbers to Zephyr devicetree nodes
+
+The legacy I2C API for the Chromium EC application uses an enumeration (e.g.
+`I2C_PORT_ACCEL`, `I2C_PORT_EEPROM`) to specify the I2C bus during transfer
+operations.
+
+The `named-i2c-ports` node creates the mapping between the legacy I2C bus
+enumeration and the Zephyr I2C bus device instance.
+
+```
+named-i2c-ports {
+ compatible = "named-i2c-ports";
+ battery {
+ i2c-port = <&i2c0_0>;
+ remote-port = <0>;
+ enum-name = "I2C_PORT_BATTERY";
+ }
+};
+```
+
+You can map multiple enumeration values to the same Zephyr I2C bus device
+instance.
+
+```
+named-i2c-ports {
+ compatible = "named-i2c-ports";
+ battery {
+ i2c-port = <&i2c0_0>;
+ remote-port = <0>;
+ enum-name = "I2C_PORT_BATTERY";
+ }
+ charger {
+ i2c-port = <&i2c0_0>;
+ remote-port = <0>;
+ enum-name = "I2C_PORT_CHARGER";
+ };
+};
+```
+
+Refer to the [cros-ec-i2c-port-base.yaml] child-binding file for details about
+each property.
+
+## Board Specific Code
+
+None required.
+
+## Threads
+
+I2C support does not enable any threads.
+
+## Testing and Debugging
+
+### Shell Command: i2c
+The EC application enables the the Zephyr shell command, `i2c`, when
+`CONFIG_I2C_SHELL=y`. The `i2c` command includes the following [subcommands]:
+
+Subcommand | Description | Usage
+:--------- | :---------- | :----
+`scan` | Scan I2C devices | `i2c scan <i2c_bus_label>`
+`recover` | Recover I2C bus | `i2c recover <i2c_bus_label>`
+`read` | Read bytes from an I2C device | `i2c read <i2c_bus_label> <dev_addr> <reg_addr> [<num_bytes>]`
+`read_byte` | Read a byte from an I2C device | `i2c read_byte <i2c_bus_label> <dev_addr> <reg_addr>`
+`write` | Write bytes to an I2C device | `i2c write <i2c_bus_label> <dev_addr> <reg_addr> <out_byte0> .. <out_byteN>`
+`write_byte` | Write a byte to an I2C device | `i2c write_byte <i2c_bus_label> <dev_addr> <reg_addr> <out_byte>`
+
+I2C parameter summary:
+
+Parameter | Description
+:-------- | :----------
+`<i2c_bus_label>` | The I2C bus label property. By default this is specified by the EC vendor in the respective devicetree include file unless you override the label in your devicetree.
+`<dev_addr>` | The I2C device address, specified using 7-bit notation. Valid device addresses are 0 - 0x7F.
+`<reg_addr>` | The register address with the I2C device to read or write.
+`<num_bytes>` | For the `read` subcommand, specifies the number of bytes to read from the I2C device. Default is 16 bytes if not specified.
+`<out_byte>` | For the `write_byte` subcommand, specifies the single data byte to write to the I2C device.
+`<out_byte0>..<out_byteN>` | For the `write` subcommand, specifies the data bytes to write to the I2C device.
+
+### Shell Command: i2c_portmap
+The shell command `i2c_portmap` displays the mapping of I2C bus enumeration to
+the physical bus and to the remote port index.
+
+Example `i2c_portmap` output from a Volteer board:
+```
+uart:~$ i2c_portmap
+Zephyr physical I2C ports (9):
+ 0 : 0
+ 1 : 0
+ 2 : 1
+ 3 : 2
+ 4 : 3
+ 5 : 4
+ 6 : 4
+ 7 : 5
+ 8 : 5
+Zephyr remote I2C ports (9):
+ 0 : -1
+ 1 : -1
+ 2 : -1
+ 3 : -1
+ 4 : -1
+ 5 : -1
+ 6 : -1
+ 7 : 7
+ 8 : -1
+```
+
+### I2C Tracing
+
+For runtime troubleshooting of an I2C device, enable the [I2C
+tracing](../i2c-debugging.md) module to log all I2C transactions initiated by
+the EC code.
+
+## Example
+
+The image below shows the I2C bus assignment for the Volteer reference board.
+
+![I2C Example]
+
+The Volteer reference design uses the Nuvoton NPCX EC, and needs the following
+I2C buses enabled:
+
+Net Name | NPCX I2C Designator | Bus speed
+:----------------- | :------------------ | :--------
+EC_I2C7_EEPROM_PWR | I2C7_PORT0 | 400 kHz
+EC_I2C5_BATTERY | I2C5_PORT0 | 100 kHz
+EC_I2C0_SENSOR | I2C0_PORT0 | 400 kHz
+EC_I2C1_USB_C0 | I2C1_PORT0 | 1000 kHz
+EC_I2C2_USB_C1 | I2C2_PORT0 | 1000 kHz
+EC_I2C3_USB_1_MIX | I2C3_PORT0 | 100 kHz
+
+
+### Enable Nuvoton I2C buses
+The Volteer project enables the Nuvoton I2C buses in [volteer.dts].
+
+```c
+&i2c0_0 {
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_FAST>;
+ label = "I2C_SENSOR";
+};
+&i2c_ctrl0 {
+ status = "okay";
+};
+
+&i2c1_0 {
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_FAST_PLUS>;
+ label = "I2C_USB_C0";
+};
+&i2c_ctrl1 {
+ status = "okay";
+};
+
+&i2c2_0 {
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_FAST_PLUS>;
+ label = "I2C_USB_C1";
+};
+&i2c_ctrl2 {
+ status = "okay";
+};
+
+&i2c3_0 {
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ label = "I2C_USB_1_MIX";
+};
+&i2c_ctrl3 {
+ status = "okay";
+};
+
+&i2c5_0 {
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+ label = "I2C_BATTERY";
+};
+&i2c_ctrl5 {
+ status = "okay";
+};
+
+&i2c7_0 {
+ status = "okay";
+ clock-frequency = <I2C_BITRATE_FAST>;
+ label = "I2C_EEPROM_PWR";
+
+ isl9241: isl9241@9 {
+ compatible = "intersil,isl9241";
+ reg = <0x09>;
+ label = "ISL9241_CHARGER";
+ switching-frequency = <SWITCHING_FREQ_724KHZ>;
+ };
+};
+&i2c_ctrl7 {
+ status = "okay";
+};
+```
+
+### Map I2C Enumerations
+The legacy cros-ec drivers require the board to define the following enumeration
+values:
+
+I2C Enumeration Name | Volteer I2C Bus Mapping
+:------------------- | :----------------------
+`I2C_PORT_SENSOR` | EC_I2C0_SENSOR
+`I2C_PORT_ACCEL` | EC_I2C0_SENSOR
+`I2C_PORT_USB_C0` | EC_I2C1_USB_C0
+`I2C_PORT_USB_C1` | EC_I2C2_USB_C1
+`I2C_PORT_USB_1_MIX` | EC_I2C3_USB_1_MIX
+`I2C_PORT_POWER` | EC_I2C5_BATTERY
+`I2C_PORT_BATTERY` | EC_I2C5_BATTERY
+`I2C_PORT_EEPROM` | EC_I2C7_EEPROM_PWR
+`I2C_PORT_CHARGER` | EC_I2C7_EEPROM_PWR
+
+The Volteer project establishes this map using the `named-i2c-ports` as shown
+below:
+
+```c
+ named-i2c-ports {
+ compatible = "named-i2c-ports";
+
+ i2c_sensor: sensor {
+ i2c-port = <&i2c0_0>;
+ enum-name = "I2C_PORT_SENSOR";
+ };
+ i2c-accel {
+ i2c-port = <&i2c0_0>;
+ enum-name = "I2C_PORT_ACCEL";
+ };
+ i2c_usb_c0: usb-c0 {
+ i2c-port = <&i2c1_0>;
+ enum-name = "I2C_PORT_USB_C0";
+ };
+ i2c_usb_c1: usb-c1 {
+ i2c-port = <&i2c2_0>;
+ enum-name = "I2C_PORT_USB_C1";
+ };
+ usb1-mix {
+ i2c-port = <&i2c3_0>;
+ enum-name = "I2C_PORT_USB_1_MIX";
+ };
+ power {
+ i2c-port = <&i2c5_0>;
+ enum-name = "I2C_PORT_POWER";
+ };
+ battery {
+ i2c-port = <&i2c5_0>;
+ enum-name = "I2C_PORT_BATTERY";
+ };
+ eeprom {
+ i2c-port = <&i2c7_0>;
+ remote-port = <7>;
+ enum-name = "I2C_PORT_EEPROM";
+ };
+ charger {
+ i2c-port = <&i2c7_0>;
+ enum-name = "I2C_PORT_CHARGER";
+ };
+ };
+```
+
+[I2C]: ../ec_terms.md#i2c
+[subcommands]: https://github.com/zephyrproject-rtos/zephyr/blob/f4a0ea7b43eee4d2ee735ab6beccc68c9d40a7d0/drivers/i2c/i2c_shell.c#L245
+[I2C Example]: ../images/i2c_example.png
+[EC I2C]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig;?q="config%20PLATFORM_EC_I2C"&ss=chromiumos
+[CONFIG_I2C_SHELL]: https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_I2C_SHELL.html
+[I2C Debug]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig;?q=PLATFORM_EC_I2C_DEBUG&sq=&ss=chromiumos
+[I2C Debug Passthru]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig;?q=PLATFORM_EC_I2C_DEBUG_PASSTHRU&ss=chromiumos
+[I2C Portmap]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP&ss=chromiumos%2Fchromiumos%2Fcodesearch
+[I2C Speed]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_CONSOLE_CMD_I2C_SPEED&ss=chromiumos
+[I2C Control]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_HOSTCMD_I2C_CONTROL&ss=chromiumos
+[I2C Passthru Restricted]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_I2C_PASSTHRU_RESTRICTED&ss=chromiumos
+[cros-ec-i2c-port-base.yaml]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml
+[volteer.dts]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/boards/arm/volteer/volteer.dts;
diff --git a/docs/zephyr/zephyr_init.md b/docs/zephyr/zephyr_init.md
new file mode 100644
index 0000000000..8822736efb
--- /dev/null
+++ b/docs/zephyr/zephyr_init.md
@@ -0,0 +1,53 @@
+# Zephyr OS-based EC Initialization Order
+
+Zephyr provides Z_INIT_ENTRY_DEFINE() & the extend macro to install the initial
+function. The initialize flow for different levels would be like the following
+(not very detailed):
+* architecture-specific initialization
+* `PRE_KERNEL_1` level
+* `PRE_KERNEL_2` level
+* `POST_KERNEL` level
+* `APPLICATION` level
+* main()
+
+The kernel and driver initial functions separate into specific initialize
+levels. It couldn't put all initial functions in main() for the Zephyr OS-based
+EC. It is also hard to maintain those initial priority which separates into
+different files.
+
+This file defines some Zephyr OS-based EC initial priorities which have critical
+sequence requirement for initializing:
+
+## PRE_KERNEL_1
+* Priority (0-9) - Reserved for system testability:
+
+ The highest priority could be used in zephyr. Don't use it when system
+ development. Buffer it for the following system development & testing.
+
+* Priority (10-19) - Chip level system pre-initialization:
+
+ These priorities in this range are used for critical chip initialization,
+ including determining the reset cause and initializing the battery-backed
+ RAM driver. Most chip drivers should only be initialized after
+ `PLATFORM_EC_SYSTEM_PRE_INIT`.
+
+* Priority (20) - PLATFORM_EC_SYSTEM_PRE_INIT:
+
+ At this initialization priority, the CROS system checks the reset cause and
+ initializing the system reset flags. Any chip level drivers related to
+ determining the reset type must be at a higher priority.
+
+* TODO
+
+## PRE_KERNEL_2
+* TODO
+
+## POST_KERNEL
+* TODO
+
+## APPLICATION
+* TODO
+
+## main()
+* TODO
+* Start the tasks.
diff --git a/docs/zephyr/zephyr_new_board_checklist.md b/docs/zephyr/zephyr_new_board_checklist.md
new file mode 100644
index 0000000000..c90bd4e2f2
--- /dev/null
+++ b/docs/zephyr/zephyr_new_board_checklist.md
@@ -0,0 +1,65 @@
+# Creating a New Zephyr EC Project
+
+[TOC]
+
+## Overview
+
+This document describes the high-level steps needed to create a new Zephyr EC
+project for a Chromebook design.
+
+## Intended Audience
+
+This document is for use by software engineers working in the EC codebase. This
+document and the linked documents provide a guide for creating new Zephyr EC
+projects and for modifying/maintaining existing Zephyr EC projects.
+
+## How to use this document
+
+The following sections detail a single feature set that needs modification for
+your board design. Each feature set can be implemented with a reasonably sized
+change list, and can be worked on independently.
+
+Each feature includes the following sub-tasks:
+
+- **Kconfig Options** - This section details the `Kconfig` options relevant to
+ the feature. `Kconfig` options are enabled in one of the [project
+ configuration files].
+- **Devicetree Nodes** - This section details the devicetree nodes and
+ properties required by the feature.
+- **Board Specific Code** - When present, this section details any C code that
+ your project must implement.
+- **Threads** - This section details the threads created by the feature and
+ provides an overview of each thread.
+- **Testing and Debugging** - This section details strategies for testing the EC
+ feature set and for debugging issues. This section also documents EC console
+ commands related to the feature set.
+- **Example** - This section walks through a complete example for configuring an
+ EC feature based on existing board implementation.
+
+## Adding a new board to zmake
+
+Refer the [zmake](TODO) documentation to add a new board project to zmake.
+
+## Configure EC Features
+
+The checklist below provides an overview of EC features that you must configure
+for correct operation of a Chromebook. The “Needed for Power On” column
+indicates the critical features needed during board bringup. Use the
+documentation link for details about the code changes required to implement each
+feature.
+
+EC Feature | Needed for Power On
+:-------------------------------------------------------------------------- | :-----------------:
+[Configure EC Chipset (TODO)](./zephyr_template.md) | yes
+[Configure AP to EC Communication (TOD0)](./zephyr_template.md) | yes
+[Configure AP Power Sequencing (TODO)](./zephyr_template.md) | yes
+[Configure USB-C (TODO)](./zephyr_template.md) | yes
+[Configure Charger (TODO)](./zephyr_template.md) | yes
+[Configure I2C Buses (TODO)](./zephyr_template.md) | yes
+[Configure Batteries (TODO)](./zephyr_template.md) | no
+[Configure CrOS Board Information (CBI) (TODO)](./zephyr_template.md) | no
+[Configure Keyboard (TODO)](./zephyr_template.md) | no
+[Configure LEDs (TODO)](./zephyr_template.md) | no
+[Configure Motion Sensors (TODO)](./zephyr_template.md) | no
+[Configure BC1.2 Charger Detector (TODO)](./zephyr_template.md) | no
+[Configure Battery (TODO)](./zephyr_template.md) | no
diff --git a/docs/zephyr/zephyr_poc_device_bringup.md b/docs/zephyr/zephyr_poc_device_bringup.md
new file mode 100644
index 0000000000..394aa4a05b
--- /dev/null
+++ b/docs/zephyr/zephyr_poc_device_bringup.md
@@ -0,0 +1,52 @@
+# Zephyr Proof-of-Concept-Device Bringup
+
+It may be useful to build a Zephyr OS-based EC for a device which
+already has a CrOS EC device build, for the purposes of demonstrating
+the feasibility of Zephyr OS.
+
+This document is a work-in-progress list of tricks & tools that may be
+useful to you.
+
+## Initial Bringup
+
+Initially, you'll want to get a basic UART functioning with nothing
+but a shell and some basic console commands.
+
+An example CL to do this for Lazor can be found
+[here](https://crrev.com/c/2749765).
+
+## Bringing up GPIOs
+
+After you have UART functioning, GPIOs can be an easy target to start
+unblocking further features.
+
+We have a very ugly program to auto-generate the GPIO DTS based on
+gpio.inc for the existing board. You can find it at
+`util/gpios_to_zephyr_dts.c`, and instructions are in the file on how
+to compile and use it. You may have to hand-modify the output.
+
+The resultant CL for Lazor can be found [here](https://crrev.com/c/2749768).
+
+## Bring up Host Commands
+
+Set `CONFIG_PLATFORM_EC_HOSTCMD=y` and enable the appropriate
+host-command interface for your platform (e.g., eSPI).
+
+An example CL for Lazor can be found [here](https://crrev.com/c/2749428).
+
+As long as you get this compiling that should be enough to move to the
+next step. Further testing of the host command layer will require
+power sequencing up and going.
+
+## Enabling some simple GPIO-based buttons and switches
+
+Next, you can:
+
+* [Add the lid switch](https://crrev.com/c/2749768)
+* [Add the power button](https://crrev.com/c/2749426)
+* [Add AC presence detection](https://crrev.com/c/2749428)
+
+## Power Sequencing
+
+TODO(jrosenth): add steps on enabling power sequencing and expand this
+document.
diff --git a/docs/zephyr/zephyr_shim.md b/docs/zephyr/zephyr_shim.md
new file mode 100644
index 0000000000..fac0383aff
--- /dev/null
+++ b/docs/zephyr/zephyr_shim.md
@@ -0,0 +1,381 @@
+[TOC]
+
+# Zephyr Shimming How-To
+
+## Objective
+
+Allow a subset of the platform/ec code to be built as part of the Zephyr-based
+EC without needing to land code into upstream zephyr, or our zephyr-chrome
+repository.
+
+## Background
+
+Now that Google has joined [Zephyr OS](https://www.zephyrproject.org/), the EC
+team is moving toward it instead of platform/ec code on embedded controllers for
+future Chrome OS devices. See the
+[originally proposed idea](https://goto.google.com/cros-ec-rtos) and a more
+specific [Zephyr process doc](https://goto.google.com/zephyr-structure) of what
+future development on Zephyr will look like.
+
+Simply put, we want to move to Zephyr OS to use an open-source embedded OS that
+has a vibrant community. The embedded OS scene for the industry is very
+fragmented, with various parties using their own custom solution. We see the
+strong open-source community at Zephyr as potentially helping to consolidate
+efforts in the embedded controller space. It will also benefit our partners
+(both chip vendors and OEMs) since they should only have to support one embedded
+OS (i.e., Zephyr) for both their Chrome OS and Windows based devices.
+
+Migrating to use Zephyr fully is going to take a few years. We do not want to
+diverge from the active development happening on platform/ec code. We
+potentially want to ship a product using Zephyr before the migration is
+complete.
+
+## Design ideas
+
+In order to reuse `platform/ec` development , we shim "active" `platform/ec`
+code as a
+[Zephyr Module](https://docs.zephyrproject.org/latest/guides/modules.html). This
+requires us to add some Zephyr specific code in a `zephyr` directory in the
+`platform/ec` codebase. Once we release a Zephyr-based EC, then we can turn down
+platform/ec for future development and work on migrating the platform/ec-module
+code out of the module directory and into a first-class Zephyr code format -- in
+the local
+[Chrome Zephyr repo](https://chromium.googlesource.com/chromiumos/platform/zephyr-chrome/+/HEAD)
+and ultimately [upstream](https://github.com/zephyrproject-rtos/zephyr).
+
+For platform/ec code that is stable and not under active development, the Zephyr
+team may port that code to Zephyr, thus skipping the shimming process.
+
+### Subsystems of interest
+
+#### With Shim
+
+We shim the following subsystems (non-exhaustive).
+
+* USB-C: TCPC, PPC, MUX, TCPMv2
+* Charge Manager
+* SoC Power Sequencing
+* Sensors, if Intel’s HID-based solution is delayed in getting to Zephyr
+ upstream
+
+#### Little-to-No Shim
+
+We adopt upstream Zephyr or skip the shimming process (non-exhaustive).
+
+* CBI and dependent EEPROM code
+ * The format is stable. We pull in the list of CBI tags from platform/ec
+ though
+* EFS2, Vboot, RO/RW split
+ * Adjusting flash layout would be difficult to shim, and the concept is
+ very stable.
+ * We may shim some core EFS2 logic
+* Host command framework
+* Sensors, if Intel’s HID-based solution getts to Zephyr upstream and passes
+ CTS
+* Keyboard and keycode scanning support
+ * We may shim the newer Vivaldi feature.
+* Console support
+ * We allow individual console commands via DECLARE\_CONSOLE\_COMMAND to be
+ shimmed to Zephyr. These convert commands to work with Zephyr's shell
+ subsystem.
+* I2C
+
+### New content in platform/ec
+
+Add the `src/platform/ec/zephyr` folder with:
+
+* [Module integration files](https://docs.zephyrproject.org/latest/guides/modules.html#build-system-integration),
+ e.g., module.yml, CMakeLists.txt, and KConfig.
+ * **module.yml** is the required entry point (must be located at
+ _zephyr/module.yml_ in the repository) for Zephyr modules, and declares
+ the location of Kconfig and CMakeLists.txt files used by the Zephyr
+ build system.
+ * **CMakeLists.txt** replicates build logic for the files being shimmed,
+ outside of the platform/ec Makefile.
+ * **Kconfig** will declare any CONFIG\_\* options which are important to
+ expose from platform/ec code to the Zephyr build.
+* Shim code to translate platform/ec code into Zephyr code
+ * For example, redefine platform/ec’s
+ [`DECLARE_HOST_COMMAND`](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/HEAD:src/platform/ec/include/host_command.h;l=256;drc=514923bc59f5a3435dbb7cbf348735ed41889ffe)
+ to map to Zephyr's upstream
+ [`EC_HOST_CMD_HANDLER`](https://github.com/zephyrproject-rtos/zephyr/blob/d7468bf836b75c29980441f294a61eae6bf4bc75/include/ec_host_cmd.h#L73)
+ macro. This allows us to compile select platform/ec files in the Zephyr
+ build.
+
+### Namespace Collisions
+
+One significant issue of mixing Zephyr headers with our existing EC code is that
+we currently have many names colliding with the Zephyr code. For example,
+Zephyr's atomic functions also are named `atomic_add`, `atomic_or`, ...,
+however, have a different API from our EC's atomic functions. This is critical,
+since atomic operations are often used in `static inline` functions placed in
+header files.
+
+In some cases, we are able to hack around these collisions by creating macros
+and functions which are compatible with both Zephyr and our EC's usages. For
+example, we can create a modified `IS_ENABLED` which accepts both defined to
+nothing usages (CrOS EC `config.h` style), and defined to `1` usages (Zephyr
+Kconfig style).
+
+However, long term, we may find this to be a continual cause of issues, and
+creating hacks for every colliding macro or function may be unsustainable. We
+propose _gradually_ introducing a namespace prefix to the `platform/ec`
+codebase, for example `crec_`. We can begin at the critical areas of namespace
+collision (e.g., atomics) and continue to improve the naming convention with
+time.
+
+### New CQ check
+
+As long as code from platform/ec is part of the zephyr
+[ebuild](http://cs/chromeos_public/src/third_party/chromiumos-overlay/chromeos-base/chromeos-zephyr-2_3/chromeos-zephyr-2_3-9999.ebuild),
+then we need to run the Zephyr CQ checks on any platform/ec CLs in addition to
+the normal platform/ec CQ checks. This ensures that platform/ec changes aren’t
+breaking the Zephyr builds and requiring the Zephyr team to debug recent
+changes.
+
+For local builds, we can run `emerge-betty chromeos-zephyr-2_3` or `zmake`
+utility to check that an EC CL has not broken anything on the Zephyr side.
+
+We will work with the CI team to enable this.
+
+## How to shim features
+
+Before you get started shimming a feature, it's important to
+understand the general philosophies behind Zephyr OS and shimming:
+
+* Our current EC's OS isn't going away any time soon. Even after we
+ ship our first device with a Zephyr-based EC, we may still be working on
+ other projects using the old OS. It's important to consider how
+ your feature will apply to both the Zephyr world and CrOS EC OS
+ world.
+
+* We won't be converting old devices to use Zephyr-based firmware.
+ This means that our existing OS and its code will need maintained
+ for bug and security fixes for years to come. **Do not allow the
+ code you write for the CrOS EC OS to lack in quality or be "throw
+ away code" as it will need to be maintained for a long time.**
+
+* Shimming, by the very nature of the design, will lead to some ugly
+ hacks. We try and avoid this when we can, but some of them may be
+ completely unavoidable. This means we need to actively work against
+ nature to keep the code clean. If we do things right, there's even
+ a possibility that we leave things cleaner than we found them.
+
+* Shimming occasionally digs up landmines. Be prepared to step on
+ them. 💣
+
+### What code can be shimmed?
+
+Code in the `common/` directory (and other common code directories,
+like `power/`) is the ideal target for shimming, with the exception of
+core OS features which have Zephyr OS equivalents.
+
+Code in the following directories should **never be shimmed**:
+
+- `core/`: this directory contains architecture-specific code which
+ should have a Zephyr OS equivalent feature.
+
+- `chip/`: this directory contains chip-specific code, and similarly
+ should have a Zephyr OS equivalent feature.
+
+In both cases, you should instead determine (or, in rare cases,
+implement upstream) the equivalent Zephyr OS feature, and *implement
+an architecture and chip agnostic* "shim layer" in the `zephyr/shim/`
+directory which translates the APIs as necessary.
+
+As of the time of this document, the shim layer is nearing 100%
+complete, and it should be rare that you encounter an API which needs
+translation.
+
+Finally, code in the following directories should **avoid being
+shimmed, if possible**:
+
+- `board/`: this directory contains variant-specific code.
+
+- `baseboard/`: this directory contains baseboard-specific code.
+
+In both cases, the only value in shimming in code from one of those
+directories would be to enable a Zephyr OS build for a device which
+already has CrOS EC OS support, as *Zephyr-only projects will not have
+these directories*. You should be thinking about how this would be
+implemented for a Zephyr-only project, and filing bugs to create the
+appropriate device-tree and Kconfig equivalents before shimming this
+code.
+
+See [Zephyr PoC device bringup](zephyr_poc_device_bringup.md) for more
+information about bringing up proof-of-concept devices.
+
+### Configuration
+
+CrOS EC OS uses a special header `config.h`, which sets configuration
+defaults, and includes board and chip specific configurations by
+expecting the headers `board.h` and `config_chip.h` to be present.
+Most of these configuration options start with `CONFIG_`, however the
+rules were loosely defined over the years.
+
+Zephyr OS, on the other hand, uses two different configuration
+systems:
+
+* Kconfig, the configuration system from the Linux Kernel, which
+ fits well within the domain of preprocessor definitions in C. The
+ schema for our Kconfig files can be found under `zephyr/Kconfig`,
+ and project-specific configurations are made in `prj.conf` files.
+
+ Kconfig is generally used to select which EC software features are
+ enabled, and should be avoided for hardware configurations, such as
+ chip configuration registers and their default settings.
+
+* Open Firmware Device Tree, which you may also be familiar with from
+ the Linux kernel. This configuration can be found in `*.dts` files.
+
+ Device-tree is generally used for hardware configurations, and
+ should be avoided for EC software feature configuration.
+
+For code which is shimmed, we need to play nicely with both the CrOS
+EC OS configuration system, and Zephyr's configuration systems. Thus,
+we follow the following pattern:
+
+* EC software features are configured using `Kconfig` and
+ `zephyr/shim/include/config_chip.h` translates them into the
+ appropriate CrOS EC OS configurations using patterns such as below:
+
+ ```c
+ #undef CONFIG_CMD_GETTIME
+ #ifdef CONFIG_PLATFORM_EC_TIMER_CMD_GETTIME
+ #define CONFIG_CMD_GETTIME
+ #endif
+ ```
+
+ The preprocessor code should follow that template exactly, and not
+ use any nesting (Kconfig handles dependencies, there is no reason to
+ do it again in the preprocessor code).
+
+* **The domain of Kconfig options and CrOS EC configuration names
+ should be completely distinct.** This is because the Kconfig options
+ are included automatically, and including `config.h` may undefine
+ them. To mitigate this, we follow a convention of using
+ `CONFIG_PLATFORM_EC_` as the prefix for EC software features in
+ Kconfig.
+
+One special configuration option exists, `CONFIG_ZEPHYR`, which you
+can use to detect whether the OS is Zephyr OS. This is the
+conventional way to add Zephyr-specific (or excluded) code in CrOS EC
+code.
+
+The typical EC macros for reducing `#ifdef` messes (e.g.,
+`IS_ENABLED`, `STATIC_IF`, etc.) work with both CrOS EC OS and Kconfig
+options, and should be used when possible.
+
+### Header Files
+
+Besides the include paths provided by Zephyr OS, the following paths
+are additionally added for shimmed code:
+
+* `include/`
+* `zephyr/include/`
+* `zephyr/shim/include/`
+
+The names of headers in these directories should be completely
+distinct. C compilers have no mechanism for "include ordering", and
+there is no way to "override a header".
+
+If you feel the need to "override" a header, say `foo.h` in
+`include/`, the best way to do this is to give it a different name
+under `zephyr/shim/include` (e.g., `zephyr_foo_shim.h`), and include
+that in the `foo.h` header with a `#ifdef CONFIG_ZEPHYR` guard.
+
+The typical styling convention for includes (following existing
+conventions in `platform/ec` and other C codebases we have) is:
+
+* Zephyr OS headers in pointy brackets, in alphabetical order.
+
+* One blank line
+
+* CrOS EC OS headers (either from `include/`, `zephyr/shim/include/`,
+ or the current directory), in quotes (not pointy brackets).
+
+### Adding files to Cmake
+
+Zephyr's build system (including shimmed code) uses CMake instead of
+`Makefiles`, and your code will not be compiled for Zephyr unless you
+list the files in `zephyr/CMakeLists.txt`.
+
+### Step-by-step guide to adding a Kconfig
+
+Follow these steps:
+
+1. Make sure you have read the above Configuration section
+
+2. Add your config to one of zephyr/Kconfig* files. Note the PLATFORM_EC_ prefix
+ and try to put it near related things:
+
+ ```kconfig
+ config PLATFORM_EC_CHARGER_BQ25720
+ bool "TI BQ25720 charger"
+ help
+ The TI BQ25720 is a blah blah (describe summary from datasheet,
+ at least 3 lines so take 10 minutes to write something truly useful)
+ ```
+
+ Consider a `depends on PLATFORM_EC_...` line if it depends on an existing
+ feature.
+
+3. Add to zephyr/shim/include/config_chip.h (put it at the bottom):
+
+ ```kconfig
+ #undef CONFIG_CHARGER_BQ25720
+ #ifdef CONFIG_PLATFORM_EC_CHARGER_BQ25720
+ #define CONFIG_CHARGER_BQ25720
+ #endif
+ ```
+
+4. Add the source file to zephyr/CMakeLists.txt if it is not already there. For
+ ordering check the comments in that file:
+
+ `zephyr_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_BQ25720
+ "${PLATFORM_EC}/driver/charger/bq25720.c")`
+
+5. Run a build on a board that enables the new CONFIG (in config.h) to make sure
+ there are no problems.
+
+6. If it doesn't work, please email zephyr-task-force@ or file a bug and assign
+ it to sjg@, cc zephyr-task-force@ (please include CL link and the error
+ output).
+
+### Unit Tests
+
+Unit tests, implemented using the Ztest framework, can be found in
+`zephyr/test`.
+
+To run all unit tests, you use `zmake testall`.
+
+## Alternatives Considered
+
+### Translate code and mirror into the zephyr-chrome repository
+
+We could potentially write a script which, via a series of find/replace
+operations, translates a platform/ec module to use Zephyr functions, macros, and
+paradigms. On a frequent basis, we would translate all modules of interest in
+the platform/ec repository and land an "uprev" change in the zephyr-chrome
+repository.
+
+The main disadvantage of this technique is that we can't get any CQ coverage
+when platform/ec CLs land that the modules will continue to work in Zephyr.
+Additionally, the translator script would be delicate and probably require
+frequent maintenance.
+
+However, this technique does have some benefits. With modules directly
+translated to code in the Zephyr paradigm, the process of upstreaming a shimmed
+module to ZephyrOS would be significantly easier. Additionally, it would require
+no shim code in platform/ec.
+
+### Don't do any code sharing
+
+One option is to avoid shimming in any platform/ec code and allow the Zephyr
+team to re-implement features in upstream zephyr, or our local zephyr-chrome
+repository.
+
+Disregarding the infeasible amount of work required to complete this option, the
+platform/ec repository has a far faster development pace as there are many more
+contributors, and the Zephyr features would quickly lose parity during the time
+frame that we are launching both Zephyr-based and platform/ec-based devices.
diff --git a/docs/zephyr/zephyr_template.md b/docs/zephyr/zephyr_template.md
new file mode 100644
index 0000000000..f75883eec9
--- /dev/null
+++ b/docs/zephyr/zephyr_template.md
@@ -0,0 +1,56 @@
+# Zephyr EC Feature Configuration Template
+
+[TOC]
+
+## Overview
+
+*Description of the Zephyr EC feature and the capabilities provided*
+
+## Kconfig Options
+
+*List the Kconfig options that enable the feature and list any sub-configuration
+options that control the behavior of the feature.*
+
+Kconfig Option | Default | Documentation
+:------------------------------------- | :-----: | :------------
+`CONFIG_PLATFORM_EC_<option>` | y/n | [zephyr/Kconfig](../zephyr/Kconfig)
+
+Kconfig sub-option | Default | Documentation
+:------------------------------------- | :-----: | :------------
+`CONFIG_PLATFORM_EC_<option>` | y/n | [zephyr/Kconfig](../zephyr/Kconfig)
+
+
+*Note - Avoid documenting `CONFIG_` options in the markdown as the relevant
+`Kconfig*` contains the authoritative definition. Link directly to the Kconfig
+option in source like this: [I2C Passthru Restricted].*
+
+## Devicetree Nodes
+
+*Detail the devicetree nodes that configure the feature.*
+
+*Note - avoid documenting node properties here. Point to the relevant `.yaml`
+file instead, which contains the authoritative definition.*
+
+## Board Specific Code
+
+*Document any board specific routines that a user must create to successfully
+compile and run. For many features, this can section can be empty.*
+
+## Threads
+
+*Document any threads enabled by this feature.*
+
+## Testing and Debugging
+
+*Provide any tips for testing and debugging the EC feature.*
+
+## Example
+
+*Provide code snippets from a working board to walk the user through
+all code that must be created to enable this feature.*
+
+<!--
+The following demonstrates linking to a code search result for a Kconfig option.
+Reference this link in your text by matching the text in brackets exactly.
+-->
+[I2C Passthru Restricted]:https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=%22config%20PLATFORM_EC_I2C_PASSTHRU_RESTRICTED%22&ss=chromiumos
diff --git a/docs/zephyr/ztest.md b/docs/zephyr/ztest.md
new file mode 100644
index 0000000000..021b3391bd
--- /dev/null
+++ b/docs/zephyr/ztest.md
@@ -0,0 +1,200 @@
+# Porting EC unit tests to Ztest
+
+[TOC]
+
+This HOWTO shows the process for porting the EC's `base32` unit test to Zephyr's
+Ztest framework. All of the work is done in `src/platform/ec`.
+
+See
+[Test Framework - Zephyr Project Documentation](https://docs.zephyrproject.org/1.12.0/subsystems/test/ztest.html#quick-start-unit-testing)
+for details about Zephyr's Ztest framework.
+
+For examples of porting an EC unit test to the Ztest API, see: *
+[base32](https://crrev.com/c/2492527) and
+[improvements](https://crrev.com/c/2634401) *
+[accel_cal](https://crrev.com/c/2645198)
+
+## Porting Considerations
+
+Not every EC unit test can be ported to Ztest. This section describes cases that
+are not supported and cases where caveats apply.
+
+### EC Mocks Are Not Supported
+
+If a test has a `$TEST.mocklist` file associated with the unit test, it is using
+the EC mocking framework, which is unsupported in the Ztest framework. Ztest has
+its own mocking framework which the EC does not support.
+
+### Multiple Task Caveats
+
+The EC unit test framework starts a single task to call `run_test`, and this
+task will then call the functions for the various test cases. Some unit tests
+have multiple threads of execution, which is enabled by a `$TEST.tasklist` file
+associated with the unit test. The test runner task has a task ID of
+`TASK_ID_TEST_RUNNER`, which can be used as an argument to any of the task
+functions. See for example the
+[`charge_ramp` unit test](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/test/charge_ramp.c#81)
+and the
+[`host_command` unit test](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/test/host_command.c#32)
+
+When a unit test is ported to Ztest, `test_main` doesn't have a thread ID, so
+`TASK_ID_TEST_RUNNER` is undefined. `charge_ramp` and `host_command` cannot be
+ported at this time. `test_main` also cannot call any of the task functions that
+must be called from a task, such as `task_wake`; these functions can pend the
+calling task, but since `test_main` doesn't have a thread ID, the pend will
+fail. See the
+[`mutex` unit test](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/test/mutex.c#116)
+for an example.
+
+## Determine source files being tested
+
+Determine which C files the unit test requires by finding the test in
+`test/test_config.h`:
+
+```
+#ifdef TEST_BASE32
+#define CONFIG_BASE32
+#endif
+```
+
+Locate the `CONFIG` item(s) in `common/build.mk`:
+
+```
+common-$(CONFIG_BASE32)+=base32.o
+```
+
+So for the `base32` test, we only need to shim `common/base32.c`.
+
+Add the C files to `zephyr/shim/CMakeLists.txt`, in the "Shimmed modules"
+section:
+
+```
+# Shimmed modules
+zephyr_sources_ifdef(CONFIG_PLATFORM_EC "${PLATFORM_EC}/common/base32.c")
+```
+
+Refer to [zephyr: shim in base32.c](https://crrev.com/c/2468631).
+
+## Create test directory
+
+Create a new directory for the unit test in `zephyr/test/base32`.
+
+Create `zephyr/test/base32/prj.conf` with these contents:
+
+```
+CONFIG_ZTEST=y
+CONFIG_PLATFORM_EC=y
+```
+
+Create `zephyr/test/base32/CMakeLists.txt` with these contents:
+
+```
+target_sources(app PRIVATE ${PLATFORM_EC}/test/base32.c)
+```
+
+## Modify test source code
+
+### Test cases
+
+In the unit test, replace `run_test` with `TEST_MAIN()`. This will allow both
+platform/ec tests and Ztests to share the same entry point.
+
+Change `RUN_TEST` to `ztest_unit_test` and add the `ztest_test_suite` wrapper
+plus the call to `ztest_run_test_suite`.
+
+```c
+/*
+ * Define the test cases to run. We need to do this twice, once in the format
+ * that Ztest uses, and again in the format the the EC test framework uses.
+ * If you add a test to one of them, make sure to add it to the other.
+ */
+TEST_MAIN()
+{
+ ztest_test_suite(test_base32_lib,
+ ztest_unit_test(test_crc5),
+ ztest_unit_test(test_encode),
+ ztest_unit_test(test_decode));
+ ztest_run_test_suite(test_base32_lib);
+}
+```
+
+Each function that is called by `ztest_unit_test` needs to be declared using
+`DECLARE_EC_TEST`. Keep the `return EC_SUCCESS;` at the end of the test
+function. Note that for the EC build, `TEST_MAIN` will call `test_reset` before
+running the test cases, and `test_print_result` after.
+
+### Assert macros
+
+Change the `TEST_ASSERT` macros to `zassert` macros. There are plans to automate
+this process, but for now, it's a manual process involving some intelligent
+find-and-replace.
+
+* `TEST_ASSERT(n)` to `zassert_true(n, NULL)`
+* `TEST_EQ(a, b, fmt)` to `zassert_equal(a, b, fmt ## ", " ## fmt, a, b)`
+ * e.g. `TEST_EQ(a, b, "%d")` becomes `zassert_equal(a, b, "%d, %d", a, b)`
+* `TEST_NE(a, b, fmt)` to `zassert_not_equal(a, b, fmt ## ", " ## fmt, a, b)`
+* `TEST_LT(a, b, fmt)` to `zassert_true(a < b, fmt ## ", " ## fmt, a, b)`
+* `TEST_LE(a, b, fmt)` to `zassert_true(a <= b, fmt ## ", " ## fmt, a, b)`
+* `TEST_GT(a, b, fmt)` to `zassert_true(a > b, fmt ## ", " ## fmt, a, b)`
+* `TEST_GE(a, b, fmt)` tp `zassert_true(a >= b, fmt ## ", " ## fmt, a, b)`
+* `TEST_BITS_SET(a, bits)` to `zassert_true(a & (int)bits == (int)bits, "%u,
+ %u", a & (int)bits, (int)bits)`
+* `TEST_BITS_CLEARED(a, bits)` to `zassert_true(a & (int)bits == 0, "%u, 0", a
+ & (int)bits)`
+* `TEST_ASSERT_ARRAY_EQ(s, d, n)` to `zassert_mem_equal(s, d, b, NULL)`
+* `TEST_CHECK(n)` to `zassert_true(n, NULL)`
+* `TEST_NEAR(a, b, epsilon, fmt)` to `zassert_within(a, b, epsilon, fmt, a)`
+ * Currently, every usage of `TEST_NEAR` involves floating point values
+* `TEST_ASSERT_ABS_LESS(n, t)` to `zassert_true(abs(n) < t, "%d, %d", n, t)`
+ * Currently, every usage of `TEST_ASSERT_ANS_LESS` involves signed
+ integers.
+
+There isn't a good replacement for `TEST_ASSERT_MEMSET(d, c, n)`, but it is only
+used in two tests, `printf.c` and `utils.c`. If you need this test, you'll need
+to code up a loop over the `n` bytes starting at `d`, and `zassert_equal` that
+each byte is equal to `c`.
+
+Also note that some tests use constructs like `TEST_ASSERT(var == const)`, which
+would have been better write as `TEST_EQ(var, const)`. These should be rewritten
+to use `zassert_equal`.
+
+Refer to
+[test: Allow EC unit test to use Ztest API](https://crrev.com/c/2492527) for the
+changes to the base32.c source code.
+
+### Tasklist
+
+For any test that has a corresponding `${TESTNAME}.tasklist`, add the file
+`shimmed_test_tasks.h` in the zephyr test directory, and in that file,
+`#include` the tasklist file. See [accel_cal](https://crrev.com/c/2645198) for
+an example.
+
+Add `CONFIG_HAS_TEST_TASKS=y` to the `prj.conf` file, as well as the appropriate
+`CONFIG_PLATFORM_EC` defines to include or exclude code that the unit under test
+uses.
+
+## Build and run
+
+Use `zmake` to build and run the test:
+
+```
+(cr) $ zmake -l DEBUG configure --test -B build/ztest/base32 zephyr/test/base32
+...
+UART_0 connected to pseudotty: /dev/pts/1
+*** Booting Zephyr OS build zephyr-v2.4.0-1-g63b2330a85cd ***
+Running test suite test_base32_lib
+===================================================================
+START - test_crc5
+ PASS - test_crc5
+===================================================================
+START - test_encode
+ PASS - test_encode
+===================================================================
+START - test_decode
+ PASS - test_decode
+===================================================================
+Test suite test_base32_lib succeeded
+===================================================================
+PROJECT EXECUTION SUCCESSFUL
+(cr) $
+```