summaryrefslogtreecommitdiffstats
path: root/src/target/firmware/board/gtm900b/rffe_gtm900b.c
blob: 3efb5e2ad144d822d1b9d688c26ede09f109c215 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* RF frontend driver for Huawei GTM900-B modems, supporting both
 * MG01GSMT and MGCxGSMT hardware variants */

/* (C) 2019 by Steve Markgraf <steve@steve-m.de>
 *
 * All Rights Reserved
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <stdint.h>
#include <stdio.h>

#include <debug.h>
#include <memory.h>
#include <rffe.h>
#include <calypso/tsp.h>
#include <rf/trf6151.h>
#include <flash/cfi_flash.h>

/* This is a value that has been measured for the GTM900-B: 74dBm,
   it is the difference between the input level at the antenna and what
   the DSP reports, subtracted by the total gain of the TRF6151 */
#define SYSTEM_INHERENT_GAIN	74

/* describe how the RF frontend is wired on the Huawei GTM900-B */
#define		IOTA_STROBE	TSPEN(0)	/* Strobe for the Iota TSP */
#define		RITA_STROBE	TSPEN(2)	/* Strobe for the Rita TSP */

#define		RITA_RESET	TSPACT(0)	/* Reset of the Rita TRF6151 */
#define		PA_BAND_SELECT	TSPACT(3)	/* Low: 850/900, High: 1800/1900 */
#define		PA_TX_ENABLE	TSPACT(9)	/* Enable the Power Amplifier */

/* MGC2GSMT Ver. BRF specific antenna switch signals, low active */
#define		ASM_VC1		TSPACT(1)	/* low on GSM900 TX */
#define		ASM_VC2		TSPACT(2)	/* low on DCS1800 TX */

/* MG01GSMT Ver. C specific antenna switch signals, low active */
#define		CXG_CTLA	TSPACT(4)	/* CXG1192UR CTLA input */
#define		CXG_CTLB	TSPACT(1)	/* CXG1192UR CTLB input */
#define		CXG_CTLC	TSPACT(2)	/* CXG1192UR CTLC input */

/*
 * The Sony CXG1192UR switch is wired as follows on the MG01GSMT Ver. C:
 *
 * Rx1: GSM850 RX filter (Epcos B5013)
 * Rx2: GSM900 RX filter (Epcos B7710)
 * Rx3: DCS1800 RX filter (Epcos 7714)
 * Rx4: PCS1900 RX filter (not populated)
 * Tx1: low band PA output
 * Tx2: high band PA output
 */

extern int gtm900_hw_is_mg01gsmt;	/* set in init.c */

static inline void rffe_mode_mgc2gsmt(enum gsm_band band, int tx)
{
	uint16_t tspact = tsp_act_state();

	/* First we mask off all bits from the state cache */
	tspact &= ~(PA_BAND_SELECT | PA_TX_ENABLE);
	tspact |=  (ASM_VC1 | ASM_VC2);	/* low-active */

#ifdef CONFIG_TX_ENABLE
	/* Then we selectively set the bits on, if required */
	if (tx) {
		tspact |= PA_TX_ENABLE;
		tspact &= ~CXG_CTLA;

		if (band == GSM_BAND_1800 || band == GSM_BAND_1900) {
			tspact |= PA_BAND_SELECT;
			tspact &= ~ASM_VC2;
		} else {
			tspact &= ~ASM_VC1;
		}
	}
#endif /* TRANSMIT_SUPPORT */

	tsp_act_update(tspact);
}

static inline void rffe_mode_mg01gsmt(enum gsm_band band, int tx)
{
	uint16_t tspact = tsp_act_state();

	/* First we mask off all bits from the state cache */
	tspact &= ~(PA_BAND_SELECT | PA_TX_ENABLE);
	tspact |=  (CXG_CTLA | CXG_CTLB | CXG_CTLC);	/* low-active */

	switch (band) {
	case GSM_BAND_850:
		tspact &= ~CXG_CTLB;		  /* select Ant1 - Rx1 */
		break;
	case GSM_BAND_900:
		tspact &= ~CXG_CTLC;		  /* select Ant1 - Rx2 */
		break;
	case GSM_BAND_1800:			  /* select Ant2 - Rx3 */
		break;
	case GSM_BAND_1900:
		tspact &= ~(CXG_CTLB | CXG_CTLC); /* select Ant2 - Rx4 */
		break;
	default:
		break;
	}

#ifdef CONFIG_TX_ENABLE
	/* Then we selectively set the bits on, if required */
	if (tx) {
		tspact |= PA_TX_ENABLE;
		tspact &= ~CXG_CTLA;

		if (band == GSM_BAND_1800 || band == GSM_BAND_1900) {
			tspact |= PA_BAND_SELECT;
			tspact &= ~CXG_CTLB;
		}
	}
#endif /* TRANSMIT_SUPPORT */

	tsp_act_update(tspact);
}

/* switch RF Frontend Mode */
void rffe_mode(enum gsm_band band, int tx)
{
	if (gtm900_hw_is_mg01gsmt)
		rffe_mode_mg01gsmt(band, tx);
	else
		rffe_mode_mgc2gsmt(band, tx);
}

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 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);

	/* 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 */
}