瑞芯微Rockchip开发者社区
登录
直播中
莫联雪
7年用户
1152经验值
私信
关注
[问答]
RK3368 QN8027 FM发射驱动代码该怎样去实现呢
开启该帖子的消息推送
QN8027
驱动
RK3368 QN8027 FM发射驱动代码该怎样去实现呢?
回帖
(1)
姜钰
2022-2-10 14:35:43
之前在做车机相关项目,有FM发射需求,8027这颗芯片,之前大部分都是在单片机使用,很少在linux系统使用,我把他移植成了linux驱动,以下为参考:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "QN8027.h"
#define QN8027_I2C_NAME "QN8027"
#define QN8027_I2C_ADDR 0x58
#define QN8027_DEV_NAME "QN8027"
static int qn8027_fm_write(struct i2c_client *client, u8 addr, u8 *pdata, int datalen);
static int qn8027_fm_read(struct i2c_client *client, u8 addr, u8 *pdata, unsigned int datalen);
void QNF_SetRegBit(struct i2c_client *client,u8 reg, u8 bitMask, u8 data_val) ;
u16 QNF_GetCh(struct i2c_client *client) ;
void QN_ChipInitialization(struct i2c_client *client);
UINT8 QNF_SetCh(struct i2c_client *client,u16 freq) ;
void QN_ChipInitialization(struct i2c_client *client);
static struct i2c_client *Gol_client;
struct proc_dir_entry *qn8027_extend_dir;
extern void es8316_spk_ctrl(int level);
static int qn8027_fm_write(struct i2c_client *client, u8 addr, u8 *pdata, int datalen)
{
int ret = 0;
u8 tmp_buf[128];
unsigned int bytelen = 0;
if (datalen > 125)
{
printk("%s too big datalen = %d!n", __func__, datalen);
return -1;
}
tmp_buf[0] = addr;
bytelen++;
if (datalen != 0 && pdata != NULL)
{
memcpy(&tmp_buf[bytelen], pdata, datalen);
bytelen += datalen;
}
ret = i2c_master_send(client, tmp_buf, bytelen);
return ret;
}
static int qn8027_fm_read(struct i2c_client *client, u8 addr, u8 *pdata, unsigned int datalen)
{
int ret = 0;
if (datalen > 126)
{
printk("%s too big datalen = %d!n", __func__, datalen);
return -1;
}
ret = qn8027_fm_write(client, addr, NULL, 0);
if (ret < 0)
{
printk("%s set data address fail!n", __func__);
return ret;
}
return i2c_master_recv(client, pdata, datalen);
}
void QNF_SetRegBit(struct i2c_client *client,u8 reg, u8 bitMask, u8 data_val)
{
u8 temp;
int ret;
ret= qn8027_fm_read(client,reg,&temp,sizeof(temp));
temp &= (u8)(~bitMask);
temp |= data_val & bitMask;
qn8027_fm_write(client, reg, &temp, 1);
}
UINT8 QNF_SetCh(struct i2c_client *client,u16 freq)
{
// calculate ch parameter used for register setting
UINT8 tStep;
UINT8 tCh;
UINT16 f;
f = FREQ2CHREG(freq);
// set to reg: CH
tCh = (UINT8) f;
qn8027_fm_write(client,CH, &tCh,1);
// set to reg: CH_STEP
qn8027_fm_read(client,CH_STEP,&tStep,1);
tStep &= ~CH_CH;
tStep |= ((UINT8) (f >> 8) & CH_CH);
qn8027_fm_write(client,CH_STEP, &tStep,1);
return 1;
}
u16 QNF_GetCh(struct i2c_client *client)
{
u8 tCh;
u8 tStep;
u16 ch = 0;
// set to reg: CH_STEP
qn8027_fm_read(client,CH_STEP,&tStep,1);
tStep &= CH_CH;
printk("Step &= CH_CH; ==== %dn",tStep);
ch = tStep ;
printk(" ch = tStep ; ==== %dn",ch);
qn8027_fm_read(client,CH,&tCh,1);
printk(" ch = tCh ; ==== %dn",tCh);
ch = (ch<<8)+tCh;
printk("(ch<<8)+tCh; ==== %dn",ch);
return CHREG2FREQ(ch);
}
void QN_ChipInitialization(struct i2c_client *client)
{
u8 write_buf;
u8 read_buf;
int ret = 0;
//write_buf = 0x81;
//ret = qn8027_fm_write(client, 0x00, &write_buf, 1);
//msleep(200);
write_buf = 0x20;
ret = qn8027_fm_write(client, 0x03, &write_buf, 1);
msleep(200);
write_buf = 0x21;
ret = qn8027_fm_write(client, 0x04, &write_buf, 1);
msleep(200);
QNF_SetRegBit(client,0x00,0x40,0x40);
msleep(200); //delay 20 ms
write_buf = 0xe4;
ret = qn8027_fm_write(client, 0x18, &write_buf, 1);
msleep(200);
write_buf = 0xf0;
qn8027_fm_write(client, 0x1b, &write_buf, 1);
msleep(200);
write_buf = 0xB9;
ret = qn8027_fm_write(client, 0x02, &write_buf, 1);
msleep(200);
write_buf = 0x20;
ret = qn8027_fm_write(client, 0x00, &write_buf, 1);
ret= qn8027_fm_read(client,0x00,&read_buf,sizeof(read_buf));
printk("intqn8027_fm_read ===================== %xn",read_buf);
}
static int qn8027_fm_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ch;
int ret = 0;
u8 write_buf;
QN_ChipInitialization(client);
ch = QNF_GetCh(client);
Gol_client = client;
printk("qn8027 ch ========================= %dn",ch);
return 0;
}
static int qn8027_fm_remove(struct i2c_client *client)
{
printk("qn8027_fm_remove ========================= n");
return 0;
}
static int qn8027_open(struct inode *inode, struct file *file)
{
return nonseekable_open(inode, file);
}
static int qn8027_release(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t qn8027_read(struct file *file, char __user * usr_buf, size_t len, loff_t * f_pos)
{
int ch = 0;
ch = QNF_GetCh(Gol_client);
copy_to_user(usr_buf,&ch,1);
printk("qn8027_read =================== %dn",ch);
return 0;
}
static ssize_t qn8027_write(struct file *file, const char __user * usr_buf, size_t len, loff_t * f_pos){
char fm_buf[40];
copy_from_user(&fm_buf,usr_buf,len);
QNF_SetCh(Gol_client,10000);
printk("qn8027_write ===================n");
return len;
}
static ssize_t qn8027_proc_write(struct file *file, const char __user *usr_buf,
size_t count, loff_t *pos){
char fm_buf[40];
int value;
char write_buf;
copy_from_user(&fm_buf,usr_buf,count);
fm_buf[count] = '