The remarkable 2 has two USB port, one USB-C port used for charging and connecting to a PC and a second one exposed on the pogo pins. The chip used for charging the device (max77818) only supports one VBUS with back power. This bus is connected to the pogo pins, so only this port can be used for USB OTG.

Pogo Pins OTG

The pogo pinout is:

  (left to right)  
  
  GND, ID, D+, D-, VBUS

With the VBUS closest to the USB-C port. There is a custom linux drivers that controls the USB port dr mode and VBUS power (https://github.com/reMarkable/linux/tree/zero-sugar/drivers/misc/rm-otgcontrol). The driver monitors the status of the ID pin. If it gets grounded it tries to authenticate the device before changing the port to OTG mode. This authentication is intended to work over a one-wire protocol over the ID port, but is currently unimplemented. As a result the device detection is currently disabled by default (https://github.com/reMarkable/linux/commit/e27d817e3c968624f7ae454f9b643157a2d39dab).

Luckily there is an unauthenticated mode that can be enabled by writing to sysfs:

  echo 2 > /sys/otgcontrol/control/otg1_controllermode

Now whenever the ID pin is connected to ground, the VBUS supply will be set to OTG mode and the USB mode will change to host. This allows connecting any OTG device by connecting the pogo pins to a Micro-USB connector and using an OTG cable (or creating a custom pogo cable that connects ID to ground).

It's also possible to manually control the VBUS and dr mode by using sysfs, for example to put it into OTG mode:

echo "OTG Supply" > /sys/otgcontrol/control/otg1_chargermode
echo 1 > /sys/otgcontrol/control/otg1_dr_mode

UART from Pogo Pins

It is also possible to disable OTG from the pogo pins and instead use the ID pin as a UART TX. This allows the software to print logs via UART to the ID pin. This is especially useful for debugging or developing U-boot or kernel issue.

Currently this has been tested with the Linux kernel by printing the entire boot log via `uart6` which is broken out to the pogo pin ID pin (see above). Although it should also work for u-boot.

Enable UART

In order to enable UART first make this change to the device tree

  diff --git a/arch/arm/boot/dts/zero-sugar.dts b/arch/arm/boot/dts/zero-sugar.dts
  index 8aa62bc2c468..aa7327d47e18 100644
  --- a/arch/arm/boot/dts/zero-sugar.dts
  +++ b/arch/arm/boot/dts/zero-sugar.dts
  @@ -50,7 +50,7 @@
          compatible = "fsl,imx7d-sdb", "fsl,imx7d";
   
          chosen {
  -               stdout-path = &uart1;
  +               stdout-path = &uart6;
          };
   
          memory {
  @@ -617,7 +617,8 @@
   };
   
   &uart6 {
  -       /* Pinctrl is defined under 'otgcontrol' driver, which will switch the pinmuxing as required */
  +       pinctrl-names = "default";
  +       pinctrl-0 = <&pinctrl_uart6>;
          assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
          assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
          status = "okay";
  @@ -791,6 +792,13 @@
                  >;
          };
   
  +       pinctrl_uart6: uart6grp {
  +               fsl,pins = <
  +                       MX7D_PAD_EPDC_DATA09__UART6_DCE_TX              0x79
  +                       MX7D_PAD_EPDC_DATA08__UART6_DCE_RX              0x79
  +               >;
  +       };
  +
          pinctrl_usdhc2: usdhc2grp {
                  fsl,pins = <
                          MX7D_PAD_SD2_CMD__SD2_CMD               0x59
  @@ -912,13 +920,13 @@
          pinctrl_one_wire_uart6_tx: one_wire_uart6_tx_grp {
                  fsl,pins = <
                          MX7D_PAD_EPDC_DATA08__GPIO2_IO8         0x00000004
  -                       MX7D_PAD_EPDC_DATA09__UART6_DCE_TX      0x00000004
  +                       MX7D_PAD_EPDC_DATA09__UART6_DCE_TX      0x00000079
                  >;
          };
   
          pinctrl_one_wire_uart6_rx: one_wire_uart6_rx_grp {
                  fsl,pins = <
  -                       MX7D_PAD_EPDC_DATA08__UART6_DCE_RX      0x00000004
  +                       MX7D_PAD_EPDC_DATA08__UART6_DCE_RX      0x00000079
                          MX7D_PAD_EPDC_DATA09__GPIO2_IO9         0x00000004
                  >;
          };
  

After that the /dev/ttymxc5 device on Linux can be used to print to the pogo pin.

Set console output

In order to see the full Linux boot, you need to change the command line arguments passed to Linux. This can be done with the following two commands.

  fw_setenv console ttymxc5

to enable the output on the UART

Disable quiet boot

Secondly you need to tell the kernel not to be quiet.

  fw_printenv mmcargs

Then remove the word quiet from the args and re-set them, remember to escape the dollar signs. The command will look something like this

  fw_setenv mmcargs "setenv bootargs console=\${console},\${baudrate} root=/dev/mmcblk2p\${active_partition} rootwait rootfstype=ext4 rw panic=20 systemd.crash_reboot"

You should double check to make sure the args look like they originally did (without quiet) using fw_printenv mmcargs

USB-C in OTG mode

There is a kernel module which controls the OTG mode of the USB-C port, provided by remarkable. At present it does not correctly detect and configure when it should be an OTG host.

It's also possible to change the dr mode of the USB-C port to OTG by executing:

echo host > /sys/kernel/debug/ci_hdrc.0/role

However, the VBUS will not be powered.

A USB-OTG forking cable does work with external power. This has been tested.

A powered USB hub does not work if the control chip still uses host VBUS, which is required by the USB standard.