📄 mt6189a1_drv.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
*
* Filename:
* ---------
* MT6189A1_drv.c
*
* Project:
* --------
* MAUI
*
* Description:
* ------------
*
* FM Radio Driver (MT6189A1)
*
* Author:
* -------
* -------
*
*******************************************************************************/
#include "l1audio_def.h"
#include "drv_comm.h"
#if (defined(MT6189A1))
static uint8 cw_cache[66] = {0};
#if defined MT6189_DEBUG
static uint8 dbg_cw_readback = 0;
#endif
#define USE_I2C
/// #define MT6189_DEBUG
/// #define MT6189_DEBUG_DUMP_LOG
#if (defined(MT6205B) || defined(MT6208)) && defined(MT6189_DEBUG_DUMP_LOG)
#error "No file system on MT6205!"
#endif
/* MT6189 Control Word */
#define CW(_A,_B) (const)(uint8)((_A << 1) + _B)
/* General propose constant */
#define MT6189 96 /// Device ID of MT6189 = 96
#define OP_WRITE 0 /// Write to MT6189
#define OP_READ 1 /// Read from MT6189
#define MT6189_WRITE 192
#define MT6189_READ 193
#define SET_FREQ_FAIL -1
#define LO_INJECTION 0
#define HI_INJECTION 1
#define RSSI_CHECK_FAIL 2
#define FM_TUNER_GRID 100
#define PRESET_IF 140 /// Preset IF: 140 khz
#define IF_MEASURE_COUNT 2 /// 2 * 1,9 ms
#define VCO_LOCKING_TIME 6 /// 8 * 4.615 ms
#define CALIBRATION_FAIL_COUNT_THRESHOLD 5
#if !defined( MT6205B ) && !defined( MT6208 )
#define REF_CLK_32K
#define PRESET_IF_CNT 274 /// 140000 * 64 / 32768 = 273.4375
#define PRESET_IF_DELTA_O 30 //30
#define IF_CONVERT_FACTOR 512 /// 32768 / 64 = 512
#else
#define USE_MT6189_AMP
#define REF_CLK_26M
#define PRESET_IF_CNT 265 /// 140000 * 49152 / 26000000 = 264.66
#define PRESET_IF_DELTA_O 32
#define IF_CONVERT_FACTOR 529 /// 26000000 / 49152 = 529
#endif
/*
#define REF_CLK_26M
#define PRESET_IF_CNT 265 /// 140000 * 49152 / 26000000 = 264.66
#define PRESET_IF_DELTA 29
#define IF_CONVERT_FACTOR 529 /// 26000000 / 49152 = 529
*/
#ifdef USE_MT6189_AMP
void ExtSwitchInit(void);
void SwitchExtFMPath(uint8 if_on);
#endif
/* Serial communication interfaces */
void SerialCommInit(void);
void SerialCommRelease(void);
void SerialCommCryClkOn(void);
void SerialCommCryClkOff(void);
void GPIO_WriteIO(char data,char port);
#if defined USE_I2C
void SerialCommStart(void);
void SerialCommStop(void);
uint8 SerialCommTxByte(uint8 data);
void SerialCommRxByte(uint8 *data, uint8 ack);
#elif defined USE_3_WIRE
uint8 SerialCommTxByte(uint8 cw, uint8 data);
void SerialCommRxByte(uint8 cw, uint8 *data);
#endif
typedef struct {
uint8 addr;
uint8 value;
} ctrl_word_setting;
typedef struct {
uint8 addr;
uint8 and;
uint8 or;
} ctrl_word_operation;
extern uint8 const FM_RADIO_INPUT_LEVEL_THRESHOLD;
/// Global variables for current FM status
static int16 _current_frequency = -1;
static uint8 _current_level = 0x80;
static bool _is_fm_on = false;
static bool _is_fm_mute = false;
static uint8 _valid_rssi = 0;
static uint16 PRESET_IF_CNT_PLUS; //add to adjust IF rounding
static uint8 PRESET_IF_DELTA = PRESET_IF_DELTA_O;
static uint8 RSSI_offset = 0;//FM_RADIO_INPUT_LEVEL_THRESHOLD;
static uint8 _rssi_threshold = 0;//RSSI_offset;
#ifdef MT6189_DEBUG_DUMP_LOG
extern uint32 video_get_current_time(void);
extern uint32 video_get_duration_ms(uint32 t1);
static kal_uint8 _file_name[] = {"D\0:\0\\\0f\0m\0_\0l\0o\0g\0.\0t\0x\0t\0\0\0"};
static uint32 _data_written;
static uint8 _dbg_str[128];
static FS_HANDLE _file_handle = 0;
#endif
static void MT6189_Mute(uint8 mute);
void FMDrv_EvaluateRSSIThreshold(void);
typedef enum group_idx {
mono=0,
stereo,
RSSI_threshold,
IF_count_delta,
GROUP_TOTAL_NUMS
} FACTORY_GROUP_ENUM;
typedef enum item_idx {
Sblend_ON=0,
Sblend_OFF,
ITEM_TOTAL_NUMS
} FACTORY_ITEM_INDEX;
#define POWER_ON_COMMAND_COUNT 49
static const ctrl_word_setting PowerOnSetting[POWER_ON_COMMAND_COUNT] = {
{ CW( 6, 1), 16 }, { CW( 7, 1), 0 },
{ CW( 0, 1), 1 }, { CW( 0, 0), 1 },
{ CW( 14, 1), 7 }, { CW( 14, 0), 230 },//166
{ CW( 1, 1), 6 }, { CW( 1, 0), 0 },
{ CW( 2, 1), 12 }, { CW( 2, 0), 187 },
#if defined REF_CLK_32K //==============================================
{ CW( 3, 1), 32 }, { CW( 3, 0), 34 },
#elif defined REF_CLK_13M
{ CW( 3, 1), 32 }, { CW( 3, 0), 66 },
#elif defined REF_CLK_26M
{ CW( 3, 1), 32 }, { CW( 3, 0), 194 },
#else
#error "Reference Clock Definition Error!"
#endif //=================================================================
{ CW( 4, 1), 194 }, { CW( 4, 0), 183 },
{ CW( 5, 1), 0 }, { CW( 5, 0), 255 },
{ CW( 8, 1), 198 }, { CW( 8, 0), 8 },
{ CW( 9, 1), 6 }, { CW( 9, 0), 2 },
{ CW( 10, 1), 48 }, { CW( 10, 0), 192 },
{ CW( 11, 1), 32 }, { CW( 11, 0), 0 },
{ CW( 12, 1), 49 }, { CW( 12, 0), 128 },
{ CW( 13, 1), 0 }, { CW( 13, 0), 3 },
{ CW( 15, 1), 170 }, { CW( 15, 0), 170 },
{ CW( 16, 1), 0 }, { CW( 16, 0), 0 },
{ CW( 17, 1), 136 }, { CW( 17, 0), 136 },
{ CW( 18, 1), 2 }, { CW( 18, 0), 2 },
{ CW( 19, 1), 0 }, { CW( 19, 0), 170 },
{ CW( 20, 1), 0 }, { CW( 20, 0), 0 },
{ CW( 21, 1), 7 }, { CW( 21, 0), 30 },
{ CW( 23, 1), 0 }, { CW( 23, 0), 0 },
{ CW( 24, 1), 5 }, { CW( 24, 0), 128 },
{ CW( 6, 1), 16 }, { CW( 7, 1), 0 },
{ CW( 7, 0), 7 },
};
#define POWER_OFF_COMMAND_COUNT 11
static const ctrl_word_operation PowerOffProc[POWER_OFF_COMMAND_COUNT] = {
{ CW( 1, 1), 0xDF, 0x20 }, /// CW1 [13:13] 1
{ CW( 5, 0), 0x00, 0x00 }, /// CW5 [7:0] 0
{ CW( 3, 0), 0xFE, 0x01 }, /// CW3 [0:0] 1
{ CW( 10, 0), 0xE0, 0x1F }, /// CW10 [4:0] 1
{ CW( 12, 0), 0xFE, 0x01 }, /// CW12 [0:0] 1
{ CW( 12, 1), 0xFD, 0x02 }, /// CW12 [9:9] 1
{ CW( 13, 0), 0xFE, 0x01 }, /// CW13 [0:0] 1
{ CW( 19, 1), 0xFE, 0x01 }, /// CW19 [8:8] 1
{ CW( 21, 0), 0xDF, 0x20 }, /// CW21 [5:5] 1
{ CW( 14, 1), 0x00, 0xFF }, /// CW14 [15:8] 1
{ CW( 4, 0), 0xFC, 0x00 }, /// CW4 [1:0] 0
};
#define CAL_PLL_COMMAND_COUNT 59
static const ctrl_word_operation CalPLLProcess[CAL_PLL_COMMAND_COUNT] = {
{ CW( 1, 1), 0xDF, 0x00 }, /// CW1 [13:13] 0
{ CW( 3, 0), 0xDD, 0x22 }, /// CW3 [5:5] 1, /// CW3 [1:1] 1
{ CW( 3, 1), 0x1F, 0xE0 }, /// CW3 [15:13] 7
{ CW( 6, 1), 0x0F, 0x10 }, /// CW6 [15:12] 1
{ CW( 7, 1), 0xFC, 0x00 }, /// CW7 [9:8] 0
#if defined REF_CLK_32K //==============================================
{ CW( 3, 0), 0x1E, 0x20 }, /// CW3 [7:5] 1, /// CW3 [0:0] 0
#elif defined REF_CLK_13M
{ CW( 3, 0), 0x1E, 0x40 }, /// CW3 [7:5] 2, /// CW3 [0:0] 0
#elif defined REF_CLK_26M
{ CW( 3, 0), 0x1E, 0xC0 }, /// CW3 [7:5] 6, /// CW3 [0:0] 0
#endif //=================================================================
{ CW(103, 1), 0xF8, 0x04 }, /// CW103 [10:8] 4
{ CW(103, 0), 0xC0, 0x20 }, /// CW103 [5:0] 32
{ CW(101, 0), 0xF8, 0x04 }, /// CW101 [2:0] 4
{ CW( 12, 0), 0x9E, 0x60 }, /// CW12 [0:0] 0, /// CW12 [6:5] 3
{ CW( 12, 1), 0xFE, 0x01 }, /// CW12 [8:8] 1
{ CW( 14, 0), 0x6F, 0x10 }, /// CW14 [4:4] 1, /// CW14 [7:7] 0
{ CW( 6, 0), 0xFC, 0x01 }, /// CW6 [1:0] 1
{ CW( 7, 1), 0xFC, 0x03 }, /// CW7 [9:8] 3
{ CW( 6, 1), 0x00, 0x66 }, /// CW6 [15:8] 102
{ CW( 25, 1), 0xF0, 0x03 }, /// CW25 [11:8] 3
#if defined REF_CLK_32K //==============================================
{ CW( 25, 0), 0x00, 0x7A }, /// CW25 [7:0] 122
#elif defined REF_CLK_13M
{ CW( 25, 0), 0x00, 0x5E }, /// CW25 [7:0] 94
#elif defined REF_CLK_26M
{ CW( 25, 0), 0x00, 0x5E }, /// CW25 [7:0] 94
#endif //=================================================================
{ CW( 1, 0), 0x00, 0x00 }, /// CW1 [7:0] 0
#if defined REF_CLK_32K //==============================================
{ CW( 5, 0), 0xEF, 0x10 }, /// CW5 [4:4] 1
#elif defined REF_CLK_13M
{ CW( 5, 0), 0xEF, 0x00 }, /// CW5 [4:4] 0
#elif defined REF_CLK_26M
{ CW( 5, 0), 0xEF, 0x00 }, /// CW5 [4:4] 0
#endif //=================================================================
{ CW( 6, 1), 0xFE, 0x01 }, /// CW6 [8:8] 1
{ CW(127, 1), 0x00, 0x01 }, /// <----------------- polling SARIFG
{ CW( 1, 0), 0x00, 0x00 }, /// CW1 [7:0] 0, reset CW1_0
{ CW( 6, 1), 0x0F, 0x10 }, /// CW6 [15:12] 1
{ CW( 7, 1), 0xFC, 0x00 }, /// CW7 [9:8] 0
#if defined REF_CLK_32K //==============================================
{ CW( 3, 0), 0x1E, 0x20 }, /// CW3 [7:5] 1, /// CW3 [0:0] 0
#elif defined REF_CLK_13M
{ CW( 3, 0), 0x1E, 0x40 }, /// CW3 [7:5] 2, /// CW3 [0:0] 0
#elif defined REF_CLK_26M
{ CW( 3, 0), 0x1E, 0xC0 }, /// CW3 [7:5] 6, /// CW3 [0:0] 0
#endif //=================================================================
{ CW( 12, 0), 0x9E, 0x60 }, /// CW12 [6:5] 3, /// CW12 [0:0] 0
{ CW( 12, 1), 0xFE, 0x01 }, /// CW12 [8:8] 1
{ CW( 14, 0), 0x6F, 0x10 }, /// CW14 [4:4] 1, /// CW14 [7:7] 0
{ CW( 6, 0), 0xFC, 0x01 }, /// CW6 [1:0] 1
{ CW( 7, 1), 0xFC, 0x03 }, /// CW7 [9:8] 3
{ CW( 6, 1), 0x00, 0x76 }, /// CW6 [15:8] 118
{ CW( 25, 1), 0xF0, 0x03 }, /// CW25 [11:8] 3
#if defined REF_CLK_32K //==============================================
{ CW( 25, 0), 0x00, 0x7A }, /// CW25 [7:0] 122
#elif defined REF_CLK_13M
{ CW( 25, 0), 0x00, 0x5E }, /// CW25 [7:0] 94
#elif defined REF_CLK_26M
{ CW( 25, 0), 0x00, 0x5E }, /// CW25 [7:0] 94
#endif //=================================================================
{ CW( 1, 0), 0x00, 0x00 }, /// CW1 [7:0] 0
#if defined REF_CLK_32K //==============================================
{ CW( 5, 0), 0xEF, 0x10 }, /// CW5 [4:4] 1
#elif defined REF_CLK_13M
{ CW( 5, 0), 0xEF, 0x00 }, /// CW5 [4:4] 0
#elif defined REF_CLK_26M
{ CW( 5, 0), 0xEF, 0x00 }, /// CW5 [4:4] 0
#endif //=================================================================
{ CW( 6, 1), 0xFE, 0x01 }, /// CW6 [8:8] 1
{ CW(127, 1), 0x00, 0x01 }, /// <----------------- polling SARIFG
{ CW( 1, 0), 0x00, 0x00 }, /// CW1 [7:0] 0, reset CW1_0
{ CW( 6, 1), 0x0F, 0x10 }, /// CW6 [15:12] 1
{ CW( 7, 1), 0xFC, 0x00 }, /// CW7 [9:8] 0
#if defined REF_CLK_32K //==============================================
{ CW( 3, 0), 0x1E, 0x20 }, /// CW3 [7:5] 1, /// CW3 [0:0] 0
#elif defined REF_CLK_13M
{ CW( 3, 0), 0x1E, 0x40 }, /// CW3 [7:5] 2, /// CW3 [0:0] 0
#elif defined REF_CLK_26M
{ CW( 3, 0), 0x1E, 0xC0 }, /// CW3 [7:5] 6, /// CW3 [0:0] 0
#endif //=================================================================
{ CW( 12, 0), 0x9E, 0x60 }, /// CW12 [6:5] 3, /// CW12 [0:0] 0
{ CW( 12, 1), 0xFE, 0x01 }, /// CW12 [8:8] 1
{ CW( 14, 0), 0x6F, 0x10 }, /// CW14 [4:4] 1, /// CW14 [7:7] 0
{ CW( 6, 0), 0xFC, 0x01 }, /// CW6 [1:0] 1
{ CW( 6, 1), 0x00, 0x56 }, /// CW6 [15:8] 86
{ CW( 7, 1), 0xFC, 0x03 }, /// CW7 [9:8] 3
{ CW( 25, 1), 0xF0, 0x03 }, /// CW25 [11:8] 3
#if defined REF_CLK_32K //==============================================
{ CW( 25, 0), 0x00, 0x7A }, /// CW25 [7:0] 122
#elif defined REF_CLK_13M
{ CW( 25, 0), 0x00, 0x5E }, /// CW25 [7:0] 94
#elif defined REF_CLK_26M
{ CW( 25, 0), 0x00, 0x5E }, /// CW25 [7:0] 94
#endif //=================================================================
{ CW( 1, 0), 0x00, 0x00 }, /// CW1 [7:0] 0
#if defined REF_CLK_32K //==============================================
{ CW( 5, 0), 0xEF, 0x10 }, /// CW5 [4:4] 1
#elif defined REF_CLK_13M
{ CW( 5, 0), 0xEF, 0x00 }, /// CW5 [4:4] 0
#elif defined REF_CLK_26M
{ CW( 5, 0), 0xEF, 0x00 }, /// CW5 [4:4] 0
#endif //=================================================================
{ CW( 6, 1), 0xFE, 0x01 }, /// CW6 [8:8] 1
{ CW(127, 1), 0x00, 0x01 }, /// <----------------- polling SARIFG
{ CW( 1, 0), 0x00, 0x00 }, /// CW1 [7:0] 0, reset CW1_0
{ CW( 14, 0), 0x6F, 0x80 }, /// CW14 [4:4] 0, [7:7] 1
{ CW( 12, 0), 0x1F, 0x80 }, /// CW12 [6:5] 0, /// CW12 [7:7] 1
{ CW( 12, 1), 0xDF, 0x00 }, /// CW12 [13:13] 0
{ CW( 13, 0), 0x7F, 0x00 }, /// CW13 [7:7] 0
{ CW( 23, 1), 0xE3, 0x00 }, /// CW23 [12:10] 0
};
#define CAL_DEMOD_I_COMMAND_COUNT 41
static const ctrl_word_operation CalDemodIProcess[CAL_DEMOD_I_COMMAND_COUNT] = {
{ CW( 1, 1), 0xDF, 0x00 }, /// CW1 [13:13] 0
{ CW( 10, 0), 0xF7, 0x00 }, /// CW10 [3:3] 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -