最近应一个朋友邀请,帮他移植了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. Linux学习笔记之Linux最小化安装启动后如何配置

    在VM虚拟机中安装CentOS 7 时 有时候顾虑到电脑硬件性能,我们需要最小化安装,而最小化安装后与centos6的版本是有一些差异的,接下来我们就对刚安装好的最小化centos7做一些操作,来世我 ...

  2. 20145204 《Java程序设计》第2周学习总结

    20145204 <Java程序设计>第2周学习总结 教材学习内容总结 在第三章主要学习了Java语言中的类型及其变量主要类型为:整数(1字节的byte,2字节的short,4字节的int ...

  3. 如何使用AngularJS对表单提交内容进行验证

    AngularJS是一款优秀的前端JS框架,已经被用于Google的多款产品当中.它有着诸多特性,最为核心的是:MVC.模块化.自动化双向数据绑定.语义化标签.依赖注入等……使用它可以大大减少书写代码 ...

  4. Python3基础 三元运算符 简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  5. linux 查看数据库和表

    mysql -h localhost -u 用戶名 -p密碼                //連接數據庫use desk_show;                                 ...

  6. bzoj 1799: [Ahoi2009]self 同类分布 数位dp

    1799: [Ahoi2009]self 同类分布 Time Limit: 50 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Descripti ...

  7. python 列表求和

    def sum_list(items): sum_numbers = for x in items: sum_numbers += x return sum_numbers print(sum_lis ...

  8. 微信小程序登录,获取code,获取openid,获取session_key

    微信小程序登录 wx.login(Object object) 调用接口获取登录凭证(code).通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session ...

  9. JSP 点击量统计

    JSP 点击量统计 有时候我们需要知道某个页面被访问的次数,这时我们就需要在页面上添加页面统计器,页面访问的统计一般在用户第一次载入时累加该页面的访问数上. 要实现一个计数器,您可以利用应用程序隐式对 ...

  10. 数据模板--DataTemplate

    DataTemplate 的 "DataType" 通常就是 “ViewModel” ——视图模型(亦可不恰当称之为:数据模型) <DataTemplate DataType ...