[mtk] Add initial / unfinished MT6139 driver
This commit is contained in:
parent
b6156d3e3d
commit
9f30c97e4a
|
@ -0,0 +1,60 @@
|
|||
#ifndef _MTK_MT6139_H
|
||||
#define _MTK_MT6139_H
|
||||
|
||||
enum mt6139_band {
|
||||
MTRF_BAND_GSM850 = 0,
|
||||
MTRF_BAND_GSM900 = 1,
|
||||
MTRF_BAND_GSM1800 = 2,
|
||||
MTRF_BAND_GSM1900 = 3,
|
||||
};
|
||||
|
||||
#define MT6139_CW0_SYNCP_SHIFT 0
|
||||
#define MT6139_CW0_SYNCPW (1 << 2)
|
||||
#define MT6139_CW0_DIEN (1 << 3)
|
||||
#define MT6139_CW0_FLT (1 << 4)
|
||||
#define MT6139_CW0_AFC_SHIFT 5
|
||||
#define MT6139_CW0_VCO_SEL (1 << 11)
|
||||
#define MT6139_CW0_GPO (1 << 12)
|
||||
#define MT6139_CW0_POR (1 << 13)
|
||||
|
||||
#define MT6139_CW1_NFRACT_SHIFT 0
|
||||
#define MT6139_CW1_NINT_SHIFT 8
|
||||
#define MT6139_CW1_BAND_SHIFT 16
|
||||
#define MT6139_CW1_TRX_850 (1 << 18)
|
||||
|
||||
#define MT6139_CW2_GAINTBL_SHIFT 0
|
||||
#define MT6139_CW2_MODE_SHIFT 6
|
||||
#define MT6139_CW2_AUTO_CAL (1 << 9)
|
||||
#define MT6139_CW2_DCD_AQ_SHIFT 10
|
||||
#define MT6139_CW2_DCD_AI_SHIFT 16
|
||||
|
||||
#define MT6139_CW9_DCD_CQ_SHIFT 0
|
||||
#define MT6139_CW9_DCD_BQ_SHIFT 7
|
||||
#define MT6139_CW9_PWR_DAC_C (1 << 14)
|
||||
#define MT6139_CW9_PWR_DAC_B (1 << 15)
|
||||
#define MT6139_CW9_PWR_DAC_A (1 << 16)
|
||||
#define MT6139_CW9_AM_ENABLE (1 << 17)
|
||||
|
||||
enum mt6139_cw2_mode {
|
||||
MODE_SLEEP = 0x0,
|
||||
MODE_WARM_UP = 0x1,
|
||||
MODE_RECEIVE = 0x3,
|
||||
MODE_TRANSMIT = 0x4,
|
||||
};
|
||||
|
||||
#define MT6139_CW11_TX_CTL (1 << 0)
|
||||
#define MT6139_CW11_TXG_IQM (1 << 1)
|
||||
#define MT6139_CW11_TXD_IQM (1 << 2)
|
||||
#define MT6139_CW11_TX_DIV2 (1 << 3)
|
||||
#define MT6139_CW11_TX_DIV4 (1 << 4)
|
||||
#define MT6139_CW11_TXG_BUF (1 << 5)
|
||||
#define MT6139_CW11_TXD_BUF (1 << 6)
|
||||
#define MT6139_CW11_TXMODGAIN_SHIFT 7
|
||||
#define MT6139_CW11_TX_FLT_SHIFT 10
|
||||
#define MT6139_CW11_TXAPC_SHIFT 14
|
||||
#define MT6139_CW11_TXPW_SHIFT 16
|
||||
#define MT6139_CW11_TXBIAST_SHIFT 18
|
||||
#define MT6139_CW11_TXDIV_GC0 (1 << 20)
|
||||
#define MT6139_CW11_TXDIV_GC1 (1 << 21)
|
||||
|
||||
#endif /* _MTK_MT6139_H */
|
|
@ -0,0 +1,205 @@
|
|||
/* Driver for RF Transceiver Circuit (MT6139) */
|
||||
|
||||
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <memory.h>
|
||||
#include <keypad.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
|
||||
#include <layer1/agc.h>
|
||||
#include <rffe.h>
|
||||
|
||||
#include <mtk/mt6139.h>
|
||||
|
||||
static void mt6139_compute_pll(uint32_t f_vco_100khz,
|
||||
uint16_t *nint, uint16_t *nfrac)
|
||||
{
|
||||
/* To compute Nint, we assume Nfrac is zero */
|
||||
*nint = (fvco_100khz / (10 * 2 * 26)) - (0 / 130);
|
||||
|
||||
if (nint > 127)
|
||||
printf("VCO Frequency %u kHz is out of spec\n", f_vco_100khz);
|
||||
|
||||
/* Compute Nfract using the pre-computed Nint */
|
||||
/* Nfrac = ( (Fvco/2*26) - Nint) * 130 */
|
||||
/* Nfrac = ( (Fvco*130)/(2*26) - (Nint * 130) */
|
||||
*nfrac = (f_vco_100khz*130)/(52*10) - (nint * 130);
|
||||
}
|
||||
|
||||
/* Set ARFCN. Takes 2 reg_write, i.e. 8 TPU instructions */
|
||||
void mt6139_set_arfcn(uint16_t arfcn, int uplink)
|
||||
{
|
||||
uint32_t regval = 0;
|
||||
uint32_t vco_mult;
|
||||
uint32_t freq_khz, f_vco_100khz;
|
||||
uint16_t nint, nfrac;
|
||||
|
||||
freq_khz = gsm_arfcn2freq10(arfcn, uplink) * 100;
|
||||
printd("ARFCN %u -> %u kHz\n", arfcn, freq_khz);
|
||||
|
||||
switch (gsm_arfcn2band(arfcn)) {
|
||||
case GSM_BAND_850:
|
||||
if (uplink)
|
||||
regval |= MT6139_CW1_TRX_850;
|
||||
regval |= (0 << MT6139_CW1_BAND_SHIFT);
|
||||
vco_mult = 4;
|
||||
break;
|
||||
case GSM_BAND_900:
|
||||
regval |= (1 << MT6139_CW1_BAND_SHIFT);
|
||||
vco_mult = 4;
|
||||
break;
|
||||
case GSM_BAND_1800:
|
||||
regval |= (2 << MT6139_CW1_BAND_SHIFT);
|
||||
vco_mult = 2;
|
||||
break;
|
||||
case GSM_BAND_1900:
|
||||
regval |= (3 << MT6139_CW1_BAND_SHIFT);
|
||||
vco_mult = 2;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported rf_band.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute VCO frequency for channel frequency */
|
||||
f_vco_100khz = (freq_khz / 100) * vco_mult;
|
||||
|
||||
/* Compute Nint and Nfract */
|
||||
mt6139_compute_pll(f_vco_100khz, &nint, &nfrac);
|
||||
|
||||
/* mask-in the Nint / Nfrac bits in CW1 */
|
||||
regval |= (nfrac & 0xff) << MT6139_CW1_NFRACT_SHIFT;
|
||||
regval |= (nint & 0x7f) << MT6139_CW1_NINT_SHIFT;
|
||||
|
||||
}
|
||||
|
||||
void mt6139_init()
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* reset and get it out of reset again */
|
||||
val = MT6139_CW0_DIEN | (0x20 << MT6139_CW0_AFC_SHIFT);
|
||||
mt6139_reg_write(0, val | MT6139_CW0_POR);
|
||||
mt6139_reg_write(0, val);
|
||||
|
||||
/* Turn off AM and A loop calibration function (CM9) */
|
||||
val = (0x40 << MT6139_CW9_DCD_CQ_SHIFT) |
|
||||
(0x40 << MT6139_CW9_DCD_BQ_SHIFT) |
|
||||
MT6139_CW9_PWR_DAC_C | MT6139_CW9_PWR_DAC_B;
|
||||
mt6139_reg_write(9, val);
|
||||
|
||||
/* Move to SLEEP mode */
|
||||
val = (0x3e << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_SLEEP << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
}
|
||||
|
||||
void mt6139_rx_burst()
|
||||
{
|
||||
uint8_t pga_gain;
|
||||
|
||||
/* Turn on the synthesizer and move into Warm-up mode */
|
||||
val = (0x3e << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_WARM_UP << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
|
||||
/* Program the frequency synthesizer N counter and band selection */
|
||||
/* FIXME: see above for mt6139_set_arfcn() */
|
||||
|
||||
/* Set receive mode, PGA gain */
|
||||
val = (pga_gain << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_RECEIVE << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
|
||||
/* FIXME: Do the actual burst Rx */
|
||||
|
||||
/* Set Sleep mode */
|
||||
val = (0x3e << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_SLEEP << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
}
|
||||
|
||||
void mt6139_tx_burst()
|
||||
{
|
||||
/* Turn on the synthesizer and move into Warm-up mode */
|
||||
val = (0x3e << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_WARM_UP << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
|
||||
/* Program the frequency synthesizer N counter and band selection */
|
||||
/* FIXME: see above for mt6139_set_arfcn() */
|
||||
|
||||
/* Send Tx setting */
|
||||
val = MT6139_CW11_TX_CTL |
|
||||
MT6139_CW11_TXG_IQM |
|
||||
MT6139_CW11_TXD_IQM |
|
||||
MT6139_CW11_TX_DIV2 |
|
||||
MT6139_CW11_TX_DIV4 |
|
||||
MT6139_CW11_TXG_BUF |
|
||||
MT6139_CW11_TXD_BUF |
|
||||
(3 << MT6139_CW11_TX_FLT_SHIFT) |
|
||||
(1 << MT6139_CW11_TXAPC_SHIFT) |
|
||||
(3 << MT6139_CW11_TXPW_SHIFT) |
|
||||
(2 << MT6139_CW11_TXBIAST_SHIFT) |
|
||||
MT6139_CW11_TXDIV_GC0;
|
||||
if (1) // low band
|
||||
mt6139_reg_write(11, val | (0 << MT6139_CW11_TXMODGAIN_SHIFT));
|
||||
else
|
||||
mt6139_reg_write(11, val | (4 << MT6139_CW11_TXMODGAIN_SHIFT));
|
||||
|
||||
/* Set Transmit mode */
|
||||
val = (0x3e << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_TRANSMIT << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
|
||||
/* FIXME: Do the actual burst Tx */
|
||||
|
||||
/* Set Sleep mode */
|
||||
val = (0x3e << MT6139_CW2_GAINTBL_SHIFT) |
|
||||
(MODE_SLEEP << MT6139_CW2_MODE_SHIFT) |
|
||||
MT6139_CW2_AUTO_CAL |
|
||||
(0x20 << MT6139_CW2_DCD_AQ_SHIFT) |
|
||||
(0x20 << MT6139_CW2_DCD_AI_SHIFT);
|
||||
mt6139_reg_write(2, val);
|
||||
}
|
||||
|
Loading…
Reference in New Issue