Bluetooth配電ファイル解析


1、まず分析
Msm_bluetooth_power_Init()初期化関数
この関数ではまずreset脚を確認します.
Gpio_bt_config()
主要設定gpio_bt_sys_reset_en=BT_RST;
(実際の接続と一致)、
次にi 2 cデバイスボディbahama_を登録するdevice.
この装置体はfmの配電とbtの重要なレジスタ部分を含む.
最終登録プラットフォームデバイスmsm_bt_power_デバイス名bt_Power、このデバイスのプラットフォームデータplatform_data=&Bluetooth_Power、Bluetoothの電源投入を実現.
 
2,bahama_についてdevice
Static struct i2c_board_info bahama_devices[] = {

       I2C_BOARD_INFO(“marimba”,0x0c),

       .platform = &marimba_pdata,

}


 
I 2 c構造体はシステムに登録しやすく、i 2 c読み書き関数を提供する.
 
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には「msme 1」電圧の申請が含まれており、reset脚が高くなっています.
msm_bahama_core_config判定パラメータはBAHAMA_IDの場合、i 2 cはレジスタパラメータを書き込みます.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.8 v電圧の設定を実現し、クロックTCXOを申請する.D 1,resetは1に設定し,reset後にFM slaveアドレスを書き,FM割り込みをinputモードに設定する.
  
3,Bluetooth電源配置関数を登録装置体のプラットフォームデータとする
 
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
", __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
", __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
", __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
"); 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
", __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
", __func__, rc); } rc = bt_set_gpio(on); if (rc) { pr_err("%s: bt_set_gpio = %d
", __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
", __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
", __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がオンの場合はi 2 s、fmがオフの場合はBluetooth状態、Bluetooth状態がオンの場合はpcmオン、Bluetooth状態オフのまま、そのままオフモードを実行します.
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__);

	}

}