最近应一个朋友邀请,帮他移植了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. Centos75下samba搭建配置

    工作中,很经常需要把Linux服务器上的文件共享到windows上面,这时候需要在Linux服务器上安装samba套件. samba服务很好的实现了windows和linux之间的文件共享. 下面配置 ...

  2. 《Java程序设计》第四章-认识对象

    20145221<Java程序设计>第四章-认识对象 总结 教材学习内容总结 类与对象 定义:对象是Java语言中重要的组成部分,之前学过的C语言是面向过程的,而Java主要是面向对象的. ...

  3. windows下利用批处理命令生成maven项目(java、javaWeb)

    觉得用IDE生成maven项目会卡住,很慢.就用cmd写了个cmd批处理命令来生成maven项目.效果如下 生成项目导入idea后结构如下 批处理命令代码如下 @echo off ::echo 请选择 ...

  4. Tensorflow一些常用基本概念与函数(二)

    1.tensorflow的基本运作 为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始: import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf. ...

  5. Rails 5 Test Prescriptions 第5章 Testing Models

    Rails,model层包含业务逻辑和储存逻辑.其中储存逻辑被ActiveRecord处理. 在model中,不是每件事都必须是ActiveRecord对象.model layer可以包含各种服务,对 ...

  6. ActiveStorage Overview --Rails guide (history:7-1更新)

    如何attach一个或多个文件到一个记录.has_many_attach()方法. 如何删除一个附加的文件. purge方法 如何连接到一个附加的文件.url_for() 如何使用variants来转 ...

  7. Rails 5 Test Prescriptions 倒数第2章spring gem 如何让测试变快。分离rails(只有原理)

    Spring speeds up development by keeping your application running in the background Rails程序自动增加:sprin ...

  8. Linux命令详解-whatis

    描述一个命令执行什么功能. 1.命令格式: whatis [ -M PathName ] Command ... 2.命令功能: 描述一个命令执行什么功能. 3.命令参数:     -M PathNa ...

  9. DBMS_LOB的简单用法以及释放DBMS_LOB生成的临时CLOB内存

    dbms_lob包(一) dbms_lob包(二) 如何释放DBMS_LOB.CREATETEMPORARY的空间 Temporary LOB导致临时表空间暴满. oracle数据库中的大对象1——永 ...

  10. 331. Verify Preorder Serialization of a Binary Tree -- 判断是否为合法的先序序列

    One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, ...