FM 发射模块QN8027软件android 5.1实现分析
一,kernel层中的驱动:(主要为厂家提供,主要配置对应的I2C口线)
由三个文件组成:
1, Makefile /*驱动的编译文件,让该驱动被编译到内核中去*/
2, qn8027.c /*驱动的源文件,厂家提供,具体实现不分析,这里主要关注如何与JAVA层的通讯*/
3, qn8027.h /*驱动头文件,厂家提供。定义通讯的IO*/
Makefile文档:
include $(srctree)/drivers/misc/mediatek/Makefile.custom
obj-y += qn8027.o
qn8027.c文档:
#include<linux/disp_assert_layer.h>
#include<linux/miscdevice.h>
#include<linux/fs.h>
#include<linux/file.h>
#include<linux/cdev.h>
#include<asm/tlbflush.h>
#include<asm/page.h>
#include<linux/slab.h>
//#include<linux/autoconf.h>
#include<linux/module.h>
#include<linux/mm.h>
#include<linux/init.h>
#include<linux/fb.h>
#include<linux/delay.h>
#include<linux/device.h>
#include<linux/platform_device.h>
#include<linux/dma-mapping.h>
#include<linux/earlysuspend.h>
#include<linux/kthread.h>
#include<linux/rtpm_prio.h>
#include<asm/uaccess.h>
#include<asm/atomic.h>
#include<asm/mach-types.h>
#include<asm/cacheflush.h>
#include<asm/io.h>
#include<mach/dma.h>
#include<mach/irqs.h>
#include<linux/vmalloc.h>
#include<mach/mt_gpio.h>
#include"cust_gpio_usage.h"
#include"qn8027.h"
staticsize_t qn8027_iic_log_on = false;
#defineQN8027_IIC_LOG(fmt, arg...) \
do { \
if (qn8027_iic_log_on){printk("[qn8027]%s,#%d ", __func__, __LINE__); printk(fmt, ##arg);}\
}while (0)
#defineQN8027_IIC_FUNC() \
do { \
if(qn8027_iic_log_on)printk("[qn8027] %s\n", __func__); \
}while (0)
/*----------------------------------------------------------------------------*/
// qn8027device information
/*----------------------------------------------------------------------------*/
#defineMAX_TRANSACTION_LENGTH 8
#defineQN8027_DEVICE_NAME "FMtransmitter"
#defineQN8027_I2C_SLAVE_ADDR 0x58
#defineIIC_BUSNUM 2
#defineGPIO_EN_QN8027_PIN (GPIO31 |0x80000000)
/*EINT_AMP Y23 */
#defineGPIO_SPEAKER_EN_PIN (GPIO88| 0x80000000)
staticbool QN8027_FLAG = FALSE;
externbool accdet_plug_state();
/*----------------------------------------------------------------------------*/
staticint qn8027_i2c_probe(struct i2c_client *client, const struct i2c_device_id*id);
staticint qn8027_i2c_remove(struct i2c_client *client);
staticstruct i2c_client *qn8027_i2c_client = NULL;
staticconst struct i2c_device_id qn8027_i2c_id[] = { {QN8027_DEVICE_NAME,0},{}};
staticstruct i2c_board_info __initdata i2c_qn8027 = {I2C_BOARD_INFO(QN8027_DEVICE_NAME, (QN8027_I2C_SLAVE_ADDR>>1))};
externvoid set_pwm(int vol);
/*----------------------------------------------------------------------------*/
structi2c_driver qn8027_i2c_driver = {
.probe = qn8027_i2c_probe,
.remove = qn8027_i2c_remove,
.driver = { .name = QN8027_DEVICE_NAME,},
.id_table = qn8027_i2c_id,
};
structqn8027_i2c_data {
struct i2c_client *client;
uint16_t addr;
int use_reset; //use RESET flag
int use_irq; //use EINT flag
int retry;
};
staticstruct qn8027_i2c_data *obj_i2c_data = NULL;
boolqn8027_status()
{
return QN8027_FLAG;
}
EXPORT_SYMBOL(qn8027_status);
/*----------------------------------------------------------------------------*/
intqn8027_i2c_read(u16 addr, u32 *data)
{
u8 rxBuf[1] = {0};
int ret = 0;
struct i2c_client *client = qn8027_i2c_client;
u8 lens;
client->addr = (client->addr &I2C_MASK_FLAG);
client->timing = 400;
client->ext_flag = I2C_WR_FLAG;
rxBuf[0] = addr;
lens = 1;
ret = i2c_master_send(client,&rxBuf[0], (1 << 8) | lens);
if (ret < 0)
{
QN8027_IIC_LOG("qn8027_i2c_read reg[0x%X] fail, Error code [0x%X]\n", addr, ret);
return -EFAULT;
}
//ret = i2c_master_recv(client,&rxBuf[0], 0x1);
*data = rxBuf[0];
QN8027_IIC_LOG("qn8027_i2c_readreg[0x%X] = 0x%X\n", addr, rxBuf[0]);
return 0;
}
/*----------------------------------------------------------------------------*/
EXPORT_SYMBOL_GPL(qn8027_i2c_read);
/*----------------------------------------------------------------------------*/
intqn8027_i2c_write(u16 addr, u32 data)
{
struct i2c_client *client =qn8027_i2c_client;
u8 buffer[8];
u8 write_data[2] = {0};
int ret = 0;
struct i2c_msg msg =
{
.addr = client->addr &I2C_MASK_FLAG,
.flags = 0,
.len = 2,
.buf = write_data,
.timing = 400,
};
write_data[0] = addr;
write_data[1] = data;
//ret = i2c_master_send(client,write_data, 0x2);
ret = i2c_transfer(client->adapter,&msg, 1);
if (ret < 0)
{
QN8027_IIC_LOG("qn8027_write reg[0x%X] fail, Error code [0x%X]\n", addr, ret);
return -EFAULT;
}
QN8027_IIC_LOG("[QN8027]qn8027_i2c_write reg[0x%X] = 0x%X\n", addr, data);
return 0;
}
/*----------------------------------------------------------------------------*/
EXPORT_SYMBOL_GPL(qn8027_i2c_write);
voidqn8027_reg_init()
{