/********************************************************************************
Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved.
FileName: hw_fm8035.c
Description: FM 收音模块 fm8035 驱动程序.
-------------------------------------------------------------------------------
Created by: 李 青
Created Date: 2014-4-22 9:51
Version: 0.1
Descriptions:
-------------------------------------------------------------------------------
Modified by:
Created Date:
Version:
Descriptions:
********************************************************************************/
#define _FM8035_IN_
#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/ioport.h>
#include <linux/input-polldev.h>
#include <linux/console.h>
#include <linux/fb.h>
#include <mach/iomux.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/workqueue.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <mach/gpio.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <mach/board.h>
#include <linux/preempt.h>
#include "fm8035.h"
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <mach/irqs.h>
#include <linux/miscdevice.h>
#include <asm/dma.h>
#include <linux/preempt.h>
//#include "rk29_spim.h"
#include <linux/spi/spi.h>
#include <mach/board.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
#define DRV_NAME "RADIO_FM8035"//"FM8035"
struct fm8035_dev_s{
struct miscdevice misc_dev;
struct i2c_client *client;
const struct fm8035_platform_data *plat_data;
unsigned short FmSearchMode;
unsigned short FmSearchDirect;
unsigned long FmArea;
bool FmStereo;
unsigned short FmState;
unsigned long FmFreq;
bool FmAutoSearchState;
};
char qnd_div1;
char qnd_div2;
char qnd_nco;
char qnd_IsQN8035B;
char qnd_ChipID;
u8 qnd_CH_STEP = 1;
struct fm8035_dev_s *fm8035_reg;
static struct miscdevice fm8035_dev;
u8 qnd_StepTbl[3]={5,10,20};
u8 qnd_AutoScanAll = 0;
u8 qnd_ChCount;
u16 qnd_ChList[QN_CCA_MAX_CH];
static struct class *menual_rearch = NULL; //表示文件节点
/*********************************************************************
FM 收音模块 fm8035 驱动程序 物理层 函数定义.
*********************************************************************/
/**********************************************************************
int QND_Delay()
**********************************************************************
Description: Delay for some ms, to be customized according to user
application platform
Parameters:
ms: ms counts
Return Value:
None
**********************************************************************/
void QND_Delay(u8 ms)
{
mdelay(ms);
}
/*
--------------------------------------------------------------------------------
Function name : fm8035_i2c_set_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
Author :
Description : 设置rda8035 内部寄存器
Input : client -- I2C设备指针
reg -- 要设置的寄存器位
Return :
History: <author> <time> <version>
desc: ORG
--------------------------------------------------------------------------------
*/
int fm8035_i2c_set_regs(struct i2c_client *client, u16 reg, u8 val)
{
int err,cnt;
u8 buf[2];
struct i2c_msg msg[1];
buf[0] = reg & 0xFF;
buf[1] = val;
msg->addr = client->addr;
msg->flags = client->flags;
msg->buf = buf;
msg->len = sizeof(buf);
msg->scl_rate = QN8035_I2C_SPEED;
msg->read_type = 0;
cnt = 3;
err = -EAGAIN;
while ((cnt-- > 0) && (err < 0)) {
err = i2c_transfer(client->adapter, msg, 1);
if (err >= 0) {
return 0;
} else {
udelay(10);
}
}
return err;
}
/*
--------------------------------------------------------------------------------
Function name : fm8035_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
Author :
Description : 读取fm8035 内部寄存器
Input : client -- I2C设备指针
reg -- 要设置的寄存器
Return :
History: <author> <time> <version>
desc: ORG
--------------------------------------------------------------------------------
*/
u8 fm8035_i2c_read_regs( struct i2c_client *client,u8 reg)
{
int err,cnt;
u8 buf[1];
struct i2c_msg msg[2];
u8 *val;
buf[0] = reg & 0xFF;
msg[0].addr = client->addr;
msg[0].flags = client->flags;
msg[0].buf = buf;
msg[0].len = sizeof(buf);
msg[0].scl_rate = QN8035_I2C_SPEED;
msg[0].read_type = 2;
msg[1].addr = client->addr;
msg[1].flags = client->flags|I2C_M_RD;
msg[1].buf = buf;
msg[1].len = 1;
msg[1].scl_rate = QN8035_I2C_SPEED;
msg[1].read_type = 2;
cnt = 3;
err = -EAGAIN;
while ((cnt-- > 0) && (err < 0)) {
err = i2c_transfer(client->adapter, msg, 2);
if (err >= 0) {
*val = buf[0];
return *val;
} else {
udelay(10);
}
}
return err;
}
/*
--------------------------------------------------------------------------------
Function name : fm8035_i2c_set_regs_bit(struct i2c_client *client, u16 reg, u8 bit_Mask, u8 data_val)
Author :
Description : 设置fm8035对应寄存器的bit_Mask位的值为data_val
Input : client -- I2C设备指针
reg -- 要设置的寄存器
Return :
History: <author> <time> <version>
desc: ORG
--------------------------------------------------------------------------------
*/
int fm8035_i2c_set_regs_bit(struct i2c_client *client, u16 reg, u8 bit_Mask, u8 data_val)
{
u8 reg_val;
int ret = 0;
reg_val = fm8035_i2c_read_regs(client, reg);
reg_val &= (u8)(~bit_Mask);
reg_val |= data_val & bit_Mask;
ret = fm8035_i2c_set_regs(client, reg, reg_val);
return ret;
}
/*********************************************************************
FM 收音模块 fm8035 驱动程序 接口函数 定义.
*********************************************************************/
/**********************************************************************
void QNF_RXInit()
**********************************************************************
Description: set to SNR based MPX control. Call this function before
tune to one specific channel
Parameters:
None
Return Value:
None
**********************************************************************/
void QNF_RXInit(struct i2c_client *client)
{
fm8035_i2c_set_regs_bit(client,0x1b,0x08,0x00); //Let NFILT adjust freely
fm8035_i2c_set_regs_bit(client,0x2c,0x3f,0x12);
fm8035_i2c_set_regs_bit(client,0x1d,0x40,0x00);
fm8035_i2c_set_regs_bit(client,0x41,0x0f,0x0a);
fm8035_i2c_set_regs(client,0x45,0x50);
fm8035_i2c_set_regs_bit(client,0x3e,0x80,0x80);
fm8035_i2c_set_regs_bit(client,0x41,0xe0,0xc0);
if(qnd_ChipID == CHIPSUBID_QN8035A0)
{
fm8035_i2c_set_regs_bit(client,0x42,0x10,0x10);
}
}
/**********************************************************************
void QNF_SetMute(u8 On)