最近应一个朋友邀请,帮他移植了SDIO WIFI到3.2版本内核。因为之前已经成功移植了3.14内核,所以整个过程花了一个下午就完成了。
话不多说,先交待一下平台:

CPU:TI AM3352 600M
OS:ubuntu core 12.04 for arm
SDK版本:TI SDK 06.00.00(非常老的一个版本,但比较稳定。也是比较通用的工业核心板自带系统)
内核版本:3.2.0(SDK 06.00.00自带)
SDIO WIFI:RTL8189e WIFI模块

AM335xSDK 06_00_00_00下载地址:
http://software-dl.ti.com/sitara_linux/esd/AM335xSDK/06_00_00_00/index_FDS.html
OS下载地址:
12.04是比较古老的系统了,官网已经没有下载连接了。可以到我的网盘去下载。
http://pan.baidu.com/s/1hskhqdQ

先说说SDIO WIFI移植的通用流程:
1、第一步当然是确认PIN MUX了。一般来说,如下几个PIN(采用4线SDIO)是不能少的。
wlan_en(这个也可以没有,默认拉高就可以)
mmcX_cmd
mmcX_clk
mmcX_data0
mmcX_data1
mmcX_data2
mmcX_data3
注:上面的X是你选用的MMC总线,对335来说可能是0,1,2

2、确认了以上管脚和对应的pin mux后,就可以进入代码修改环节:
AM335在内核中对应的BSP代码位于:
arch/arm/mach-omap2/board-am335xevm.c
先在其中修改或增加一个节点:

/* Module pin mux for wlan and bluetooth */
static struct pinmux_config mmc2_qca9377_pin_mux[] = {
//add by alan for mmc3(mmcblk2)
{"gpmc_oen_ren.gpio2_3", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_clk.mmc2_clk", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_csn3.mmc2_cmd", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad12.mmc2_dat0", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad13.mmc2_dat1", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad14.mmc2_dat2", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad15.mmc2_dat3", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},
{NULL, 0},
};

*****************注:1、本次使用的模块是rtl8189的,模块与9377是pin2pin兼容的,所以就没有改名字
***************** 2、配置完必须检查这里的管脚有没有在其它的地方进行配置,如果有把它们都屏蔽掉。

3、在内核中添加对应的init函数。
static void mmc2_qca9377_init(int evm_id, int profile)
{
setup_pin_mux(mmc2_qca9377_pin_mux);

am335x_mmc[1].mmc = 3;
am335x_mmc[1].name = "rtl8189es";
am335x_mmc[1].caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE | MMC_CAP_SD_HIGHSPEED;
am335x_mmc[1].nonremovable = true;
am335x_mmc[1].gpio_cd = -EINVAL;
am335x_mmc[1].gpio_wp = -EINVAL;
am335x_mmc[1].ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34; /* 3V3 */
/* mmc will be initialized when mmc0_init is called */
return;
}
**************** 注:这里有一个非常容易犯错的地方,这个项目中我们用的mmc总线为2,众所周知AM335x共有三组SDIO,分别是mmc0,mmc1,mmc2
**************** 你们会很惊奇地发现,我们在这里用了am335x_mmc[1],明明是mmc2为什么[]中是1呢?答案是我们在实际应用中没有配置mmc1,所以这里要用1;
**************** 至于"am335x_mmc[1].mmc = 3"中的3代表是的物理的总线位置(mmc0对应1,mmc1对应2,mmc2对应3)

4、添加最为重要的函数,就是mmc的电源管理配置和clock ref
static void wl12xx_init(int evm_id, int profile)
{
struct device *dev;
struct omap_mmc_platform_data *pdata;
int ret;

//配置wlan_en管脚,我们用的是gpio2,3
am335xevm_wlan_data.wlan_enable_gpio = GPIO_TO_PIN(2, 3);

if (wl12xx_set_platform_data(&am335xevm_wlan_data))
pr_err("error setting wl12xx data\n");

//注意这里am335x_mmc[1]中的1原因和步骤3中注释的一样,如果你的情况不同请改掉
dev = am335x_mmc[1].dev;
if (!dev) {
pr_err("wl12xx mmc device initialization failed\n");
goto out;
}

pdata = dev->platform_data;
if (!pdata) {
pr_err("Platfrom data of wl12xx device not set\n");
goto out;
}

ret = gpio_request_one(am335xevm_wlan_data.wlan_enable_gpio,
GPIOF_OUT_INIT_LOW, "wlan_en");
if (ret) {
pr_err("Error requesting wlan enable gpio: %d\n", ret);
goto out;
}

pdata->slots[0].set_power = wl12xx_set_power;
out:
return;
}

//wl12xx_init中用到了下面函数
/* wlan enable pin */
#define AM33XX_CONTROL_PADCONF_GPMC_CSN0_OFFSET 0x087C
static int wl12xx_set_power(struct device *dev, int slot, int on, int vdd)
{
int pad_mux_value;

if (on) {
gpio_direction_output(am335xevm_wlan_data.wlan_enable_gpio, 1);

/* Enable pullup on the WLAN enable pin for keeping wlan active during suspend
in wowlan mode */

mdelay(70);
} else {
gpio_direction_output(am335xevm_wlan_data.wlan_enable_gpio, 0);

}

return 0;
}

5、到这里对bsp的修改就差不多了,剩下一个步骤。确认以上的函数被内核加载。
我们的板子把EEPROM写死成了Starter Kit的配置,如果你的不同,请检查对应的启动序列。
/* EVM - Starter Kit */
static struct evm_dev_cfg evm_sk_dev_cfg[] = {
/******************确认代码中包含如下两项***/
{mmc2_qca9377_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{wl12xx_init, DEV_ON_BASEBOARD, PROFILE_ALL},

6、把模块驱动加入内核中,我们放在drivers/net/wireless/
把rtl8189ES_linux_v4.3.18.2_17395.20160422.tar解压在这里。
由于我们用cfg80211的试来驱动,所以要检查
drivers/net/wireless/rtl8189ES_linux_v4.3.18.2_17395.20160422/include/autoconf.h中宏定义
#define CONFIG_IOCTL_CFG80211
被打开

修改
drivers/net/wireless/Makefile
obj-$(CONFIG_RTL8189ES) += rtl8189ES_linux_v4.3.18.2_17395.20160422/

drivers/net/wireless/Kconfig
source "drivers/net/wireless/rtl8189ES_linux_v4.3.18.2_17395.20160422/Kconfig"

7、配置对应的内核选项:
在内核目录运行make menuconfig(先确认对应的ARCH是否是arm)
确认如下配置:
Networking support->Wireless->cfg80211 - wireless configuration API 配置为<M>
Device Drivers->Network device support->Wireless LAN->Realtek 8189E SDIO WiFi 配置为<M>

8、编译,上机测试(大家用的方法可能都不太一样,如里这里有疑问请对照自己的方法)
make uImage && make modules
将内核和模块放到你的目标板上测试吧。

9、写在最后:
移植SDIO WIFI有几个基本知识,知道后会事半功倍.首先你的SDIO总线要配置正确,如果配置好了在dmesg中能看到类似下面的信息:
mmc2:new high speed SDIO card at address 0001
再就是很多SDIO WIFI是需要fireware的,一般放在/lib/firemware;请留你的dmesg信息。我们用的rtl8189不需要另外的firmware固件。
明白了一个SDIO WIFI的移植方法后,可以举一反三。这样其它的SDIO WIFI也不在话下啦。。。

有兴趣的朋友可以关注一下我的一个开源硬件项目zcore-am335x mini:
资料链接:https://pan.baidu.com/s/1qYJB1Vm 密码:5t5u

相关介绍:http://www.deyisupport.com/question_answer/dsp_arm/sitara_arm/f/25/t/127477.aspx
http://www.eeboard.com/bbs/thread-42233-1-1.html

http://www.deyisupport.com/question_answer/dsp_arm/sitara_arm/f/25/t/127565.aspx

关于AM335X移植SDIO WIFI的简易教程(转)的更多相关文章

  1. [洛谷日报第62期]Splay简易教程 (转载)

    本文发布于洛谷日报,特约作者:tiger0132 原地址 分割线下为copy的内容 [洛谷日报第62期]Splay简易教程 洛谷科技 18-10-0223:31 简介 二叉排序树(Binary Sor ...

  2. 生活科技两相宜:(一)Win7使用微软SkyDrive网盘简易教程

    今天得写一个Win7使用微软SkyDrive网盘的简易教程,主要是给我老婆看,顺便贴出来给大家共享一下:)    使用微软SkyDrive网盘有两个层次.一个是使用网页版,这个跟使用163或者QQ网盘 ...

  3. JavaScript简易教程(转)

    原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...

  4. Emacs简易教程

    Emacs简易教程阅读: 命令: $emacs 进入之后,输入: C-h t 这里,C-h表示按住[Ctrl]键的同时按h ####### 20090620 *退出: 输入“C-x C-c” *撤销: ...

  5. 为AM335x移植Linux内核主线代码

    /********************************************************************** * 为AM335x移植Linux内核主线代码 * 说明: ...

  6. 文件上传利器SWFUpload入门简易教程

    凡做过网站开发的都应该知道表单file的确鸡肋. Ajax解决了不刷新页面提交表单,但是却没有解决文件上传不刷新页面,当然也有其它技术让不刷新页面而提交文件,该技术主要是利用隐藏的iFrame, 较A ...

  7. 【转】Delphi内嵌ASM简易教程

    Delphi内嵌ASM简易教程 作者:heiying2006-03-19 18:33分类:默认分类标签: 前言 Delphi作为一个快速高效的开发平台,使用的人越来越多,但熟悉在Delphi代码中嵌入 ...

  8. Ant 简易教程

    转载:http://www.cnblogs.com/jingmoxukong/p/4433945.html Ant 简易教程 Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动 ...

  9. Intellj IDEA 简易教程

    Intellj IDEA 简易教程 目录 JDK 安装测试 IDEA 安装测试 调试 单元测试 重构 Git Android 其他 参考资料 Java开发IDE(Integrated Developm ...

随机推荐

  1. ESXi上的固态硬盘识别为非SSD

    启动ESXi的SSH服务 通过SSH远程连接ESXi主机 输入如下命令 # esxcli storage nmp device list        #列出储存清单(SSD设备的“device na ...

  2. [BZOJ2834]回家的路

    Description Input Output Sample Input 2 1 1 2 1 1 2 2 Sample Output 5   思路还是很简单的,然而最短路打错各种对拍各种调了一早上 ...

  3. install flask

    pip install flask -i http://pypi.douban.com/simple

  4. css3 抖动

    1. html <div id="wrapper"> <section> <p class="shake freez shake-hard& ...

  5. 最全Python内置函数

    内置函数的基本使用 abs的使用: 取绝对值 absprint(abs(123))print(abs(-123)) result:123123 all的使用: 循环参数,如果每个元素都为真的情况下,那 ...

  6. Linux CentOS 6.5 使用自带jdk修改环境变量

    首先声明,默认jdk指我们安装完CentOS后系统自带jdk,自己下载安装的jdk只需要下载,解压即可,之后步骤与此文一致 1.查看我们默认jdk的位置 指令: which java 我们去看一下发现 ...

  7. HDU1598 并查集+贪心

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  8. UVA-11082 Matrix Decompressing (网络流建模)

    题目大意:给出一个由1到20组成的整数矩阵的每一行和每一列的和,构造这个矩阵.输出任意一个构造方案. 题目分析:将每一行视作一个点x,将每一列视作一个点y.对于矩阵中的每一个格子,都对应一个二元关系& ...

  9. python 字符串、列表、字典相关内建方法

    """字符串相关内建方法""" # a = ["qwe", "name", "sex&qu ...

  10. BZOJ1228 [SDOI2009]E&D

    蒟蒻不会= = 话说写题解的巨巨也只会打表233 反正先A掉再说 /************************************************************** Pro ...