打印

AM335X移植SDIO WIFI的简易教程

[复制链接]
5213|86
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zjtech|  楼主 | 2017-3-18 21:43 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
最近应一个朋友邀请,帮他移植了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下载地址:
OS下载地址:
12.04是比较古老的系统了,官网已经没有下载连接了。可以到我的网盘去下载。

先说说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



相关帖子

沙发
suzhanhua| | 2017-3-18 22:24 | 只看该作者
有移植好的工程文件吗?

使用特权

评论回复
板凳
suzhanhua| | 2017-3-18 22:25 | 只看该作者
在beaglebone上能够使用这个wifi模块吗?

使用特权

评论回复
地板
zhangmangui| | 2017-3-18 22:42 | 只看该作者
感谢分享     求带

使用特权

评论回复
5
zjtech|  楼主 | 2017-3-19 09:04 | 只看该作者
suzhanhua 发表于 2017-3-18 22:24
有移植好的工程文件吗?

这里不能上传url,我看一下提取出来

使用特权

评论回复
6
zjtech|  楼主 | 2017-3-19 09:09 | 只看该作者
应朋友要求上传了arch/arm/mach-omap2/board-am335xevm.c的源文件,里面有些注释或屏蔽的代码请忽略。

board-am335xevm.zip

18.41 KB

使用特权

评论回复
7
mmbs| | 2017-3-19 14:59 | 只看该作者
这个嵌入式的开发教程。

使用特权

评论回复
8
mmbs| | 2017-3-19 15:03 | 只看该作者
这个驱动程序可以在其他芯片移植吗?

使用特权

评论回复
9
zjtech|  楼主 | 2017-3-19 21:01 | 只看该作者
mmbs 发表于 2017-3-19 15:03
这个驱动程序可以在其他芯片移植吗?

当然可以啊。

使用特权

评论回复
10
ghuca| | 2017-3-20 13:04 | 只看该作者
linux的开发的吗

使用特权

评论回复
11
ghuca| | 2017-3-20 13:06 | 只看该作者
linux不会移植这个驱动程序

使用特权

评论回复
12
zjtech|  楼主 | 2017-3-20 18:51 | 只看该作者
ghuca 发表于 2017-3-20 13:06
linux不会移植这个驱动程序

是linux,其实android也差不多。

使用特权

评论回复
13
lzmm| | 2017-4-1 22:13 | 只看该作者
AM335X移植SDIO WIFI学习。

使用特权

评论回复
14
lzmm| | 2017-4-1 22:17 | 只看该作者
这个在linux集成的wifi驱动了吗?

使用特权

评论回复
15
chenci2013| | 2017-4-2 10:56 | 只看该作者
beagle bone 开发板也可以吗

使用特权

评论回复
16
chenci2013| | 2017-4-2 10:57 | 只看该作者
这个借口没有做过,不需要修改内部的驱动吗?

使用特权

评论回复
17
mituzu| | 2017-4-2 21:51 | 只看该作者
这个开发平台是自己编译的吗

使用特权

评论回复
18
mituzu| | 2017-4-2 21:52 | 只看该作者
以前都是使用360wifi,自动识别。

使用特权

评论回复
19
yujielun| | 2017-4-3 22:22 | 只看该作者
这个可以借鉴使用,应该自带wifi吧

使用特权

评论回复
20
yujielun| | 2017-4-3 22:25 | 只看该作者
linux的usb驱动不好设计,只会简单的字符串驱动。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

53

帖子

8

粉丝