📄 tea5760_drv.c
字号:
/*
* Modify by xiezhongren.
* Create 2006.12.1
* Copyright by KONKA SOFTWARE GROUP. 2006.12.1
*
*
*/
#include "l1audio_def.h"
#if defined(TEA5760)
/* GPIO definition */
#if 0
typedef unsigned short uint16;
typedef short int16;
typedef unsigned long uint32;
typedef long int32;
typedef unsigned char uint8;
typedef char int8;
#endif
#define TUNER_BYTE1 1
#define TUNER_BYTE2 2
#define TUNER_BIT0_MASK 0x01
#define TUNER_BIT1_MASK 0x02
#define TUNER_BIT2_MASK 0x04
#define TUNER_BIT3_MASK 0x08
#define TUNER_BIT4_MASK 0x10
#define TUNER_BIT5_MASK 0x20
#define TUNER_BIT6_MASK 0x40
#define TUNER_BIT7_MASK 0x80
//The following is for command bit mask
#define TUNER_MUTE_MASK TUNER_BIT7_MASK
#define TUNER_MUTE_LOCATION 4
#define TUNER_SEARCH_MASK TUNER_BIT6_MASK
#define TUNER_SEARCH_LOCATION 1
#define TUNER_HLSI_MASK TUNER_BIT4_MASK
#define TUNER_HLSI_LOCATION 4
#define TUNER_MONO_STEREO_MASK TUNER_BIT3_MASK
#define TUNER_MONO_LOCATION 4
#define TUNER_STEREO_MASK TUNER_BIT2_MASK
#define TUNER_STEREO_LOCATION 9
#define TUNER_STAND_BY_MASK TUNER_BIT6_MASK
#define TUNER_STAND_BY_LOCATION 3
#define TUNER_SEARCH_UP_DOWN TUNER_BIT7_MASK
#define TUNER_SEARCH_UP_DOWN_LOCATION 1
#define TUNER_SSL0 TUNER_BIT5_MASK
#define TUNER_SSL1 TUNER_BIT6_MASK
#define TUNER_LEVEL_LOCATION 4
#define TUNER_BYTE3_DEFAULT 0x69
#define TUNER_BYTE4_DEFAULT 0x91
#define TUNER_BYTE3 3
#define TUNER_BYTE4 4
#define TUNER_BYTE5_DEFAULT 0x10
#define TUNER_BYTE6_DEFAULT 0x00
#define TUNER_BYTE5 5
#define TUNER_BYTE6 6
#define cFM_TUNER_FREQUENCY_START 8750
#define cFM_TUNER_FREQUENCY_END 10800
#define cFM_TUNER_FREQUENCY_STEP_SIZE_50KHz 5
#define cFM_TUNER_FREQUENCY_STEP_SIZE_100KHz cFM_TUNER_FREQUENCY_STEP_SIZE_50KHz*2
#define SLAVE_ADDRESS 0x11
#define SUB_ADDRESS 0
#define PHILIPS_I2C_WADDRESS 0x22 // by xiezhongren.
#define PHILIPS_I2C_RADDRESS 0x23 // by xiezhongren.
#define cIIC_READING_LENGTH 16 // 10
#define cIIC_WRITING_LENGTH 7
//extern int LM4811_ON(int fm_onoff);
static int16 Philips_FM_Read(uint8 *data, uint16 length, uint8 address);
static int16 Philips_FM_Send(uint8 *data, uint16 length, uint8 address);
void Philips_FM_Mute(uint8 mute);
static void FM_Debug_Print_Bin(uint8 *filename, uint8 *function, uint16 line_number, uint8 *debug_info,uint8 *data, uint16 length);
static void FM_Debug_Print_String(uint8 *filename, uint8 *function, uint16 line_number, uint8 *debug_info,uint8 *data);
static int16 Philips_FM_Send_checkRF(void);
#define HI_SIDE_INJECTION 1
#define LO_SIDE_INJECTION 0
#define FM_HLSI 0x10
#define FM_MUTE 0x80
#define FM_POWERON 0x40
#define FM_SUD 0x80
#define FM_SM 0x40
#define SEND_ADDRESS_WITHOUT_ACK -1001
#define SEND_CMD_ACK_ERROR -1002
#define SEND_READ_ADDRESS_WITHOUT_ACK -1003
#define OPTIMIZER_HI_SIDE_READ_ERROR -1004
#define OPTIMIZER_HI_SIDE_TIMEOUT_ERROR -1005
#define OPTIMIZER_LO_SIDE_READ_ERROR -1006
#define OPTIMIZER_LO_SIDE_TIMEOUT_ERROR -1007
#define CHECK_PHILIPSFM_RF_TIMEOUT -1008
#define CHECK_PHILIPSFM_REATCH_LIMIT -1009
#define CHECK_PHILIPSFM_RF_READ_ERR -1010
typedef struct {
uint8 wb[7];
uint8 rb[16];
uint8 hi_level,lo_level;
}PHILIPS_FM;
PHILIPS_FM philips_fm;
static void FetchCommandData(void)
{
//{0x00,0x00,0x00,0x49,0x10,0x00,0x00};
philips_fm.wb[0] = 0x00;
philips_fm.wb[1] = 0x00;
philips_fm.wb[2] = 0x00;
philips_fm.wb[3] = 0x49;
philips_fm.wb[4] = 0x10;
philips_fm.wb[5] = 0x00;
philips_fm.wb[6] = 0x00;
philips_fm.wb[TUNER_MONO_LOCATION]&=(~TUNER_MONO_STEREO_MASK);
philips_fm.wb[TUNER_HLSI_LOCATION]|=TUNER_HLSI_MASK;
FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Build Data",philips_fm.wb,7);
}
static int32 GetPllFromFrequency(int16 curf,uint8 InJect_Type)
{
int32 PLL;
if(InJect_Type == HI_SIDE_INJECTION)
{
PLL=((int32)curf*10000+225000)/8192;
}
else
{
PLL=((int32)curf*10000-225000)/8192;
}
return PLL;
}
void FMDrv_PowerOnReset(void)
{
uint16 i;
//uint8 philips_read_buffer[26];
SerialCommInit();
FetchCommandData();
// Send Data....
FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Init Send Data",philips_fm.wb,7);
Philips_FM_Send(philips_fm.wb,7,PHILIPS_I2C_WADDRESS);
for( i = 0; i < 1000; i++);
Philips_FM_Read(philips_fm.rb,16,PHILIPS_I2C_RADDRESS);
FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Init Send Data",philips_fm.rb,16);
return;
}
static int16 Philips_FM_Send(uint8 *data, uint16 length, uint8 address)
{
uint16 i;
uint8 ack;
//kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);
SerialCommStart();
ack = SerialCommTxByte(address);
if (ack != 0 )
{
kal_prompt_trace(MOD_MMI,"%s:%d: Write Address ACK not Low!!",__FILE__,__LINE__);
return SEND_ADDRESS_WITHOUT_ACK;
}
GPIO_WriteIO(1,7);//wzs
for(i=0;i<length;i++)
{
ack = SerialCommTxByte(data[i]);
if (ack != 0 )
{
kal_prompt_trace(MOD_MMI,"%s:%d: I = [%d] Write Data ACK not Low!!",__FILE__,__LINE__,i);
return SEND_CMD_ACK_ERROR;
}
else
{
kal_prompt_trace(MOD_MMI,"%s:%d: I = [%d] Write Data: [ %x ]",__FILE__,__LINE__,i,data[i]);
}
}
SerialCommStop();
//kal_prompt_trace(MOD_MMI,"%s:%d: Exit Function: %s",__FILE__,__LINE__,__func__);
return length;
}
static int16 Philips_FM_Read(uint8 *data, uint16 length, uint8 address)
{
uint16 i;
uint8 ack;
uint8 read_fm_data;
//kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);
SerialCommStart();
ack = SerialCommTxByte(address);
if (ack != 0 )
{
kal_prompt_trace(MOD_MMI,"%s:%d: Write Address ACK not Low!!",__FILE__,__LINE__);
return SEND_READ_ADDRESS_WITHOUT_ACK;
}
for(i=0;i<length-1;i++)
{
SerialCommRxByte(&read_fm_data, 0);
data[i] = (uint8)read_fm_data;
}
SerialCommRxByte(&read_fm_data, 1);
data[i] = (uint8)read_fm_data;
SerialCommStop();
//kal_prompt_trace(MOD_MMI,"%s:%d: Exit Function: %s",__FILE__,__LINE__,__func__);
return length;
}
void FMDrv_PowerOffProc(void)
{
int16 retcode;
//GPIO_ModeSetup(3,0);
//GPIO_InitIO(1,3);
// GPIO_WriteIO(1,3); // Modify, Enable LM4811
// tunoff PHILIPS CHIPID1
// 1. power offsetof
FetchCommandData();
philips_fm.wb[3] &= ~(FM_POWERON);
retcode = Philips_FM_Send(philips_fm.wb, 7, PHILIPS_I2C_WADDRESS);
//Disable CHIP
//GPIO_ModeSetup(6,0);
//GPIO_InitIO(1,6);
//GPIO_WriteIO(0,6);//wzs //JAMES
//Disable Loaudspeaker
// LM4811_ON(1);
}
uint8 FMDrv_ValidStop(int16 freq, int8 signalvl, bool is_step_up)
{
int16 retcode;
uint8 fm_hlsi;
uint32 command_pll;
uint8 frrflag,if_value;
uint16 i;
uint8 search_directory;
uint16 used_freq;
used_freq = (freq*10);
kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);
if ( used_freq > 10800 || used_freq < 8750)
{
kal_prompt_trace(MOD_MMI,"%s:%s:%d: fatal error: feq = %d \n",__FILE__,__func__,__LINE__,used_freq);
return 0;
}
if ( is_step_up )
{
search_directory = 1; //up
fm_hlsi = 0;
}
else
{
search_directory = 0; //down
fm_hlsi = 1;
}
if ( fm_hlsi)
{
command_pll = GetPllFromFrequency(used_freq, HI_SIDE_INJECTION);
}
else
{
command_pll = GetPllFromFrequency(used_freq, LO_SIDE_INJECTION);
}
FetchCommandData();
philips_fm.wb[4] = (philips_fm.wb[4] | (FM_MUTE));
//set HLSI
if ( fm_hlsi)
{
philips_fm.wb[1] &= ~(FM_SUD);
philips_fm.wb[4] |= FM_HLSI;
}
else
{
philips_fm.wb[1] |= FM_SUD;
philips_fm.wb[4] &= (~FM_HLSI);
}
// Threshold
philips_fm.wb[4] |= 0x20; // 00100000
// SETTING searching mode
philips_fm.wb[1] |= FM_SM;
// set feq.
philips_fm.wb[1] |= (uint8)((command_pll>>8)&0x0000003f);
philips_fm.wb[2] = (uint8)(command_pll&0x000000ff);
//FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Vaild stop send",philips_fm.wb,7);
// send to philips chip register
retcode = Philips_FM_Send(philips_fm.wb, 7, PHILIPS_I2C_WADDRESS);
if ( retcode < 0 )
{
kal_prompt_trace(MOD_MMI,"%s:%s:%d: set register error,code = %d\n",__FILE__,__func__,__LINE__,retcode);
return 0; // FLASE
}
//wait for RF == 1
retcode = Philips_FM_Send_checkRF();
if ( retcode < 0 )
{
kal_prompt_trace(MOD_MMI,"%s,%s,%d: Check RF Error,retcode:%d", __FILE__,__func__,__LINE__,retcode);
return 0;
}
//FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Read vaild stop",philips_fm.rb,16);
kal_prompt_trace(MOD_MMI,"%s:%s:%d: Feq = %d IF Count = %x, Level = %x ",__FILE__,__func__,__LINE__,used_freq,(philips_fm.rb[8]>>1),(philips_fm.rb[9]>>4));
// IF check
if_value = (philips_fm.rb[8]>>1);
if ( if_value <= 0x31 || if_value >= 0x3e )
{
// not in condition check.
kal_prompt_trace(MOD_MMI,"%s,%s,%d: %x not in IF condition check. ",__FILE__,__func__,__LINE__,if_value);
return 0;
}
philips_fm.hi_level = (philips_fm.rb[9]>>4);
/*
if ( philips_fm.hi_level < 5 ) // FIXME!!
{
return 0;
}
*/
fm_hlsi = ( fm_hlsi )? 0:1;
if ( fm_hlsi)
{
command_pll = GetPllFromFrequency(used_freq, HI_SIDE_INJECTION);
}
else
{
command_pll = GetPllFromFrequency(used_freq, LO_SIDE_INJECTION);
}
FetchCommandData();
philips_fm.wb[4] = (philips_fm.wb[4] | (FM_MUTE));
//set HLSI
if ( fm_hlsi)
{
philips_fm.wb[1] &= ~(FM_SUD);
philips_fm.wb[4] |= FM_HLSI;
}
else
{
philips_fm.wb[1] |= FM_SUD;
philips_fm.wb[4] &= (~FM_HLSI);
}
// SETTING searching mode
philips_fm.wb[1] &= ~(FM_SM);
// set feq.
philips_fm.wb[1] |= (uint8)((command_pll>>8)&0x0000003f);
philips_fm.wb[2] = (uint8)(command_pll&0x000000ff);
// FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Vaild stop send2",philips_fm.wb,7);
// send to philips chip register
retcode = Philips_FM_Send(philips_fm.wb, 7, PHILIPS_I2C_WADDRESS);
if ( retcode < 0 )
{
kal_prompt_trace(MOD_MMI,"%s:%s:%d: set register error,code = %d\n",__FILE__,__func__,__LINE__,retcode);
return 0; // FLASE
}
//wait for RF == 1
retcode = Philips_FM_Send_checkRF();
if ( retcode < 0 )
{
kal_prompt_trace(MOD_MMI,"%s,%s,%d: Check RF Error,retcode:%d", __FILE__,__func__,__LINE__,retcode);
return 0;
}
kal_prompt_trace(MOD_MMI,"%s:%s:%d: FEQ = %d IF Count2 = %x, Level = %x ",__FILE__,__func__,__LINE__,used_freq,(philips_fm.rb[8]>>1),(philips_fm.rb[9]>>4));
//FM_Debug_Print_Bin((uint8 *)__FILE__,(uint8 *)__func__,__LINE__,(uint8 *)"Read vaild stop2",philips_fm.rb,16);
// IF check
if_value = (philips_fm.rb[8]>>1);
if ( if_value <= 0x31 || if_value >= 0x3e )
{
// not in condition check.
kal_prompt_trace(MOD_MMI,"%s,%s,%d: %x not in IF condition check.",__FILE__,__func__,__LINE__,if_value);
return 0;
}
philips_fm.lo_level = (philips_fm.rb[9]>>4);
/*
if ( philips_fm.lo_level < 5 ) // FIXME!!
{
return 0;
}
*/
if ( philips_fm.lo_level > philips_fm.hi_level )
{
if_value = philips_fm.lo_level - philips_fm.hi_level;
}
else
{
if_value = philips_fm.hi_level - philips_fm.lo_level;
}
if ( if_value > 2 )
{
return 0;
}
kal_prompt_trace(MOD_MMI,"%s:%d: Exit Function: %s",__FILE__,__LINE__,__func__);
return 1;
}
//频率选择优化
static int16 FM_Philips_optimizer(int16 curf)
{
uint32 command1_pll,command2_pll;
uint16 i;
int16 retcode;
int16 frrflag;
uint8 fm_hlsi;
// set command 1
// PLL = F+450KHZ
// HLSI = 1
// MUTE = 1
kal_prompt_trace(MOD_MMI,"%s:%d: Entry Function: %s",__FILE__,__LINE__,__func__);
// 1. set Default command Data
FetchCommandData();
// 2. set HI INJECT PLL
command1_pll = GetPllFromFrequency((curf+45), HI_SIDE_INJECTION);
philips_fm.wb[4] = philips_fm.wb[4] | FM_HLSI| FM_MUTE; // HLSI = 1, MUTE = 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -