您的位置:首页 > 其它

MUSB (3) --- OMAP2430 USB OTG Controller(device)

2014-05-07 17:00 591 查看
MUSB (3) --- OMAP2430 USB OTG Controller(device) 2013-12-13
17:19:52

分类: Android平台

1. Makefile

fudan_abc在他的《Linux那些事儿之我是USB》中反复提到了Makefile.作为整个软件架构分析的map.

这里拾人牙慧也按照这种方式来描述MUSB的软件架构.

红色部分是指arch/arm/configs/XXXX_config中已经定义的.

点击(此处)折叠或打开

#

# for USB OTG silicon based on Mentor Graphics INVENTRA designs

#

ccflags-$(CONFIG_USB_MUSB_DEBUG) := -DDEBUG

obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o

musb_hdrc-y := musb_core.o

musb_hdrc-$(CONFIG_USB_GADGET_MUSB_HDRC) += musb_gadget_ep0.o
musb_gadget.o

musb_hdrc-$(CONFIG_USB_MUSB_HDRC_HCD) += musb_virthub.o
musb_host.o

musb_hdrc-$(CONFIG_DEBUG_FS) += musb_debugfs.o

ifeq ($(CONFIG_USB_MUSB_DEBUG),y)

musb_hdrc-$(CONFIG_PROC_FS) += musb_procfs.o

endif

# Hardware Glue Layer

obj-$(CONFIG_USB_MUSB_OMAP2PLUS_GLUE) += omap2430.o

obj-$(CONFIG_USB_MUSB_AM35X_GLUE) += am35x.o

obj-$(CONFIG_USB_MUSB_TI81XX_GLUE) += ti81xx.o

obj-$(CONFIG_USB_MUSB_TUSB6010_GLUE) += tusb6010.o

obj-$(CONFIG_USB_MUSB_DAVINCI_GLUE) += davinci.o

obj-$(CONFIG_USB_MUSB_DA8XX_GLUE) += da8xx.o

obj-$(CONFIG_USB_MUSB_BLACKFIN_GLUE) += blackfin.o

obj-$(CONFIG_USB_MUSB_UX500_GLUE) += ux500.o

# the kconfig must guarantee that only one of the

# possible I/O schemes will be enabled at a time ...

# PIO only, or DMA (several potential schemes).

# though PIO is always there to back up DMA, and for ep0

obj-$(CONFIG_USB_INVENTRA_DMA_HW) += musbhsdma.o

obj-$(CONFIG_USB_TI_CPPI_DMA_HW) += cppi_dma.o

obj-$(CONFIG_USB_TI_CPPI41_DMA_HW) += cppi41dma.o

cppi41dma-y += cppi41.o
cppi41_dma.o

obj-$(CONFIG_USB_TUSB_OMAP_DMA_HW) += tusb6010_omap.o



从上图中,我把Makefile中的源文件分为了三类:

(1) Controller相关

主要源文件2个:OMAP2430.c & musbhsdma.c

(2) Host 相关

这部分是很困难的部分,在后续的章节中要仔细分析他们是如何跟USB core关联起来的.

musb_hdrc.c

musb_gadget_ep0.c

musb_gadget.c

musb_virthub.c

musb_host.c

(3) debugfs

不做分析.

2. Host Controller

众所周知,在Linux的驱动架构中.有device和driver两部分.在最后他们会配对.

(1) device

点击(此处)折叠或打开

static struct omap_musb_board_data musb_board_data = {

.interface_type = MUSB_INTERFACE_ULPI,

.mode = MUSB_OTG,

.power = 100,

};

-->这就是device开始注册的起点. power域由原来的100mA修改为了500mA.这部分的详细描述参见USB spec. 最为让人奇怪的是extbus这个域.顾名思义是引用外部的电源.这个后续遇到了再做讨论.

点击(此处)折叠或打开

static int __init xxx_musb_init(void) {

int ret;

/* EVM REV >= E
can supply 500mA with EXTVBUS programming */

musb_board_data.power = 500;

musb_board_data.extvbus = 1;

usb_musb_init(&musb_board_data);

return 0;

}

-->那么接下来就是usb_musb_init

点击(此处)折叠或打开

void __init usb_musb_init(struct omap_musb_board_data *board_data)

{

int i;

if (cpu_is_omap243x()) {

musb_resources[0].start = OMAP243X_HS_BASE;

} else if (cpu_is_omap3517() || cpu_is_omap3505()) {

musb_device[0].name = "musb-am35x";

musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE;

musb_resources[1].start = INT_35XX_USBOTG_IRQ;

board_data->set_phy_power = am35x_musb_phy_power;

board_data->clear_irq = am35x_musb_clear_irq;

board_data->set_mode = am35x_musb_set_mode;

board_data->reset = am35x_musb_reset;

} else if (cpu_is_omap34xx()) {

musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;

} else if (cpu_is_omap44xx()) {

musb_resources[0].start = OMAP44XX_HSUSB_OTG_BASE;

musb_resources[1].start = OMAP44XX_IRQ_HS_USB_MC_N;

musb_resources[2].start = OMAP44XX_IRQ_HS_USB_DMA_N;

} else if (cpu_is_ti81xx()) {

/* disable musb multipoint support for ti8168 */

if (cpu_is_ti816x())

musb_config.multipoint = 0;

/* only usb0 port enabled in peripheral mode*/

if (board_data->mode == MUSB_PERIPHERAL)

board_data->instances = 0;

musb_resources[0].start = TI81XX_USB0_BASE;

musb_resources[1].start = TI81XX_IRQ_USB0;

musb_resources[0].end = musb_resources[0].start + SZ_2K - 1;

for (i = 0; i <= board_data->instances; i++) {

musb_device[i].name = "musb-ti81xx";

musb_device[i].num_resources = 0;

}

musb_config.fifo_mode = 4;

board_data->set_phy_power = ti81xx_musb_phy_power;

}

if (cpu_is_omap3517() || cpu_is_omap3505())

musb_resources[0].end = musb_resources[0].start + SZ_32K - 1;

else if (!cpu_is_ti81xx())

musb_resources[0].end = musb_resources[0].start + SZ_4K - 1;

/*

* OMAP3630/AM35x platform has MUSB RTL-1.8
which has the fix for the

* issue restricting active endpoints to use first 8K of FIFO space.

* This issue restricts OMAP35x platform to use fifo_mode '5'.

*/

if (cpu_is_omap3430())

musb_config.fifo_mode = 5;

for (i = 0; i <= board_data->instances; i++) {

if (cpu_is_ti816x())

musb_plat[i].clock = "usbotg_ick";

else if (cpu_is_ti814x())

musb_plat[i].clock = "usb_ick";

musb_plat[i].board_data = board_data;

musb_plat[i].power = board_data->power >> 1;

musb_plat[i].mode = board_data->mode;

musb_plat[i].extvbus = board_data->extvbus;

if (platform_device_register(&musb_device[i]) < 0)

printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");

}

usb_musb_pm_init();

}

我总是急功近利的,line:68 就将device注册进系统了.这也是整个device部分的终结点.

那么注册device到底涉及到了哪些方方面面的内容呢?仔细分析这部分是十分有必要的.首先,这可以帮助我们了解到MUSB这个device到底包含了哪些资源,对MUSB的硬件结构有了一个更为数字化的印象;其次再遇到其它设备的时候我们也能够以彼之道还施彼身,彼这里就是指MUSB了.也就是一法通万法通.

cpu_is_omap34xx()的返回值为true.

所以line:16 musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;

跟它对应的是line:47,这个是分配OTG controller的register物理地址



line 55: musb_config全局变量

line 63: musb_plat全局变量

line 68: 是最后注册的,我们要了解的就是:

点击(此处)折叠或打开

static struct platform_device musb_device[] = {

{

.name = "musb-omap2430",

.id = 0,

.dev = {

.dma_mask = &musb_dmamask,

.coherent_dma_mask = DMA_BIT_MASK(32),

.platform_data = &musb_plat[0],

},

.num_resources = 3,

.resource = &musb_resources[0],

},

{

.name = "musb-omap2430",

.id = 1,

.dev = {

.dma_mask = &musb_dmamask,

.coherent_dma_mask = DMA_BIT_MASK(32),

.platform_data = &musb_plat[1],

},

.num_resources = 3,

.resource = &musb_resources[3],

},

};

--->

点击(此处)折叠或打开

static struct musb_hdrc_platform_data musb_plat[] = {

{

.config = &musb_config,

.clock = "ick",

},

{

.config = &musb_config,

.clock = "ick",

},

};

--->

点击(此处)折叠或打开

static struct musb_hdrc_config musb_config = {

.fifo_mode = 4,

.multipoint = 1,

.dyn_fifo = 1,

.num_eps = 16,

.ram_bits = 12,

};

这里fifo_mode 被设置成了5.

点击(此处)折叠或打开

static struct resource musb_resources[] = {

[0] = { /* start and end set dynamically */

.flags = IORESOURCE_MEM,

},

[1] = { /* general
IRQ */

.start = INT_243X_HS_USB_MC,

.flags = IORESOURCE_IRQ,

.name = "mc",

},

[2] = { /* DMA
IRQ */

.start = INT_243X_HS_USB_DMA,

.flags = IORESOURCE_IRQ,

.name = "dma",

},

[3] = { /* MEM for TI81x's second musb */

.flags = IORESOURCE_MEM,

.start = TI81XX_USB1_BASE,

.end = TI81XX_USB1_BASE + SZ_2K - 1,

},

[4] = { /* IRQ for TI81x's second musb */

.start = TI81XX_IRQ_USB1,

.flags = IORESOURCE_IRQ,

.name = "mc",

},

};

在line:2~3中我们注意到只有flag,其它部分譬如说start,是在usb_musb_init中根据CPU的类型而进行裁定的.

上述就是所有注册device相关的内容.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: