linux内核开启otg,OTG驱动分析(一)

前一段时间弄了2个礼拜的OTG驱动调试,感觉精神疲惫啊。主要原因还是自己对OTG功能不了解造成的。现在终于完成但是对实质原理还有些模糊。所以自己重新总结一下。因为自己是菜鸟,所以用菜鸟的白话方式分析。高手滤过吧。所谓OTG功能就是具备该功能的设备即可当主设备(host)去轮询别人,也可以当从设备(device)去被别人轮~~(双性人?)。正所谓所有的产品和功能都是因为需求存在的,举个最简单的需求,原来MP3想传送一个歌曲都得通过电脑。现在只要两个MP3链接,其中一个MP3有OTG功能作为主设备(相当于电脑主机),然后另外一个是从设备就可以实现数据的传送了。那么话说回来,具有OTG功能的设备如何确定自己是主还是从设备那。原来原来USB接口上有4个管脚,OTG功能有5个。原来4个分别是电D+ D-地。现在增加了一个ID。这个ID线就决定了自己做主设备还是从设备。如果ID线是高则自己是从设备,反之是主设备。

下面开始分析代码。

向平时一样定义platform_device资源等信息。

定义platform_device结构

static struct platform_device __maybe_unused dr_otg_device =

{ .name = "fsl-usb2-otg", //设备的名称 日后匹配用

.id = -1, //只有一个这样的设备

.dev = { .release = dr_otg_release,

.dma_mask = &dr_otg_dmamask,

.coherent_dma_mask = 0xffffffff,

},

.resource = otg_resources, //设备的资源 看下面

.num_resources = ARRAY_SIZE(otg_resources),

};

定义platform_device下的struct resource设备资源结构static struct resource otg_resources[] = {

[0] = {

.start = (u32)(USB_OTGREGS_BASE), //描述设备实体在cpu总线上的线性起始物理地址

.end = (u32)(USB_OTGREGS_BASE + 0x1ff), //描述设备实体在cpu总线上的线性结尾物理地址

.flags = IORESOURCE_MEM, },

[1] = {

.start = MXC_INT_USB_OTG, //中断号

.flags = IORESOURCE_IRQ, },

};定义平台设备私有数据,以后驱动要使用

static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config = {

.name = "DR",

.platform_init = usbotg_init,

.platform_uninit = usbotg_uninit,

.phy_mode = FSL_USB2_PHY_UTMI_WIDE,

.power_budget = 500, /* via RT9706 */

.gpio_usb_active = gpio_usbotg_utmi_active,

.gpio_usb_inactive = gpio_usbotg_utmi_inactive,

.transceiver = "utmi",

.wake_up_enable = _wake_up_enable,

};

#define PDATA (&dr_utmi_config) 定义platform_device下的DEV设备下的平台私有数据(就是该设备私有的数据)

static inline void dr_register_otg(void) {

PDATA->operating_mode = FSL_USB2_DR_OTG; //将模式更改(上面定义的时候定义的是FSL_USB2_PHY_UTMI_WIDE,不知道为什么开始不定义这个,可能是为了兼容)

dr_otg_device.dev.platform_data = PDATA; //该设备的私有数据赋值,就是上面定义的dr_utmi_config

if (platform_device_register(&dr_otg_device))

printk(KERN_ERR "usb: can't register otg device\n");

else

printk(KERN_INFO "usb: DR OTG registered\n");

}

上面几个过程主要是完成了设备的注册。这个过程是:

1.定义platform_device结构。

2.定义platform_device下的struct resource设备资源结构

3.定义platform_device下的DEV设备下的平台私有数据(就是该设备私有的数据)

4.调用platform_device_register将platform_device结构

注册上面4个过程调用结束后,设备的信息就被注册到系统中,等待驱动的使用

下面分析驱动和设备的链接过程

定义platform_driver结构

struct platform_driver fsl_otg_driver = {

.probe = fsl_otg_probe, //定义处理函数,该函数在设备名字匹配到后调用,也就是发现该驱动对应的设备在系统中注册过。

.remove = fsl_otg_remove,

.driver = {

.name = "fsl-usb2-otg", //通过该名字匹配开始注册进系统的设备

.owner = THIS_MODULE,

},

};

将platform_driver结构注册进系统,系统通过注册名字匹配该设备是否已经在系统中,如果在调用注册的probe = fsl_otg_probe函数

static int __init fsl_usb_otg_init(void)

{

printk(KERN_INFO DRIVER_DESC " loaded, %s\n", DRIVER_VERSION);

return platform_driver_register(&fsl_otg_driver);

}

调用fsl_otg_probe函数,函数参数platform_device *pdev,就是我们上面注册进系统的platform_device结构,现在由系统赋值调用fsl_otg_probe

static int __init fsl_otg_probe(struct platform_device *pdev)

{

int status;

struct fsl_usb2_platform_data *pdata;

DBG("pdev=0x%p\n", pdev);

if (!pdev)

return -ENODEV;

/*判断是否有设备自己的数据,就是检查我们上面定义的3的过程*/

if (!pdev->dev.platform_data)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值