基于mtk平台调试FM发射芯片KT0805

一个比较简单的i2c设备,原理图如下,

主要是供电,硬件连接好了,软件不需要处理,音频数据是接在耳机模式上AU_HPL,AU_HPR,数据芯片自己接受发射,

软件需要处理的是SW1或者SW2,连接的GPIO,选择不同的频率,简单就是拉高就ok了,硬件已经选择了。然后通过i2c设置FM发射频率。

1、需要给上层提供几个接口,开启和关闭功能,即耳机插入和拨出一样,还有一个就是设置频率功能。

这三个接口都可以通过sys文件系统或者proc文件系统来操作。在使用sys/class文件系统进行echo操作时,居然不能够输入数据,没有搞明白mtk平台为啥不行,我在高通,展讯平台都是可以的,奇怪了,后来只有使用proc文件系统进行echo输入数据。






再到平台相应的关机耳机部分的驱动,在probe中

#ifdef FM_ACCDET_TX//
device_create_file(accdet_nor_device, &dev_attr_fmtransmitter);
//device_create_file(accdet_nor_device, &dev_attr_fmtransmitterfrq);
_create_procfs();
#endif


#ifdef FM_ACCDET_TX




static void accdet_fmtx_enable()
{


//set PWM IDLE  on
pmic_pwrap_write(ACCDET_STATE_SWCTRL, (pmic_pwrap_read(ACCDET_STATE_SWCTRL)|ACCDET_SWCTRL_IDLE_EN));
//enable ACCDET unit
enable_accdet(ACCDET_SWCTRL_EN); 


}
//static ssize_t store_fmtx_disable(struct device_driver *ddri, char *buf, size_t count)


static ssize_t show_fmtx_enable(struct device_driver *ddri, char *buf)


{


//set PWM IDLE  on
pmic_pwrap_write(ACCDET_STATE_SWCTRL, (pmic_pwrap_read(ACCDET_STATE_SWCTRL)|ACCDET_SWCTRL_IDLE_EN));
//enable ACCDET unit
enable_accdet(ACCDET_SWCTRL_EN); 


}
static ssize_t store_fmtx_disable(struct device_driver *ddri, char *buf, size_t count)
//static ssize_t show_fmtx_enable(struct device_driver *ddri, char *buf)


//static ssize_t store_fmtx_disable(struct device *dev,struct device_attribute *attr, const char *buf, size_t size)
//static void store_fmtx_disable()
{

accdet_auxadc_switch(0);
disable_accdet();   
headset_plug_out();

}
 int KTTX_FRQ;
extern int KT_Bus_Read(kal_uint8 addr, kal_uint8 *returnData);
extern int KT_Bus_Write(kal_uint8 addr, kal_uint8 writeData);


void KT_TXTune (int Frequency) // Exemple :91.55MHz---> *Freqency = 9155;
{
char reg1,reg2;
char aa;
Frequency = Frequency / 5;
KT_Bus_Write( 0x00, (Frequency & 0x01FE) >>1);
//reg1 = KT_Bus_Read( 0x01);
KT_Bus_Read( 0x01,&reg1);
printk("======KT_TXTune===reg1=%x\n",reg1);
aa=(reg1 & 0xF8 ) | ((Frequency & 0x0E00) >> 9);
printk("======KT_TXTune===aa=%x\n",aa);
KT_Bus_Write( 0x01, (reg1 & 0xF8 ) | ((Frequency & 0x0E00) >> 9) );
//reg2 = KT_Bus_Read( 0x02);

KT_Bus_Read( 0x01,&reg2);
printk("======KT_TXTune===reg2=%x,Frequency=%x\n",reg2,Frequency);


if ( Frequency & 0x0001) // if frequency = XX.X5 MHz
{
KT_Bus_Write( 0x02, reg2 | 0x80);
}
else
{
KT_Bus_Write( 0x02, reg2 & 0x7F);
}
}


int strtoint(const char *str,int len)
 {
  int result = 0;
  int i = 0;
  char c;
  while(i <= len-1)
  {   
  c = str[i++];
  if(c<'0' || c>'9')
  break;
  result = 10*result + c - '0';
  }
  return result;
 }






static char *_copy_from_user_for_proc(const char __user *buffer, size_t count)
{
    char *buf = (char *)__get_free_page(GFP_USER);


    if (!buf)
        return NULL;


    if (count >= PAGE_SIZE)
        goto out;


    if (copy_from_user(buf, buffer, count))
        goto out;


    buf[count] = '\0';


    return buf;


out:
    free_page((unsigned long)buf);


    return NULL;
}




static DEVICE_ATTR(fmtransmitter,0777, show_fmtx_enable, store_fmtx_disable);
//static DEVICE_ATTR(fmtransmitterfrq,0777, show_fmtxfrq, store_fmtxfrq);


static int accdet_fmtx_proc_show(struct seq_file *m, void *v)
{
    printk("accdet_fmtx_proc_show=====cpufreq debug (log level) KTTX_FRQ= %d\n", KTTX_FRQ);


    return 0;;
}


static ssize_t accdet_fmtx_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
{
    unsigned int dbg_lv;


    char *buf = _copy_from_user_for_proc(buffer, count);


    if (!buf)
        return -EINVAL;


    sscanf(buf, "%d", &dbg_lv);
printk("========accdet_fmtx_proc_write======dbg_lv=%d\n",dbg_lv);
KTTX_FRQ=dbg_lv;
KT_TXTune(dbg_lv);
free_page((unsigned int)buf);
    return count;
}


#define PROC_FOPS_RW(name) \
    static int name ## _proc_open(struct inode *inode, struct file *file) \
{ \
    return single_open(file, name ## _proc_show, NULL); \
} \
static const struct file_operations name ## _proc_fops = { \
    .owner          = THIS_MODULE, \
    .open           = name ## _proc_open, \
    .read           = seq_read, \
    .llseek         = seq_lseek, \
    .release        = single_release, \
    .write          = name ## _proc_write, \
}






#define PROC_ENTRY(name) {__stringify(name), &name ## _proc_fops}


PROC_FOPS_RW(accdet_fmtx);


static int _create_procfs(void)
{
    struct proc_dir_entry *dir = NULL;
    //struct proc_dir_entry *cpu_dir = NULL;
    //struct mt_cpu_dvfs *p = id_to_cpu_dvfs(0);
    int i; //, j;


    struct pentry {
        const char *name;
        const struct file_operations *fops;
    };


    const struct pentry entries[] = {
        PROC_ENTRY(accdet_fmtx),
    };


 


    dir = proc_mkdir("accdetfmtx", NULL);


    if (!dir) {
        printk("fail to_create_procfs------------create /proc/accdetfmtx @ %s()\n", __func__);
        return -ENOMEM;
    }


    for (i = 0; i < ARRAY_SIZE(entries); i++) {
        proc_create(entries[i].name, S_IRUGO | S_IWUSR | S_IWGRP, dir, entries[i].fops);
           printk("%s(), create --------------/proc/accdetfmtx/%s failed\n", __func__, entries[i].name);
    }




    return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值