//==========================================================================
//
// FM_Module.c
//
//
//
//==========================================================================
//
// Author(s): yangdi
// Contributors:
// Date: 2010年11月23日 10:09:41
// Description:
//==========================================================================
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <mach/irqs.h>
#include <linux/input.h>
#include "FM_hw_ctrl.h"
#define DBGFLG_FM_HW_LVL0 0x1
#define DBGFLG_FM_HW_LVL1 0x2
#define DBGFLG_FM_HW_LVL2 0x10
#include <mach/typedef.h>
#include <mach/gp_i2c_bus.h>
#include <mach/regs-scu.h>
#include "asm/delay.h"
#include <mach/audio/audio_util.h>
#include <mach/audio/i2s.h>
#define DBGFLG_FM_HW_LVL0 0x1
#define DBGFLG_FM_HW_LVL1 0x2
#define DBGFLG_FM_HW_LVL2 0x10
#define MMP_ARM_I2C_P034_BASE (0xfd000000+0xB03000)
#define I2C_P0ICCR (MMP_ARM_I2C_P034_BASE+0x00)
#define I2C_P0ICSR (volatile UINT32 *)(MMP_ARM_I2C_P034_BASE+0x04)
#define I2C_P0IAR (volatile UINT32 *)(MMP_ARM_I2C_P034_BASE+0x08)
#define I2C_P0IDSR (volatile UINT32 *)(MMP_ARM_I2C_P034_BASE+0x0C)
#define I2C_P0IDEBCLK (volatile UINT32 *)(MMP_ARM_I2C_P034_BASE+0x10)
#define I2C_P0ITXLCLK (volatile UINT32 *)(MMP_ARM_I2C_P034_BASE+0x14)
#define MMP_SARADC_P012_BASE 0x9301F000
#define MMP_SCU_A_BASE 0xfc800000+0x7000//0x93007000
#define MMP_SCU_B_BASE 0xfc000000+0x5000//
#define MMP_SCU_C_BASE 0xfd000000+0x5000//0x92005000
#define CYG_SCU_C_PERI_CLKEN ((volatile UINT32 *)(MMP_SCU_C_BASE+0x0004)) // R/W
#define CYG_SCU_B_PADGRP_SEL1 ((volatile UINT32 *)(MMP_SCU_B_BASE+0x0084))
#define DEV_SARADC_DACCTRL (volatile UINT32 *)(MMP_SARADC_P012_BASE+0x2C) //Audio DAC control
#define CYG_SCU_A_PERI_CLKEN ((volatile UINT32 *)(MMP_SCU_A_BASE+0x0004)) // R/W
#define CYG_SCU_B_PERI_CLKEN ((volatile UINT32 *)(MMP_SCU_B_BASE+0x0020))
//#define //DBGLVL_PRINT(_lvl_, args...) printk(_lvl_, args...)
#define I2C_C_ICCR_OFST 0x00
#define I2C_C_ICSR_OFST 0x04
#define I2C_C_IAR_OFST 0x08
#define I2C_C_IDSR_OFST 0x0C
#define I2C_C_IDEBCLK_OFST 0x10
#define I2C_C_TXLCLK_OFST 0x14
#define SAR_HPINS_DAC (0x0<<6)//audio driver input 00:DAC
#define SAR_HPINS_MIC (0x1<<6)//audio driver input 01:MIC
#define SAR_HPINS_LININ (0x2<<6)//audio driver input 10:line-in
#define SAR_HPINS_MASK (0x3<<6)//audio driver input mask
#define SAR_DAC_POWER (1<<11) //
#ifndef HAL_READ_UINT32
#define HAL_READ_UINT32( _register_, _value_ ) \
((_value_) = *((volatile unsigned int *)(_register_)))
#endif
#ifndef HAL_WRITE_UINT32
#define HAL_WRITE_UINT32( _register_, _value_ ) \
(*((volatile unsigned int *)(_register_)) = (_value_))
#endif
#define readl(addr) *((volatile unsigned int *)(addr))
#define writel(value,addr) *((volatile unsigned int *)(addr)) = (value)
#define FM_NAME "FM"
//static
UINT32 g_FM_I2C_table_fm1010[18]={
0xFFFB, // R0 -- the first writable register .
0x5B15, // R1.
0xD0B9, // R2.
0xA010, // R3, seekTHD = 16
0x0780, // R4
0x28AB, // R5
0x6400, // R6
0x1EE7, // R7
0x7141, // R8
0x007D, // R9
0x82C6, // R10 disable wrap
0x4E55, // R11. <---
0x970C, // R12.
0xB845, // R13
0xFC2D, // R14
0x8097, // R15
0x04A1, // R16
0xDF6A // R17
};
//static
typedef struct fm_info_s {
struct miscdevice dev;
int i2c_handle;
int used_flag;
} fm_info_t;
static struct fm_info_s fm_data = {
.i2c_handle = 0,
.used_flag = 0,
};
UINT8 seeking=0;
//globe var
// 声明
void FM_AR1000_MUTE_ENABLE(INT32 value);
void FM_AR1000_SEEK_ENABLE(INT32 value);
void SETAR1000_FREQ2CHAN(INT32 FreqKHz);
INT32 FM_I2C_config_fm1010(void);
INT32 FM_AR1000_TUNE_HILO1(INT32 DisFreqKHz);
//--------------------------------------------------------------
void FM_AR1000_TUNE_HILO(INT32 FreqKHz)
{
INT32 temp;
FM_AR1000_MUTE_ENABLE(1); //Set Muto ON before TUNE
FM_AR1000_SEEK_ENABLE(0); //clear SEEK
//TUNE to FreqKHz with current setting
SETAR1000_FREQ2CHAN(FreqKHz); // this function will turn on TUNE
// TUNE begins then wait for STC flag
FM_rd_fm1010(0x20, 0x13, &temp);
temp &=0x0020; // check STC flag
while( temp == 0){
FM_rd_fm1010(0x20, 0x13, &temp);
temp &=0x0020; // check STC flag
}
FM_AR1000_MUTE_ENABLE(0); //Set MUTO OFF before TUNE
}
int I2C_P0_P034_mstart(UINT32 aAck, UINT32 aCmd, UINT32 aData)
{
unsigned int ctrl = 0;
unsigned int iccr = 0;
unsigned int delay_count = 25000;
int ret = 0;
iccr = readl( I2C_P0ICCR + I2C_C_ICCR_OFST);
iccr &= 0x2F;
switch(aCmd){
case 1: // write
iccr |= 0x00;
ctrl = 0xD0;
break;
case 2: // Read
iccr |= 0x80;
ctrl = 0x90;
break;
default:
iccr |= 0x00;
ctrl = 0xD0;
break;
}
writel(iccr,I2C_P0ICCR + I2C_C_ICCR_OFST);
writel(ctrl, I2C_P0ICCR + I2C_C_ICSR_OFST);
if(2 == aCmd){ //READ CMD
writel((aData|0x01), I2C_P0ICCR + I2C_C_IDSR_OFST);
}
else{
writel(aData, I2C_P0ICCR + I2C_C_IDSR_OFST);
}
writel(ctrl | 0x20, I2C_P0ICCR + I2C_C_ICSR_OFST);
do{
iccr =readl(I2C_P0ICCR + I2C_C_ICCR_OFST);
ctrl =readl(I2C_P0ICCR+ I2C_C_ICSR_OFST);
//udelay(20);
//usleep(2);
if(--delay_count <= 0)
{
ret = -1;
break;
}
}
while( !(iccr & 0x10) | // Interrupt Pending
(ctrl & 0x01 & aAck) // ACK Received
);
return ret;
}
int I2C_P0_P034_mmid(unsigned int aAck, unsigned int aCmd, unsigned int aData)
{
unsigned int iccr, ctrl, data0;
unsigned int delay_count = 25000;
int ret = 0;
iccr =readl( I2C_P0ICCR + I2C_C_ICCR_OFST);
iccr &= 0x2F;
switch(aCmd){
case 1: // write
writel(aData, I2C_P0ICCR+ I2C_C_IDSR_OFST);
iccr = 0x10|iccr;
break;
case 2: // Read
if(aAck == 1){
iccr |= 0x90;
}
else{
iccr |= 0x10;
}
break;
default:
iccr |= 0x00;
break;
//=======================================================
}
writel(iccr, I2C_P0ICCR + I2C_C_ICCR_OFST);
do{
iccr =readl( I2C_P0ICCR + I2C_C_ICCR_OFST);
ctrl =readl( I2C_P0ICCR + I2C_C_ICSR_OFST);
//udelay(20);
if(--delay_count <= 0)
{
ret = -1;
return ret;
}
}
while( !(iccr & 0x10) | // Interrupt Pending
(ctrl & 0x01 & aAck) // ACK Received
);
data0 =readl( I2C_P0ICCR + I2C_C_IDSR_OFST);
return data0;
}
void I2C_P0_P034_stop(unsigned int aAck, unsigned int aCmd, unsigned int aData)
{
unsigned int ctrl;
switch(aCmd){
case 1: // write
ctrl = 0xD0;
writel(ctrl, I2C_P0ICCR + I2C_C_ICSR_OFST);
do{
ctrl =readl(I2C_P0ICCR+ I2C_C_ICSR_OFST);
}
while(ctrl & 0x20); // wait non-busy
break;
case 2:
ctrl = 0x90;
writel(ctrl, I2C_P0ICCR + I2C_C_ICSR_OFST);
do{
ctrl =readl(I2C_P0ICCR+ I2C_C_ICSR_OFST);
}
while(ctrl & 0x20); // wait non-busy
break;
default:
ctrl = 0xD0;
break;
}
}
//----------------------------------------------------------------------------
INT32 FM_wr_fm1010(UINT32 aId, UINT32 aAddr, UINT32 aData)
{
INT32 ret;
//I2C_P0_P034_WR(aId, aAddr, aData);
ret=I2C_P0_P034_mstart(0, 1, aId);
if(ret == -1)
{
return -1;
}
ret=I2C_P0_P034_mmid(0, 1, aAddr);
if(ret == -1)
{
return -1;
}
ret=I2
评论15