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相关的内容.
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相关的内容.
相关文章推荐
- MUSB(4) --- OMAP2430 USB OTG Controller (Driver)
- USB蓝牙配合DesignWare USB 2.0 OTG Controller使用时4字节对齐问题
- UDC (usb device controller) Framework - USB gadget driver framework
- DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver File List
- mini2440 usb device controller 驱动的分析--gadget设备(二)---枚举
- USB device & USB controller & USB passthrough
- mini2440 usb device controller 驱动的分析--gadget设备
- 基于s3c6410 otg controller的gadget driver及usb枚举分析
- 基于s3c6410 otg controller的gadget driver及usb枚举分 析
- USB Device Descriptor for AMP Controller
- mini2440 usb device controller 驱动的分析--gadget设备(三)--- usb device framework
- mini2440 usb device controller 驱动的分析--gadget设备(一)--device controller
- mini2440 usb device controller 驱动的分析--gadget设备(四)---class driver
- 基于s3c6410 otg controller的gadget driver及usb枚举分 析
- DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver File List
- usb unknow device 无法识别的USB设备 Enhanced Host Controller 静电
- What decide the USB OTG port as host or device
- DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver File List
- usb host controller & usb core & usb device driver之间的关系
- mini2440 usb device controller 驱动的分析--gadget设备(五)--zero和usb-skeleton测试例