<p>steve-m has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmocom-bb/+/15152">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">fw: Add support for Huawei GTM900-B modules<br><br>Both MG01GSMT and MG01GSMT hardware variants are<br>supported and automatically detected based on the<br>flash manufacturer.<br><br>Change-Id: I3a770ea93fc72c4e9b63078e253602f204b5be23<br>---<br>M src/target/firmware/Makefile<br>A src/target/firmware/board/gtm900b/init.c<br>A src/target/firmware/board/gtm900b/keymap.h<br>A src/target/firmware/board/gtm900b/rf_power.c<br>A src/target/firmware/board/gtm900b/rffe_gtm900b.c<br>5 files changed, 464 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/52/15152/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile</span><br><span>index 2f44a20..f7235ac 100644</span><br><span>--- a/src/target/firmware/Makefile</span><br><span>+++ b/src/target/firmware/Makefile</span><br><span>@@ -24,7 +24,7 @@</span><br><span> #</span><br><span> </span><br><span> # List of all supported boards (meant to be overridden on command line)</span><br><span style="color: hsl(0, 100%, 40%);">-BOARDS?=compal_e88 compal_e86 compal_e99 se_j100 gta0x fcdev3b pirelli_dpl10</span><br><span style="color: hsl(120, 100%, 40%);">+BOARDS?=compal_e88 compal_e86 compal_e99 se_j100 gta0x gtm900b fcdev3b pirelli_dpl10</span><br><span> </span><br><span> # Framebuffer support, board specific drivers</span><br><span> FB_OBJS=fb/framebuffer.o fb/font.o fb/helvR08.o fb/helvB14.o fb/c64.o \</span><br><span>@@ -46,6 +46,12 @@</span><br><span>     battery/dummy.o $(FB_dummy_OBJS)</span><br><span> BOARD_gta0x_ENVIRONMENTS=highram</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+# Huawei GTM900-B</span><br><span style="color: hsl(120, 100%, 40%);">+BOARD_gtm900b_OBJS=$(calypso_COMMON_OBJS) board/gtm900b/init.o \</span><br><span style="color: hsl(120, 100%, 40%);">+ board/gtm900b/rffe_gtm900b.o board/gtm900b/rf_power.o \</span><br><span style="color: hsl(120, 100%, 40%);">+       battery/dummy.o $(FB_dummy_OBJS)</span><br><span style="color: hsl(120, 100%, 40%);">+BOARD_gtm900b_ENVIRONMENTS=highram</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> # FreeCalypso FCDEV3B</span><br><span> BOARD_fcdev3b_OBJS=$(calypso_COMMON_OBJS) board/fcdev3b/init.o \</span><br><span>  board/gta0x/rffe_gta0x_triband.o board/gta0x/rf_power.o \</span><br><span>diff --git a/src/target/firmware/board/gtm900b/init.c b/src/target/firmware/board/gtm900b/init.c</span><br><span>new file mode 100644</span><br><span>index 0000000..38ede10</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/board/gtm900b/init.c</span><br><span>@@ -0,0 +1,140 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* Initialization for the Huawei GTM900-B modem */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2010 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2010-19 by Steve Markgraf <steve@steve-m.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ctors.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <memory.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <board.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <keypad.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/irq.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/clock.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/dma.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/rtc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <uart.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/backlight.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <comm/sercomm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <comm/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <abb/twl3025.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <rf/trf6151.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "keymap.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define ARMIO_LATCH_OUT 0xfffe4802</span><br><span style="color: hsl(120, 100%, 40%);">+#define IO_CNTL_REG        0xfffe4804</span><br><span style="color: hsl(120, 100%, 40%);">+#define ASIC_CONF_REG       0xfffef008</span><br><span style="color: hsl(120, 100%, 40%);">+#define IO_CONF_REG 0xfffef00a</span><br><span style="color: hsl(120, 100%, 40%);">+#define LPG_LCR_REG 0xfffe7800</span><br><span style="color: hsl(120, 100%, 40%);">+#define LPG_PM_REG  0xfffe7801</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void board_io_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t reg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       reg = readw(ASIC_CONF_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Set LPG pin mux for power LED */</span><br><span style="color: hsl(120, 100%, 40%);">+   reg |= (1 << 6);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* TWL3025: Set SPI+RIF RX clock to rising edge */</span><br><span style="color: hsl(120, 100%, 40%);">+    reg |= (1 << 13) | (1 << 14);</span><br><span style="color: hsl(120, 100%, 40%);">+     writew(reg, ASIC_CONF_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * Most Calypso peripheral interface signals are unconnected</span><br><span style="color: hsl(120, 100%, 40%);">+   * on this modem.  We configure them to be GPIOs in IO_CONF_REG,</span><br><span style="color: hsl(120, 100%, 40%);">+       * then configure them to be outputs in IO_CNTL_REG, then set</span><br><span style="color: hsl(120, 100%, 40%);">+  * the outputs to 0 in ARMIO_LATCH_OUT.</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+   writew(0x03F5, IO_CONF_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+  writew(0xC000, IO_CNTL_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+  writew(0x0000, ARMIO_LATCH_OUT);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Set LPG output permanently on (power LED) */</span><br><span style="color: hsl(120, 100%, 40%);">+       writew(1, LPG_PM_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+        writew((1 << 7), LPG_LCR_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void board_init(int with_irq)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Configure the memory interface */</span><br><span style="color: hsl(120, 100%, 40%);">+  calypso_mem_cfg(CALYPSO_nCS0, 3, CALYPSO_MEM_16bit, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       calypso_mem_cfg(CALYPSO_nCS1, 3, CALYPSO_MEM_16bit, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       calypso_mem_cfg(CALYPSO_nCS2, 5, CALYPSO_MEM_16bit, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       calypso_mem_cfg(CALYPSO_nCS3, 5, CALYPSO_MEM_16bit, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       calypso_mem_cfg(CALYPSO_CS4, 0, CALYPSO_MEM_8bit, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ calypso_mem_cfg(CALYPSO_nCS6, 0, CALYPSO_MEM_32bit, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       calypso_mem_cfg(CALYPSO_nCS7, 0, CALYPSO_MEM_32bit, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Set VTCXO_DIV2 = 1, configure PLL for 104 MHz and give ARM half of that */</span><br><span style="color: hsl(120, 100%, 40%);">+ calypso_clock_set(2, CALYPSO_PLL13_104_MHZ, ARM_MCLK_DIV_2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Configure the RHEA bridge with some sane default values */</span><br><span style="color: hsl(120, 100%, 40%);">+ calypso_rhea_cfg(0, 0, 0xff, 0, 1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Initialize board-specific GPIO */</span><br><span style="color: hsl(120, 100%, 40%);">+  board_io_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Enable bootrom mapping to route exception vectors to RAM */</span><br><span style="color: hsl(120, 100%, 40%);">+        calypso_bootrom(with_irq);</span><br><span style="color: hsl(120, 100%, 40%);">+    calypso_exceptions_install();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Initialize interrupt controller */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (with_irq)</span><br><span style="color: hsl(120, 100%, 40%);">+         irq_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sercomm_bind_uart(UART_IRDA);</span><br><span style="color: hsl(120, 100%, 40%);">+ cons_bind_uart(UART_MODEM);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* initialize IRDA UART to be used for sercomm */</span><br><span style="color: hsl(120, 100%, 40%);">+     uart_init(UART_IRDA, with_irq);</span><br><span style="color: hsl(120, 100%, 40%);">+       uart_baudrate(UART_IRDA, UART_115200);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Initialize MODEM UART to be used for old-school console code. */</span><br><span style="color: hsl(120, 100%, 40%);">+   uart_init(UART_MODEM, with_irq);</span><br><span style="color: hsl(120, 100%, 40%);">+      uart_baudrate(UART_MODEM, UART_115200);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Initialize hardware timers */</span><br><span style="color: hsl(120, 100%, 40%);">+      hwtimer_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Initialize DMA controller */</span><br><span style="color: hsl(120, 100%, 40%);">+       dma_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize real time clock */</span><br><span style="color: hsl(120, 100%, 40%);">+      rtc_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize system timers (uses hwtimer 2) */</span><br><span style="color: hsl(120, 100%, 40%);">+       timer_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Initialize keypad driver */</span><br><span style="color: hsl(120, 100%, 40%);">+        keypad_init(keymap, with_irq);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Initialize ABB driver (uses SPI) */</span><br><span style="color: hsl(120, 100%, 40%);">+        twl3025_init();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/target/firmware/board/gtm900b/keymap.h b/src/target/firmware/board/gtm900b/keymap.h</span><br><span>new file mode 100644</span><br><span>index 0000000..07a19e0</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/board/gtm900b/keymap.h</span><br><span>@@ -0,0 +1,29 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* keymap for the Huawei GTM900-B */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const uint8_t keymap[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+    [KEY_0]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_1]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_2]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_3]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_4]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_5]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_6]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_7]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_8]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_9]         = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_STAR]      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_HASH]      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_MENU]      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_LEFT_SB]   = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_RIGHT_SB]  = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_UP]        = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_DOWN]      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_LEFT]      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_RIGHT]     = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_OK]        = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+/* power button is not connected to keypad scan matrix but to TWL3025 */</span><br><span style="color: hsl(120, 100%, 40%);">+        [KEY_POWER]     = 31,</span><br><span style="color: hsl(120, 100%, 40%);">+ [KEY_MINUS]     = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_PLUS]      = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+  [KEY_CAMERA]    = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span>diff --git a/src/target/firmware/board/gtm900b/rf_power.c b/src/target/firmware/board/gtm900b/rf_power.c</span><br><span>new file mode 100644</span><br><span>index 0000000..cd47ddf</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/board/gtm900b/rf_power.c</span><br><span>@@ -0,0 +1,63 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* Tx RF power calibration for the Huawei GTM900-B */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2010 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* GSM900 ARFCN 33, Measurements by Steve Markgraf / May 2010 */</span><br><span style="color: hsl(120, 100%, 40%);">+/* FIXME those are from the Compal phones, do measurements with the GTM900-B */</span><br><span style="color: hsl(120, 100%, 40%);">+const int16_t dbm2apc_gsm900[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        [0]     = 151,</span><br><span style="color: hsl(120, 100%, 40%);">+        [1]     = 152,</span><br><span style="color: hsl(120, 100%, 40%);">+        [2]     = 153,</span><br><span style="color: hsl(120, 100%, 40%);">+        [3]     = 155,</span><br><span style="color: hsl(120, 100%, 40%);">+        [4]     = 156,</span><br><span style="color: hsl(120, 100%, 40%);">+        [5]     = 158,</span><br><span style="color: hsl(120, 100%, 40%);">+        [6]     = 160,</span><br><span style="color: hsl(120, 100%, 40%);">+        [7]     = 162,</span><br><span style="color: hsl(120, 100%, 40%);">+        [8]     = 164,</span><br><span style="color: hsl(120, 100%, 40%);">+        [9]     = 167,</span><br><span style="color: hsl(120, 100%, 40%);">+        [10]    = 170,</span><br><span style="color: hsl(120, 100%, 40%);">+        [11]    = 173,</span><br><span style="color: hsl(120, 100%, 40%);">+        [12]    = 177,</span><br><span style="color: hsl(120, 100%, 40%);">+        [13]    = 182,</span><br><span style="color: hsl(120, 100%, 40%);">+        [14]    = 187,</span><br><span style="color: hsl(120, 100%, 40%);">+        [15]    = 192,</span><br><span style="color: hsl(120, 100%, 40%);">+        [16]    = 199,</span><br><span style="color: hsl(120, 100%, 40%);">+        [17]    = 206,</span><br><span style="color: hsl(120, 100%, 40%);">+        [18]    = 214,</span><br><span style="color: hsl(120, 100%, 40%);">+        [19]    = 223,</span><br><span style="color: hsl(120, 100%, 40%);">+        [20]    = 233,</span><br><span style="color: hsl(120, 100%, 40%);">+        [21]    = 244,</span><br><span style="color: hsl(120, 100%, 40%);">+        [22]    = 260,</span><br><span style="color: hsl(120, 100%, 40%);">+        [23]    = 271,</span><br><span style="color: hsl(120, 100%, 40%);">+        [24]    = 288,</span><br><span style="color: hsl(120, 100%, 40%);">+        [25]    = 307,</span><br><span style="color: hsl(120, 100%, 40%);">+        [26]    = 327,</span><br><span style="color: hsl(120, 100%, 40%);">+        [27]    = 350,</span><br><span style="color: hsl(120, 100%, 40%);">+        [28]    = 376,</span><br><span style="color: hsl(120, 100%, 40%);">+        [29]    = 407,</span><br><span style="color: hsl(120, 100%, 40%);">+        [30]    = 456,</span><br><span style="color: hsl(120, 100%, 40%);">+        [31]    = 575,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const int dbm2apc_gsm900_max = ARRAY_SIZE(dbm2apc_gsm900) - 1;</span><br><span>diff --git a/src/target/firmware/board/gtm900b/rffe_gtm900b.c b/src/target/firmware/board/gtm900b/rffe_gtm900b.c</span><br><span>new file mode 100644</span><br><span>index 0000000..633c637</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/board/gtm900b/rffe_gtm900b.c</span><br><span>@@ -0,0 +1,225 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* RF frontend driver for Huawei GTM900-B modems, supporting both</span><br><span style="color: hsl(120, 100%, 40%);">+ * MG01GSMT and MG01GSMT hardware variants */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2019 by Steve Markgraf <steve@steve-m.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <memory.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <rffe.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <calypso/tsp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <rf/trf6151.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* This is a value that has been measured for the GTM900-B: 74dBm,</span><br><span style="color: hsl(120, 100%, 40%);">+   it is the difference between the input level at the antenna and what</span><br><span style="color: hsl(120, 100%, 40%);">+   the DSP reports, subtracted by the total gain of the TRF6151 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define SYSTEM_INHERENT_GAIN    74</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* describe how the RF frontend is wired on the Huawei GTM900-B */</span><br><span style="color: hsl(120, 100%, 40%);">+#define               IOTA_STROBE     TSPEN(0)        /* Strobe for the Iota TSP */</span><br><span style="color: hsl(120, 100%, 40%);">+#define          RITA_STROBE     TSPEN(2)        /* Strobe for the Rita TSP */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define                RITA_RESET      TSPACT(0)       /* Reset of the Rita TRF6151 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define                PA_BAND_SELECT  TSPACT(3)       /* Low: 850/900, High: 1800/1900 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define            PA_TX_ENABLE    TSPACT(9)       /* Enable the Power Amplifier */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* MGC2GSMT Ver. BRF specific antenna switch signals, low active */</span><br><span style="color: hsl(120, 100%, 40%);">+#define                ASM_VC1         TSPACT(1)       /* low on GSM900 TX */</span><br><span style="color: hsl(120, 100%, 40%);">+#define         ASM_VC2         TSPACT(2)       /* low on DCS1800 TX */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* MG01GSMT Ver. C specific antenna switch signals, low active */</span><br><span style="color: hsl(120, 100%, 40%);">+#define           CXG_CTLA        TSPACT(4)       /* CXG1192UR CTLA input */</span><br><span style="color: hsl(120, 100%, 40%);">+#define             CXG_CTLB        TSPACT(1)       /* CXG1192UR CTLB input */</span><br><span style="color: hsl(120, 100%, 40%);">+#define             CXG_CTLC        TSPACT(2)       /* CXG1192UR CTLC input */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * The Sony CXG1192UR switch is wired as follows on the MG01GSMT Ver. C:</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Rx1: GSM850 RX filter (Epcos B5013)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Rx2: GSM900 RX filter (Epcos B7710)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Rx3: DCS1800 RX filter (Epcos 7714)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Rx4: PCS1900 RX filter (not populated)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Tx1: low band PA output</span><br><span style="color: hsl(120, 100%, 40%);">+ * Tx2: high band PA output</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef enum rffe_var {</span><br><span style="color: hsl(120, 100%, 40%);">+    RFFE_MGC2GSMT,</span><br><span style="color: hsl(120, 100%, 40%);">+        RFFE_MG01GSMT</span><br><span style="color: hsl(120, 100%, 40%);">+} rffe_var_t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static rffe_var_t rffe_variant = RFFE_MGC2GSMT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void rffe_mode_mgc2gsmt(enum gsm_band band, int tx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t tspact = tsp_act_state();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* First we mask off all bits from the state cache */</span><br><span style="color: hsl(120, 100%, 40%);">+ tspact &= ~(PA_BAND_SELECT | PA_TX_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+       tspact |=  (ASM_VC1 | ASM_VC2); /* low-active */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef CONFIG_TX_ENABLE</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Then we selectively set the bits on, if required */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (tx) {</span><br><span style="color: hsl(120, 100%, 40%);">+             tspact |= PA_TX_ENABLE;</span><br><span style="color: hsl(120, 100%, 40%);">+               tspact &= ~CXG_CTLA;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (band == GSM_BAND_1800 || band == GSM_BAND_1900) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 tspact |= PA_BAND_SELECT;</span><br><span style="color: hsl(120, 100%, 40%);">+                     tspact &= ~ASM_VC2;</span><br><span style="color: hsl(120, 100%, 40%);">+               } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      tspact &= ~ASM_VC1;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* TRANSMIT_SUPPORT */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    tsp_act_update(tspact);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void rffe_mode_mg01gsmt(enum gsm_band band, int tx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t tspact = tsp_act_state();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* First we mask off all bits from the state cache */</span><br><span style="color: hsl(120, 100%, 40%);">+ tspact &= ~(PA_BAND_SELECT | PA_TX_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+       tspact |=  (CXG_CTLA | CXG_CTLB | CXG_CTLC);    /* low-active */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (band) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BAND_850:</span><br><span style="color: hsl(120, 100%, 40%);">+            tspact &= ~CXG_CTLB;                  /* select Ant1 - Rx1 */</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_BAND_900:</span><br><span style="color: hsl(120, 100%, 40%);">+            tspact &= ~CXG_CTLC;                  /* select Ant1 - Rx2 */</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_BAND_1800:                       /* select Ant2 - Rx3 */</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_BAND_1900:</span><br><span style="color: hsl(120, 100%, 40%);">+           tspact &= ~(CXG_CTLB | CXG_CTLC); /* select Ant2 - Rx4 */</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef CONFIG_TX_ENABLE</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Then we selectively set the bits on, if required */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (tx) {</span><br><span style="color: hsl(120, 100%, 40%);">+             tspact |= PA_TX_ENABLE;</span><br><span style="color: hsl(120, 100%, 40%);">+               tspact &= ~CXG_CTLA;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (band == GSM_BAND_1800 || band == GSM_BAND_1900) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 tspact |= PA_BAND_SELECT;</span><br><span style="color: hsl(120, 100%, 40%);">+                     tspact &= ~CXG_CTLB;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* TRANSMIT_SUPPORT */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    tsp_act_update(tspact);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* switch RF Frontend Mode */</span><br><span style="color: hsl(120, 100%, 40%);">+void rffe_mode(enum gsm_band band, int tx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rffe_variant == RFFE_MGC2GSMT)</span><br><span style="color: hsl(120, 100%, 40%);">+            rffe_mode_mgc2gsmt(band, tx);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+          rffe_mode_mg01gsmt(band, tx);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t rffe_get_rx_ports(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return (1 << PORT_LO) | (1 << PORT_DCS1800) | (1 << PORT_PCS1900);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t rffe_get_tx_ports(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return (1 << PORT_LO) | (1 << PORT_HI);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Returns need for IQ swap */</span><br><span style="color: hsl(120, 100%, 40%);">+int rffe_iq_swapped(uint16_t band_arfcn, int tx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return trf6151_iq_swapped(band_arfcn, tx);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define ARM_CONF_REG   0xfffef006</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void rffe_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t reg;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t manufacturer_id = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       reg = readw(ARM_CONF_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+    reg &= ~ (1 << 7);    /* TSPACT4 I/O function, not nRDYMEM */</span><br><span style="color: hsl(120, 100%, 40%);">+       writew(reg, ARM_CONF_REG);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Configure the TSPEN which is connected to the TWL3025 */</span><br><span style="color: hsl(120, 100%, 40%);">+   tsp_setup(IOTA_STROBE, 1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    trf6151_init(RITA_STROBE, RITA_RESET);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Detect the used RFFE variant based on the used flash chip.</span><br><span style="color: hsl(120, 100%, 40%);">+  * The MGC2GSMT uses a Samsung flash, whereas the MG01GSMT uses</span><br><span style="color: hsl(120, 100%, 40%);">+        * a Spansion flash. We use an address above the Calpso bootrom</span><br><span style="color: hsl(120, 100%, 40%);">+        * so we do not need to unmap it to access the flash. */</span><br><span style="color: hsl(120, 100%, 40%);">+      flash_get_id((void *)0x40000, &manufacturer_id, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (manufacturer_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case CFI_MANUF_SPANSION:</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("Detected MG01GSMT module\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             rffe_variant = RFFE_MG01GSMT;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CFI_MANUF_SAMSUNG:</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("Detected MGC2GSMT module\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             rffe_variant = RFFE_MGC2GSMT;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("Unknown module detected, flash ID 0x%4.4x\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                       "Please contact mailing list!\n\n", manufacturer_id);</span><br><span style="color: hsl(120, 100%, 40%);">+                rffe_variant = RFFE_MGC2GSMT;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t rffe_get_gain(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return trf6151_get_gain();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void rffe_set_gain(uint8_t dbm)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   trf6151_set_gain(dbm);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const uint8_t system_inherent_gain = SYSTEM_INHERENT_GAIN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Given the expected input level of exp_inp dBm/8 and the target of target_bb</span><br><span style="color: hsl(120, 100%, 40%);">+ * dBm8, configure the RF Frontend with the respective gain */</span><br><span style="color: hsl(120, 100%, 40%);">+void rffe_compute_gain(int16_t exp_inp, int16_t target_bb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      trf6151_compute_gain(exp_inp, target_bb);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void rffe_rx_win_ctrl(int16_t exp_inp, int16_t target_bb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  /* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmocom-bb/+/15152">change 15152</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmocom-bb/+/15152"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I3a770ea93fc72c4e9b63078e253602f204b5be23 </div>
<div style="display:none"> Gerrit-Change-Number: 15152 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: steve-m <steve@steve-m.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>