summaryrefslogtreecommitdiffstats
path: root/src/target/firmware
diff options
context:
space:
mode:
authorMychaela N. Falconia <falcon@freecalypso.org>2023-09-02 03:03:11 +0000
committerlaforge <laforge@osmocom.org>2023-09-04 20:19:12 +0000
commit59e649dbf1e1e71d38ab6fc40d2feb6fe6195f54 (patch)
tree8ec1628b84f5b6be4528ff0df10bb1d2e1cb7f28 /src/target/firmware
parentc20f3f3f19dca217392c1e613aa1dbe8b6d37865 (diff)
firmware: board: add support for TR-800 target
iWOW TR-800 is a packaged GSM modem module based on Calypso+Iota+Rita chipset; it is fully quadband, and reverse engineering of its PCB confirms that this module is nothing but a mass-produced version of the core of TI's legendary Leonardo+ reference platform. The same module is also known as FreeCalypso Tango - a rebranded version of the same hardware module with different firmware and a different Responsible Party for official support. FreeCalypso HQ is contributing OsmocomBB support for this Calypso modem module for two reasons: 1) Harm reduction - sooner or later someone in Osmocom universe is going to run OBB firmware on TR-800 once they lay their hands on this hardware, and the resulting operation will be less harmful / closer to correct if we provide the basic board support patch. 2) There exists a large surplus of FreeCalypso Caramel2 development boards that are based around FC Tango modules. Having this hw supported by both firmwares will hopefully increase the chances that these boards will find loving homes, as opposed to continuing to gather dust in a cardboard box. Legal and ethical disclaimer: OsmocomBB firmware running on ANY Calypso+Iota+Rita target is *known*, through confirmed observations with a measuring instrument (R&S CMU200), to put out radio transmissions that are *severely out of spec*, and this defect does NOT go away with the present patch which merely adds support for a different C+I+R board target. The present patch has been produced as a harm reduction measure, to reduce (but not to zero) the harm that will be caused by parties who run OsmocomBB firmware on C+I+R hardware despite having been advised not to. As the party seeking to reduce rather than cause that harm, Mother Mychaela and her related business entities explicitly disclaim all liability for damage that will be caused by parties who continue running OsmocomBB firmware despite having been repeatedly advised to switch to manufacturer-approved published-source firmware instead. Change-Id: I84d564f052f12a25ea3bfb9c78860e9dc6262be8
Diffstat (limited to 'src/target/firmware')
-rw-r--r--src/target/firmware/Makefile10
-rw-r--r--src/target/firmware/board/tr800/afcparams.c52
-rw-r--r--src/target/firmware/board/tr800/init.c257
-rw-r--r--src/target/firmware/board/tr800/keymap.h87
-rw-r--r--src/target/firmware/board/tr800/rffe_leo_quadband.c194
5 files changed, 599 insertions, 1 deletions
diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile
index 18450ac1..2a376bc3 100644
--- a/src/target/firmware/Makefile
+++ b/src/target/firmware/Makefile
@@ -24,7 +24,8 @@ ENV_e88flash_OBJS=board/compal/start.rom.o board/compal/header.o board/compal/ex
#
# List of all supported boards (meant to be overridden on command line)
-BOARDS?=compal_e88 compal_e86 compal_e99 se_j100 se_k2x0 gta0x gtm900b fcdev3b pirelli_dpl10
+BOARDS?=compal_e88 compal_e86 compal_e99 se_j100 se_k2x0 gta0x gtm900b fcdev3b \
+ pirelli_dpl10 tr800
# Framebuffer support, board specific drivers
FB_OBJS=fb/framebuffer.o fb/font.o fb/helvR08.o fb/helvB14.o fb/c64.o \
@@ -63,6 +64,13 @@ BOARD_fcdev3b_OBJS=$(calypso_COMMON_OBJS) board/fcdev3b/init.o \
board/common/readcal_tiffs.o battery/dummy.o $(FB_dummy_OBJS)
BOARD_fcdev3b_ENVIRONMENTS=highram
+# iWOW TR-800 aka FreeCalypso Tango
+BOARD_tr800_OBJS=$(calypso_COMMON_OBJS) board/tr800/init.o \
+ board/tr800/rffe_leo_quadband.o board/gta0x/rf_tables.o \
+ board/tr800/afcparams.o \
+ board/common/readcal_tiffs.o battery/dummy.o $(FB_dummy_OBJS)
+BOARD_tr800_ENVIRONMENTS=highram
+
# Pirelli DP-L10
BOARD_pirelli_dpl10_OBJS=$(calypso_COMMON_OBJS) board/pirelli_dpl10/init.o \
board/pirelli_dpl10/rffe_dpl10_triband.o \
diff --git a/src/target/firmware/board/tr800/afcparams.c b/src/target/firmware/board/tr800/afcparams.c
new file mode 100644
index 00000000..ccbb3608
--- /dev/null
+++ b/src/target/firmware/board/tr800/afcparams.c
@@ -0,0 +1,52 @@
+/*
+ * This code was written by Mychaela Falconia <falcon@freecalypso.org>
+ * who refuses to claim copyright on it and has released it as public domain
+ * instead. NO rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <rf/vcxocal.h>
+
+/*
+ * Here is a representative set of AFC Psi parameters that has been
+ * calibrated by iWOW's factory on a TR-800 module, as recorded
+ * in the /gsm/rf/afcparams file:
+ *
+ * Psi_sta_inv: 4387
+ * Psi_st: 12
+ * Psi_st_32: 783154
+ * Psi_st_inv: 5484
+ *
+ * The following AFC slope number is the closest OsmocomBB-style afc_slope
+ * integer corresponding to these Psi numbers; the true value is somewhere
+ * between 358 and 359.
+ *
+ * Please note that all AFC parameters (both Psi and linear) have been
+ * calibrated per unit by iWOW's factory, and they do differ from unit
+ * to unit. Both iWOW and FreeCalypso firmwares make direct use of
+ * per-unit calibrated numbers, but OsmocomBB architecture cannot make
+ * use of them - hence AFC performance with OBB may be significantly
+ * poorer than with either iWOW or FC firmware. The present code has
+ * been contributed by Mother Mychaela solely as a harm reduction measure,
+ * and does NOT constitute any kind of approved production solution -
+ * you've been warned!
+ */
+int16_t afc_slope = 358;
+
+/*
+ * The compiled-in AFC initial DAC value below is the same as was used by
+ * the old OsmocomBB code written for Mot C1xx phones, but it will normally
+ * be overridden by the per-unit factory calibration value read from the
+ * /gsm/rf/afcdac file in FFS.
+ */
+int16_t afc_initial_dac_value = -700;
diff --git a/src/target/firmware/board/tr800/init.c b/src/target/firmware/board/tr800/init.c
new file mode 100644
index 00000000..a8f3253f
--- /dev/null
+++ b/src/target/firmware/board/tr800/init.c
@@ -0,0 +1,257 @@
+/* Initialization for the iWOW TR-800 modem */
+
+/*
+ * This code was written by Mychaela Falconia <falcon@freecalypso.org>
+ * who refuses to claim copyright on it and has released it as public domain
+ * instead. NO rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <debug.h>
+#include <ctors.h>
+#include <memory.h>
+#include <board.h>
+#include <keypad.h>
+#include <console.h>
+#include <flash/cfi_flash.h>
+#include <tiffs.h>
+
+#include <calypso/irq.h>
+#include <calypso/clock.h>
+#include <calypso/dma.h>
+#include <calypso/rtc.h>
+#include <calypso/timer.h>
+#include <uart.h>
+
+#include <comm/sercomm.h>
+#include <comm/timer.h>
+
+#include <abb/twl3025.h>
+#include <rf/trf6151.h>
+#include "keymap.h"
+
+#define ARMIO_LATCH_OUT 0xfffe4802
+#define IO_CNTL_REG 0xfffe4804
+#define ARM_CONF_REG 0xfffef006
+#define ASIC_CONF_REG 0xfffef008
+#define IO_CONF_REG 0xfffef00a
+
+static void board_io_init(void)
+{
+ uint16_t reg;
+
+ reg = readw(ASIC_CONF_REG);
+ /* DSR_MODEM/LPG pin is unconnected - make it LPG dummy output */
+ reg |= (1 << 6);
+ /* TWL3025: Set SPI+RIF RX clock to rising edge */
+ reg |= (1 << 13) | (1 << 14);
+ writew(reg, ASIC_CONF_REG);
+
+ /*
+ * Calypso signals GPIO0, TSPDI/GPIO4, BCLKX/GPIO6, MCUEN1/GPIO8 and
+ * MCUEN2/GPIO13 are unused and unconnected inside the TR-800 module.
+ * Configure them as dummy outputs in order to prevent floating inputs.
+ */
+ writew(0x0215, IO_CONF_REG);
+ writew(0xDC0E, IO_CNTL_REG);
+ writew(0x0000, ARMIO_LATCH_OUT);
+
+ /* configure ADD(22), needed for second half of flash */
+ reg = readw(ARM_CONF_REG);
+ reg |= (1 << 3);
+ writew(reg, ARM_CONF_REG);
+}
+
+/*
+ * A total of 8 Calypso GPIO/multifunction pins (3 pure GPIO, 5 multifunction)
+ * are brought out on the TR-800 module, with module users (application board
+ * designers) explicitly allowed to wire them in whichever way is needed for
+ * the custom application at hand. 6 of these pins power up as inputs.
+ * Should the firmware leave them as inputs, or switch them to dummy outputs
+ * to prevent floating inputs? The answer in FreeCalypso (for TR-800 modules
+ * rebranded as FC Tango) is a special file written into FFS: /etc/tango-pinmux.
+ * This board wiring config file tells the firmware what it should do with each
+ * of the 8 GPIO/multifunction pins in question; the format is defined here:
+ *
+ * https://www.freecalypso.org/hg/freecalypso-docs/file/tip/Tango-pinmux
+ *
+ * The following function reads /etc/tango-pinmux from FFS and applies the pin
+ * multiplexing configuration encoded therein. If this file is missing, all
+ * pins in question are left in their default power-up state.
+ */
+static void board_pinmux_init(void)
+{
+ uint8_t pinmux[4];
+ int rc;
+ uint16_t conf_reg, cntl_reg, out_reg;
+
+ rc = tiffs_read_file_fixedlen("/etc/tango-pinmux", pinmux, 4);
+ if (rc < 0)
+ return; /* error msg already printed */
+ if (rc == 0) {
+ puts("Warning: /etc/tango-pinmux not found, pins left in default power-up state\n");
+ return;
+ }
+ /* read-modify-write registers */
+ conf_reg = readw(IO_CONF_REG);
+ cntl_reg = readw(IO_CNTL_REG);
+ out_reg = readw(ARMIO_LATCH_OUT);
+ /* GPIO1 */
+ if (pinmux[0] & 0x80) {
+ cntl_reg &= ~(1 << 1);
+ if (pinmux[0] & 0x01)
+ out_reg |= (1 << 1);
+ else
+ out_reg &= ~(1 << 1);
+ }
+ /* GPIO2 */
+ if (pinmux[1] & 0x08) {
+ /* pinmux says it's DCD output - set it high */
+ cntl_reg &= ~(1 << 2);
+ out_reg |= (1 << 2);
+ } else if (pinmux[1] & 0x02) {
+ /* generic output */
+ cntl_reg &= ~(1 << 2);
+ if (pinmux[1] & 0x01)
+ out_reg |= (1 << 2);
+ else
+ out_reg &= ~(1 << 2);
+ }
+ /* GPIO3 */
+ if (pinmux[1] & 0x20) {
+ /* generic output */
+ cntl_reg &= ~(1 << 3);
+ if (pinmux[1] & 0x10)
+ out_reg |= (1 << 3);
+ else
+ out_reg &= ~(1 << 3);
+ }
+ /* MCSI or GPIO? */
+ if (pinmux[2] & 0x80) {
+ /* MCSI pins switch to GPIO */
+ conf_reg |= 0x1E0;
+ writew(conf_reg, IO_CONF_REG);
+ /* GPIO9 */
+ if (pinmux[3] & 0x10) {
+ cntl_reg &= ~(1 << 9);
+ if (pinmux[3] & 0x01)
+ out_reg |= (1 << 9);
+ else
+ out_reg &= ~(1 << 9);
+ } else
+ cntl_reg |= (1 << 9);
+ /* GPIO10 */
+ if (pinmux[3] & 0x20) {
+ cntl_reg &= ~(1 << 10);
+ if (pinmux[3] & 0x02)
+ out_reg |= (1 << 10);
+ else
+ out_reg &= ~(1 << 10);
+ }
+ /* GPIO11 */
+ if (pinmux[3] & 0x40) {
+ cntl_reg &= ~(1 << 11);
+ if (pinmux[3] & 0x04)
+ out_reg |= (1 << 11);
+ else
+ out_reg &= ~(1 << 11);
+ }
+ /* GPIO12 */
+ if (pinmux[3] & 0x80) {
+ cntl_reg &= ~(1 << 12);
+ if (pinmux[3] & 0x08)
+ out_reg |= (1 << 12);
+ else
+ out_reg &= ~(1 << 12);
+ }
+ }
+ writew(out_reg, ARMIO_LATCH_OUT);
+ writew(cntl_reg, IO_CNTL_REG);
+}
+
+void board_init(int with_irq)
+{
+ /*
+ * Configure the memory interface.
+ * nCS0 and nCS1 are internal flash and RAM - please refer to
+ * this technical article for an explanation of timing parameters:
+https://www.freecalypso.org/hg/freecalypso-docs/file/tip/MEMIF-wait-states
+ */
+ calypso_mem_cfg(CALYPSO_nCS0, 4, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS1, 4, CALYPSO_MEM_16bit, 1);
+ /* nCS2 and nCS3 are brought out for user-added custom hw */
+ calypso_mem_cfg(CALYPSO_nCS2, 5, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS3, 5, CALYPSO_MEM_16bit, 1);
+ /* Calypso nCS4 is not brought out on TR-800, hence a dummy */
+ calypso_mem_cfg(CALYPSO_CS4, 0, CALYPSO_MEM_8bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS6, 0, CALYPSO_MEM_32bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS7, 0, CALYPSO_MEM_32bit, 0);
+
+ /* Set VTCXO_DIV2 = 1, configure PLL for 104 MHz and give ARM half of that */
+ calypso_clock_set(2, CALYPSO_PLL13_104_MHZ, ARM_MCLK_DIV_2);
+
+ /* Configure the RHEA bridge with some sane default values */
+ calypso_rhea_cfg(0, 0, 0xff, 0, 1, 0, 0);
+
+ /* Initialize board-specific GPIO */
+ board_io_init();
+
+ /* Enable bootrom mapping to route exception vectors to RAM */
+ calypso_bootrom(with_irq);
+ calypso_exceptions_install();
+
+ /* Initialize interrupt controller */
+ if (with_irq)
+ irq_init();
+
+ /*
+ * The choice of which UART should be used for what is arbitrary -
+ * change to taste!
+ */
+ sercomm_bind_uart(UART_MODEM);
+ cons_bind_uart(UART_IRDA);
+
+ /* initialize MODEM UART to be used for sercomm */
+ uart_init(UART_MODEM, with_irq);
+ uart_baudrate(UART_MODEM, UART_115200);
+
+ /* Initialize IRDA UART to be used for old-school console code. */
+ uart_init(UART_IRDA, with_irq);
+ uart_baudrate(UART_IRDA, UART_115200);
+
+ /* Initialize hardware timers */
+ hwtimer_init();
+
+ /* Initialize DMA controller */
+ dma_init();
+
+ /* Initialize real time clock */
+ rtc_init();
+
+ /* Initialize system timers (uses hwtimer 2) */
+ timer_init();
+
+ /* Initialize keypad driver */
+ keypad_init(keymap, with_irq);
+
+ /* Initialize ABB driver (uses SPI) */
+ twl3025_init();
+
+ /* Initialize TIFFS reader (15 sectors of 64 KiB each) */
+ tiffs_init(0x700000, 0x10000, 15);
+
+ /* Initialize configurable pin multiplexing */
+ board_pinmux_init();
+}
diff --git a/src/target/firmware/board/tr800/keymap.h b/src/target/firmware/board/tr800/keymap.h
new file mode 100644
index 00000000..8e77ce2f
--- /dev/null
+++ b/src/target/firmware/board/tr800/keymap.h
@@ -0,0 +1,87 @@
+/*
+ * This code was written by Mychaela Falconia <falcon@freecalypso.org>
+ * who refuses to claim copyright on it and has released it as public domain
+ * instead. NO rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * The TR-800 module itself does not prescribe any particular keypad
+ * layout - instead all 5 KBC lines and all 5 KBR lines are simply
+ * brought out, allowing user applications to implement any desired
+ * keypad up to 5x5 buttons. When designing keypads for development
+ * boards (whether TR800-based or "raw" Calypso), Mother Mychaela's
+ * preference is to follow TI's original D-Sample key layout:
+
+ Main keypad (21 buttons):
+
+ L. Soft R. Soft
+ 5-way nav
+ Green Red
+ 1 2 3
+ 4 5 6
+ 7 8 9
+ * 0 #
+
+ Left side buttons: VOL+ / VOL-
+ Right side button: generic
+
+ Row/column matrix connections:
+
+ KBC0 KBC1 KBC2 KBC3 KBC4
+ KBR0 Green VOL- VOL+ L_Soft Nav_left
+ KBR1 1 2 3 R_Side Nav_right
+ KBR2 4 5 6 R_Soft Nav_up
+ KBR3 7 8 9 unused Nav_down
+ KBR4 * 0 # unused Nav_center
+
+ The red button is out-of-matrix PWON.
+
+ * If anyone has an original iWOW DSK board, the connection of
+ * "CALL" and "1" buttons on that board also matches the present
+ * D-Sample keymap.
+ */
+
+static const uint8_t keymap[] = {
+ [KEY_0] = 9,
+ [KEY_1] = 1,
+ [KEY_2] = 6,
+ [KEY_3] = 11,
+ [KEY_4] = 2,
+ [KEY_5] = 7,
+ [KEY_6] = 12,
+ [KEY_7] = 3,
+ [KEY_8] = 8,
+ [KEY_9] = 13,
+ [KEY_STAR] = 4,
+ [KEY_HASH] = 14,
+ [KEY_MENU] = 24,
+ [KEY_LEFT_SB] = 15,
+ [KEY_RIGHT_SB] = 17,
+ [KEY_UP] = 22,
+ [KEY_DOWN] = 23,
+ [KEY_LEFT] = 20,
+ [KEY_RIGHT] = 21,
+ [KEY_OK] = 0,
+/* power button is not connected to keypad scan matrix but to TWL3025 */
+ [KEY_POWER] = 31,
+/* D-Sample left side buttons for volume up/down control */
+ [KEY_MINUS] = 5,
+ [KEY_PLUS] = 10,
+/*
+ * D-Sample right side button can be seen as equivalent to
+ * Pirelli DP-L10 camera button, except for reversed history:
+ * D-Sample existed first and was used by the designers of the
+ * Pirelli DP-L10 phone as their starting point.
+ */
+ [KEY_CAMERA] = 16,
+};
diff --git a/src/target/firmware/board/tr800/rffe_leo_quadband.c b/src/target/firmware/board/tr800/rffe_leo_quadband.c
new file mode 100644
index 00000000..b1989a60
--- /dev/null
+++ b/src/target/firmware/board/tr800/rffe_leo_quadband.c
@@ -0,0 +1,194 @@
+/*
+ * This code was written by Mychaela Falconia <falcon@freecalypso.org>
+ * who refuses to claim copyright on it and has released it as public domain
+ * instead. NO rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This module implements RFFE control for TI's original Leonardo+
+ * quadband RFFE, depicted on page 4 of this 2011-find schematic drawing:
+ *
+ * https://www.freecalypso.org/pub/GSM/Calypso/Leonardo_plus_quadband_schem.pdf
+ *
+ * This TI-original quadband RFFE is reproduced verbatim on the TR-800
+ * packaged module by iWOW.
+ *
+ * The present C code is based on ../gta0x/rffe_gta0x_triband.c,
+ * controlling Openmoko's triband RFFE which is very closely based on
+ * Leonardo, with only a few control signal permutations.
+ *
+ * The present code addition by Mother Mychaela merely brings the TR-800 hw
+ * target to the same level of support that already existed in OBB since
+ * forever for Compal/Motorola and Openmoko GTA01/02 targets, and more
+ * recently GTM900 and FCDEV3B - it does NOT fix the problem of overly
+ * simplistic RFFE control timing and other oversimplifications which OBB
+ * exhibits in comparison to the official firmware maintained by the
+ * custodians of the Calypso+Iota+RF chipset (formerly TI, now FreeCalypso).
+ * These massive oversimplifications which OBB exhibits in comparison to
+ * officially approved production firmwares result in OBB's radio transmissions
+ * being SEVERELY out of compliance (as observed with even the simplest tests
+ * with a CMU200 RF test instrument), thus anyone who runs the present code
+ * with Tx enabled outside of a Faraday cage will very likely cause
+ * interference and disruption to public communication networks! Furthermore,
+ * if you go on with running OBB with Tx enabled after having read this
+ * warning, the resulting interference and disruption to public communication
+ * networks can be considered intentional on your part, which is likely to be
+ * seen as a more severe offense.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <debug.h>
+#include <memory.h>
+#include <rffe.h>
+#include <calypso/tsp.h>
+#include <rf/trf6151.h>
+
+/*
+ * OsmocomBB's definition of system inherent gain is similar to what is
+ * called "magic gain" (GMagic) in TI's architecture, except that TI's
+ * GMagic includes TRF6151 LNA gain whereas OBB's definition of system
+ * inherent gain does not. TI's GMagic is also reckoned in half-dB units
+ * instead of integral dB.
+ *
+ * The canonical GMagic number for Leonardo/TR-800 RFFE is 200, both in
+ * iWOW's original calibration and as confirmed with CMU200 measurements
+ * at FreeCalypso HQ. GMagic=200 in TI's universe is equivalent to
+ * OsmocomBB's "system inherent gain" of 73 dB.
+ */
+#define SYSTEM_INHERENT_GAIN 73
+
+/* describe how the RF frontend is wired on Leonardo and TR-800 */
+
+#define RITA_RESET TSPACT(0) /* Reset of the Rita TRF6151 */
+#define PA_ENABLE TSPACT(9) /* Enable the Power Amplifier */
+#define PA_BAND_SEL TSPACT(3) /* PA band select, 1=DCS/PCS */
+
+/* All FEM controls are low-active */
+#define FEM_7 TSPACT(2) /* FEM pin 7 */
+#define FEM_8 TSPACT(1) /* FEM pin 8 */
+#define FEM_9 TSPACT(4) /* FEM pin 9 */
+
+#define IOTA_STROBE TSPEN(0) /* Strobe for the Iota TSP */
+#define RITA_STROBE TSPEN(2) /* Strobe for the Rita TSP */
+
+/* switch RF Frontend Mode */
+void rffe_mode(enum gsm_band band, int tx)
+{
+ uint16_t tspact = tsp_act_state();
+
+ /* First we mask off all bits from the state cache */
+ tspact &= ~PA_ENABLE;
+ tspact &= ~PA_BAND_SEL;
+ tspact |= FEM_7 | FEM_8 | FEM_9; /* low-active */
+
+ switch (band) {
+ case GSM_BAND_850:
+ tspact &= ~FEM_9;
+ break;
+ case GSM_BAND_900:
+ case GSM_BAND_1800:
+ case GSM_BAND_1900:
+ break;
+ default:
+ /* TODO return/signal error here */
+ break;
+ }
+
+#ifdef CONFIG_TX_ENABLE
+ /* Then we selectively set the bits on, if required */
+ if (tx) {
+ switch (band) {
+ case GSM_BAND_850:
+ case GSM_BAND_900:
+ tspact |= FEM_9;
+ tspact &= ~FEM_7;
+ break;
+ case GSM_BAND_1800:
+ case GSM_BAND_1900:
+ tspact &= ~FEM_8;
+ tspact |= PA_BAND_SEL;
+ break;
+ default:
+ break;
+ }
+ tspact |= PA_ENABLE;
+ }
+#endif /* TRANSMIT_SUPPORT */
+
+ tsp_act_update(tspact);
+}
+
+/* Returns RF wiring */
+uint32_t rffe_get_rx_ports(void)
+{
+ return (1 << PORT_LO) | (1 << PORT_DCS1800) | (1 << PORT_PCS1900);
+}
+
+uint32_t rffe_get_tx_ports(void)
+{
+ return (1 << PORT_LO) | (1 << PORT_HI);
+}
+
+/* Returns need for IQ swap */
+int rffe_iq_swapped(uint16_t band_arfcn, int tx)
+{
+ return trf6151_iq_swapped(band_arfcn, tx);
+}
+
+
+#define MCU_SW_TRACE 0xfffef00e
+#define ARM_CONF_REG 0xfffef006
+
+void rffe_init(void)
+{
+ uint16_t reg;
+
+ reg = readw(ARM_CONF_REG);
+ reg &= ~(1 << 7); /* TSPACT4 I/O function, not nRDYMEM */
+ writew(reg, ARM_CONF_REG);
+
+ reg = readw(MCU_SW_TRACE);
+ reg &= ~(1 << 1); /* TSPACT9 I/O function, not MAS(1) */
+ writew(reg, MCU_SW_TRACE);
+
+ /* Configure the TSPEN which is connected to the TWL3025 */
+ tsp_setup(IOTA_STROBE, 1, 0, 0);
+
+ trf6151_init(RITA_STROBE, RITA_RESET);
+}
+
+uint8_t rffe_get_gain(void)
+{
+ return trf6151_get_gain();
+}
+
+void rffe_set_gain(uint8_t dbm)
+{
+ trf6151_set_gain(dbm);
+}
+
+const uint8_t system_inherent_gain = SYSTEM_INHERENT_GAIN;
+
+/* Given the expected input level of exp_inp dBm/8 and the target of target_bb
+ * dBm8, configure the RF Frontend with the respective gain */
+void rffe_compute_gain(int16_t exp_inp, int16_t target_bb)
+{
+ trf6151_compute_gain(exp_inp, target_bb);
+}
+
+void rffe_rx_win_ctrl(int16_t exp_inp, int16_t target_bb)
+{
+ /* FIXME */
+}