蓝牙配电文件分析

来源:互联网 发布:spss数据结果分析报告 编辑:程序博客网 时间:2024/05/16 23:47

1,首先分析

Msm_bluetooth_power_init()初始化函数

该函数中首先确认reset脚。

Gpio_bt_config()

主要设置gpio_bt_sys_reset_en=BT_RST;

(与实际连接一致)

然后注册i2c设备体bahama_device

该设备体包含了fm的配电和bt重要的寄存器部分。

最后注册平台设备msm_bt_power_device,该设备体名称bt_power,该设备的平台数据platform_data=&Bluetooth_power,实现蓝牙的上电。

 

2,关于bahama_device

Static struct i2c_board_info bahama_devices[] = {       I2C_BOARD_INFO(“marimba”,0x0c),       .platform = &marimba_pdata,}


 

I2c结构体方便注册到系统中,提供i2c读写函数。

 

Static struct marimba_platform_data marimba_pdata = {       .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,       .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMEBIST_,       .bahama_setup = msm_bahama_setup_power,       .bahama_shutdown = msm_bahama_shutdown_power,       .bahama_core_config = msm_bahama_core_config,       .fm = &marimba_fm_pdata,}


Marimba_pdata结构体包括了fm的地址,以及该结构体的电源开关,核心配置。

电源开关控制msm_bahama_setup_powe包括申请“msme1”电压,reset脚拉高。

msm_bahama_core_config判断参数为BAHAMA_ID时,i2c写寄存器参数。Reset拉低。

 

Static struct marimba_fm_platform_data marimba_fm_data = {       .fm_Setup = fm_radio_setup,       .fm_shutdown = fm_radio_shutdown,       .irq = MSM_GPIO_TO_IRQ(FM_GPIO),       …       .is_fm_soc_i2s_master = true,       .config_i2s_gpio = msm_bahama_setup_pcm_i2s,}


fm_radio_setup主要实现设置1.8v电压,申请时钟TCXO_D1reset设置为1reset后写FM slave地址,配置FM中断为input模式。

  

3,蓝牙上电配置函数作为注册设备体的平台数据 

 

static int bluetooth_power(int on){       int pin, rc = 0;       const char *id = "BTPW";       int cid = 0;        cid = adie_get_detected_connectivity_type();       if (cid != BAHAMA_ID) {              pr_err("%s: unexpected adie connectivity type: %d\n",                                   __func__, cid);              return -ENODEV;       }       if (on) {              /*setup power for BT SOC*/ // BT SOC上电              rc = bt_set_gpio(on);  //rest pin置1              if (rc) {                     pr_err("%s: bt_set_gpio = %d\n",                                   __func__, rc);                     goto exit;              }              rc = bluetooth_switch_regulators(on);//申请2.85v电压              if (rc < 0) {                     pr_err("%s: bluetooth_switch_regulators rc = %d",                                   __func__, rc);                     goto exit;              }              /*setup BT GPIO lines*///串口线配置              for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on);                     pin++) {                     rc = gpio_tlmm_config(bt_config_power_on[pin],                                   GPIO_CFG_ENABLE);                     if (rc < 0) {                            pr_err("%s: gpio_tlmm_config(%#x)=%d\n",                                          __func__,                                          bt_config_power_on[pin],                                          rc);                            goto fail_power;                     }              }              /*Setup BT clocks*///申请TCXO_D1时钟              rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,                     PMAPP_CLOCK_VOTE_ON);              if (rc < 0) {                     pr_err("Failed to vote for TCXO_D1 ON\n");                     goto fail_clock;              }              msleep(20);               /*I2C config for Bahama*///bahama_bt二维数组代表了fm和bt不同的开关状态,通过i2c写寄存器和值实现。              rc = bahama_bt(1);              if (rc < 0) {                     pr_err("%s: bahama_bt rc = %d", __func__, rc);                     goto fail_i2c;              }              msleep(20);               /*setup BT PCM lines*///获取bt和fm状态,设置对应pcm和i2s状态。              rc = msm_bahama_setup_pcm_i2s(BT_PCM_ON);              if (rc < 0) {                     pr_err("%s: msm_bahama_setup_pcm_i2s , rc =%d\n",                            __func__, rc);                            goto fail_power;                     }              rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,                              PMAPP_CLOCK_VOTE_PIN_CTRL);              if (rc < 0)                     pr_err("%s:Pin Control Failed, rc = %d",                                   __func__, rc);        } else {              rc = bahama_bt(0);              if (rc < 0)                     pr_err("%s: bahama_bt rc = %d", __func__, rc);               rc = msm_bahama_setup_pcm_i2s(BT_PCM_OFF);              if (rc < 0) {                     pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",                            __func__, rc);              }              rc = bt_set_gpio(on);              if (rc) {                     pr_err("%s: bt_set_gpio = %d\n",                                   __func__, rc);              }fail_i2c:              rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,                              PMAPP_CLOCK_VOTE_OFF);              if (rc < 0)                     pr_err("%s: Failed to vote Off D1\n", __func__);fail_clock:              for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off);                     pin++) {                     rc = gpio_tlmm_config(bt_config_power_off[pin],                            GPIO_CFG_ENABLE);                     if (rc < 0) {                            pr_err("%s:"                                   " gpio_tlmm_config(%#x)=%d\n",                                   __func__,                                   bt_config_power_off[pin], rc);                     }              }fail_power:              rc = bluetooth_switch_regulators(0);              if (rc < 0) {                     pr_err("%s: switch_regulators : rc = %d",\                            __func__, rc);                     goto exit;              }             }       return rc;exit:       pr_err("%s: failed with rc = %d", __func__, rc);       return rc;}


4.该函数被bluetooth_power直接调用,因此不对fm方面的处理判断,fm状态开着的话,该函数不起作用。

Fm开的话,打开i2s,如果fm关,则判断蓝牙状态,蓝牙状态开,则保持pcm开,蓝牙状态关,直接执行关模式。

static int msm_bahama_setup_pcm_i2s(int mode){       int fm_state = 0, bt_state = 0;       int rc = 0;       struct marimba config = { .mod_id =  SLAVE_ID_BAHAMA};
//SLAVE_ID_BAHAMA定义在drivers/mfd/marimba.h中 #define SLAVE_ID_BAHAMA 0x05//获取bt和fm状态       fm_state = marimba_get_fm_status(&config);       bt_state = marimba_get_bt_status(&config);        switch (mode) {       case BT_PCM_ON:       case BT_PCM_OFF:              if (!fm_state)                     rc = config_pcm(mode);              break;       case FM_I2S_ON:              rc = config_i2s(mode);              break;       case FM_I2S_OFF:              if (bt_state)                     rc = config_pcm(BT_PCM_ON);              else                     rc = config_i2s(mode);              break;       default:              rc = -EIO;              pr_err("%s:Unsupported mode", __func__);}}