Android移植之WIFI

 

1. 前言

   硬件平臺:marvel 310

       軟件平臺:maemo4

       內核:2.6.28(經過marvel的移植)

2. 移植思想

1,  WIFI模塊本身和cpu之間的接口;

       我們的模塊和cpu之間的接口是sdio的,也就是說必須要先保證SDIO本身是工作的;

2,  WIFI模塊本身的上電時序;

       模塊都有它自己的規律,所以必須要根據spec瞭解它本身的上電過程,嚴格遵守;

3,  以太網接口的創建;

       我們的WIFI模塊本身是建立在SDIO口之上的,而對上都是提供以太網接口的,所以必須要保證這個接口以及創建;

4,  特殊處理;

       不同的模塊都有它特別的地方,比如我們用的是8686compo也就是說它和藍牙共用天線,所以需要在初始化的時候做特殊的處理,發送特殊的命令,才能工作;

3. 移植過程

1,  sdio本身是通過gpio口模擬的,所以需要對gpio口進行配置

       static mfp_cfg_t littleton_mmc3_pins[] = {

       GPIO7_2_MMC3_DAT0,

       GPIO8_2_MMC3_DAT1,

       GPIO9_2_MMC3_DAT2,

       GPIO10_2_MMC3_DAT3,

       GPIO103_MMC3_CLK,

       GPIO105_MMC3_CMD,

       };

       void pxa3xx_enable_mmc3_pins(void)

{

       pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mmc3_pins));

}

       littleton_init()函數裏面添加下面這一行:

       pxa3xx_enable_mmc3_pins();

2,  wifi模塊本身的初始化

#define MFP_WIFI_V18_ENABLE     (GPIO26_GPIO)

#define MFP_WLAN_RESETN                  (GPIO99_GPIO) 

#define WIFI_WAKEUP_HOST          (GPIO104_GPIO) /*error must be changed*/

#define WLAN_ENABLE_PIN          26

#define WLAN_RESET_PIN            99

#define M200_B

#ifdef M200_B

#define BT_RESET_PIN                 EXT1_GPIO(1)

#define BT_RESET_GPIO             (GPIO1_2_GPIO)

#else

#define BT_RESET_GPIO                  (GPIO6_2_GPIO)

#define BT_RESET_PIN                 EXT1_GPIO(6)

#endif

static  mfp_cfg_t lin2008_wifibt_pins[] = {

MFP_WIFI_V18_ENABLE,

MFP_WLAN_RESETN,

WIFI_WAKEUP_HOST,/*wakeup host*/

};

static  mfp_cfg_t lin2008_wifibt_pins2[] = {

MFP_WIFI_V18_ENABLE,

};

static int wifibt_power_status;

int lin2008_poweron_wifibt_board(void) 

{

       if (!wifibt_power_status) {

              pxa3xx_mfp_config(ARRAY_AND_SIZE(lin2008_wifibt_pins));

                                

              gpio_direction_output(WLAN_ENABLE_PIN, 1); 

              gpio_direction_output(WLAN_RESET_PIN, 1); 

                  gpio_direction_output(BT_RESET_PIN,1);

              mdelay(1);

                  gpio_direction_output(BT_RESET_PIN, 0);

                  gpio_direction_output(WLAN_RESET_PIN, 0);

       // bt need > 5 ms to reset

                  mdelay(5);

                  gpio_direction_output(BT_RESET_PIN, 1);

                  gpio_direction_output(WLAN_RESET_PIN, 1);

              wifibt_power_status++;

              return 0;

       }

       wifibt_power_status++;

       return 1;

}

int lin2008_poweroff_wifibt_board(void) 

{

       wifibt_power_status--;

       if (!wifibt_power_status) {

              pxa3xx_mfp_config(ARRAY_AND_SIZE(lin2008_wifibt_pins2));

              gpio_direction_output(WLAN_ENABLE_PIN, 0);

              return 0;

       }

       return 1;

}

3, 以太網接口的創建

       這裏在android平臺上要做特殊的處理,也就是firmware的位置要放好,否則加載firmware始終不成功,那麼以太網接口就不會被創建了;

       需要把helper_sd.bin放在/etc/firmware/下面;

       sd8686.bin放在/etc/firmware/mrvl下面;

4, 特殊的處理

       對於8686模塊需要做特殊的處理,在註冊完以太網接口以後,需要添加下面這段話:

       {

     #define BCA_CFG_NUM_OF_MODES          4

     #define BCA_CFG_SINGLE_ANT_WITH_COEX      0

     #define BCA_CFG_DUAL_ANT_WITH_COEX    1

     #define BCA_CFG_SINGLE_ANT_FOR_BT_ONLY    2

     #define BCA_CFG_MRVL_DEFAULT          3

  

     #define BCA_CONFIG BCA_CFG_SINGLE_ANT_WITH_COEX

     static u32 BCACfgTbl[BCA_CFG_NUM_OF_MODES][3] = {

       //0xA5F0,     0xA58C,  0xA5A0 

       { 0xa027181c, 0x40214, 0xd24d}, //Mode 0: Single ANT with COEX enable

       { 0xa027181c, 0x40211, 0xd24d}, //Mode 1: Dual ANT with COEX enable

       { 0xa027181c, 0x40222, 0xd21c}, //Mode 2: single ANT for BT only

       { 0xa027801d, 0x18000, 0xd21c}, //Mode 3: Marvell default

     };

     

     wlan_offset_value    RegBuffer;     

     

     RegBuffer.offset = (0xA5F0);

     RegBuffer.value  = BCACfgTbl[BCA_CONFIG][0];

     wlan_prepare_cmd(priv,

                     HostCmd_CMD_MAC_REG_ACCESS,

                     HostCmd_ACT_GEN_SET,

                     HostCmd_OPTION_WAITFORRSP,

                     0,&RegBuffer);

  

     RegBuffer.offset =(0xA58C);

     RegBuffer.value  = BCACfgTbl[BCA_CONFIG][1];

     wlan_prepare_cmd(priv,

                     HostCmd_CMD_MAC_REG_ACCESS,

                     HostCmd_ACT_GEN_SET,

                     HostCmd_OPTION_WAITFORRSP,

                     0,&RegBuffer);

  

  

     RegBuffer.offset = (0xA5A0);

     RegBuffer.value  = BCACfgTbl[BCA_CONFIG][2];

     wlan_prepare_cmd(priv,

                     HostCmd_CMD_MAC_REG_ACCESS,

                     HostCmd_ACT_GEN_SET,

                     HostCmd_OPTION_WAITFORRSP,

                     0,&RegBuffer);

}

基本上這樣就可以工作了;

4.              其它問題

              Sdio口默認是用的3.2V這裏需要修改相關的地方強制設成是1.8V,否則SDIO接口將無法工作;

              Android平臺上需要移植一些上層軟件才能驗證,比如iwconfigiwlistwpa_supplicant等。

       測試步驟:

              iwlist mlan0 scan

              如果能掃描到AP那麼證明基本已經OK了;

              wpa_supplicant -Dwext –imlan0 -c/etc/wpa.conf &

              dhcpcd mlan0

              這樣的話,就可以pingIP地址了;

5. 常見問題

1,  WIFI驅動註冊sdio驅動的時候出錯,也就是probe函數未被調用?

       需要檢查sdio設備本身是否被檢測到,內核是通過發送特定的命令來檢測是sdio還是SD卡還是mmc的,

       mmc_rescan函數裏面可以看到sdio設備的加載過程,有可能就是你的電壓設置不對;

2,  以太網接口一直出不來或者說firmware加載失敗?

       這裏需要確保firmware是否正確被加載,很可能是它找不到對應的firmware,可以通過添加打印信息看看,它的路徑到底是在什麼地方,對於wifi來說helper_sd.bin需要放在/etc/firmware/下面,而sd8686.bin需要放在/etc/firmware/mrvl下面;

3,  一切正常,但是調用iwlist mlan0 scan的時候,掃描不到任何結果?

       這時候需要做特殊的處理,比如共存代碼的設置,是否正常等,通常可以判斷有沒有中斷上來,以此區分到底是模塊和cpu的連接問題還是模塊本身的設置問題;

4,  工作一段時間後不正常

       這個有可能是藍牙模塊需要進行初始化,因爲它們是共用天線,有時候不起藍牙模塊對應的40M時鐘就不起來;

6. 後記

       作者:wylhistory

       聯繫方式:[email protected]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章