/******************************************************************************
* IMX6 OTG set as slave device hacking
* 声明:
* 1. 本代码解析使用了倒序的方式跟踪内核驱动代码,从驱动反推需求;
* 2. 代码解析的目标是找到OTG设置成Host、Slave设备的宏定义;
* 3. 根据2中的宏定义,看make menuconfig中是否存在可直接裁剪的选项。
*
* 2015-8-7 晴 深圳 南山平山村 曾剑锋
*****************************************************************************/ <kernel path>/drivers/usb/otg/fsl_otg.c 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); |
} | |
| |
static void __exit fsl_usb_otg_exit(void) +-------------+ |
{ | |
platform_driver_unregister(&fsl_otg_driver); | |
printk(KERN_INFO DRIVER_DESC " unloaded\n"); | |
} | |
| |
subsys_initcall(fsl_usb_otg_init); --------------------|---------------+
module_exit(fsl_usb_otg_exit); |
|
MODULE_DESCRIPTION(DRIVER_INFO); |
MODULE_AUTHOR(DRIVER_AUTHOR); |
MODULE_LICENSE("GPL"); |
|
|
struct platform_driver fsl_otg_driver = { <-------------+
.probe = fsl_otg_probe,
.remove = fsl_otg_remove,
.driver = {
.name = driver_name, --------+
.owner = THIS_MODULE, |
}, |
}; |
V
static const char driver_name[] = "fsl-usb2-otg"; -------------+
|
|
<kernel path>/arch/arm$ grep fsl-usb2-otg * -R |
Binary file boot/Image matches |
mach-mx5/devices.c: .name = "fsl-usb2-otg", |
...... |
Binary file plat-mxc/devices/built-in.o matches V
plat-mxc/devices/platform-fsl-usb2-otg.c: const char *name = "fsl-usb2-otg";
Binary file plat-mxc/built-in.o matches |
|
|
<kernel path>/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c |
#define imx_fsl_usb2_otg_data_entry_single(soc) \ |
{ \ |
.iobase = soc ## _USB_OTG_BASE_ADDR, \ |
.irq = soc ## _INT_USB_OTG, \ |
} |
|
|
#ifdef CONFIG_SOC_IMX6Q |
const struct imx_fsl_usb2_otg_data imx6q_fsl_usb2_otg_data __initconst = |
imx_fsl_usb2_otg_data_entry_single(MX6Q); |
#endif /* ifdef CONFIG_SOC_IMX6Q */ |
|
struct platform_device *__init imx_add_fsl_usb2_otg( ----------+ |
const struct imx_fsl_usb2_otg_data *data, | |
const struct fsl_usb2_platform_data *pdata) | |
{ | |
struct resource res[] = { | |
{ | |
.start = data->iobase, | |
.end = data->iobase + SZ_512 - , | |
.flags = IORESOURCE_MEM, | |
}, { | |
.start = data->irq, | |
.end = data->irq, | |
.flags = IORESOURCE_IRQ, | |
}, | |
}; | |
| |
int ret = -ENOMEM; | |
const char *name = "fsl-usb2-otg"; <-------------------------|---+
int id = -; |
unsigned int num_resources = ARRAY_SIZE(res); |
size_t size_data = sizeof(*pdata); |
u64 dmamask = DMA_BIT_MASK(); |
struct platform_device *pdev; |
|
pdev = platform_device_alloc(name, id); |
if (!pdev) |
goto err; |
|
if (dmamask) { |
/* |
* This memory isn't freed when the device is put, |
* I don't have a nice idea for that though. Conceptually |
* dma_mask in struct device should not be a pointer. |
* See http://thread.gmane.org/gmane.linux.kernel.pci/9081 |
*/ |
pdev->dev.dma_mask = |
kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); |
if (!pdev->dev.dma_mask) |
/* ret is still -ENOMEM; */ |
goto err; |
|
*pdev->dev.dma_mask = dmamask; |
pdev->dev.coherent_dma_mask = dmamask; |
} |
|
ret = platform_device_add_resources(pdev, res, num_resources); |
if (ret) |
goto err; |
|
if (data) { |
ret = platform_device_add_data(pdev, pdata, size_data); |
if (ret) |
goto err; |
} |
|
return pdev; |
err: |
if (dmamask) |
kfree(pdev->dev.dma_mask); |
platform_device_put(pdev); |
return ERR_PTR(ret); |
} |
EXPORT_SYMBOL(imx_add_fsl_usb2_otg); |
|
<kernel path>/arch/arm$ grep imx_add_fsl_usb2_otg * -R <-------------+
Binary file boot/Image matches
mach-mx6/devices-imx6q.h: imx_add_fsl_usb2_otg(&imx6q_fsl_usb2_otg_data, pdata) ----------+
...... |
plat-mxc/devices/platform-fsl-usb2-otg.c:struct platform_device *__init imx_add_fsl_usb2_otg( |
plat-mxc/devices/platform-fsl-usb2-otg.c:EXPORT_SYMBOL(imx_add_fsl_usb2_otg); |
Binary file plat-mxc/built-in.o matches |
|
<kernel path>/arch/arm/mach-mx6/devices-imx6q.h |
extern const struct imx_fsl_usb2_otg_data imx6q_fsl_usb2_otg_data __initconst; |
#define imx6q_add_fsl_usb2_otg(pdata) \ -------------------+ |
imx_add_fsl_usb2_otg(&imx6q_fsl_usb2_otg_data, pdata) <------------------*------+
|
<kernel path>/arch/arm$ grep imx6q_add_fsl_usb2_otg * -R |
Binary file mach-mx6/.usb_dr.c.swp matches |
mach-mx6/devices-imx6q.h:#define imx6q_add_fsl_usb2_otg(pdata) \ |
mach-mx6/devices-imx6q.h:#define imx6q_add_fsl_usb2_otg_wakeup(pdata) \ |
mach-mx6/usb_dr.c: pdev[i] = imx6q_add_fsl_usb2_otg(&dr_utmi_config); |
mach-mx6/usb_dr.c: pdev_wakeup = imx6q_add_fsl_usb2_otg_wakeup(&dr_wakeup_config); |
|
<kernel path>/arch/arm/mach-mx6/usb_dr.c |
static int __init mx6_usb_dr_init(void) |
{ |
int i = ; |
void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); |
struct imx_fsl_usb2_wakeup_data imx6q_fsl_otg_wakeup_data = |
imx_fsl_usb2_wakeup_data_entry_single(MX6Q, , OTG); |
struct imx_mxc_ehci_data __maybe_unused imx6q_mxc_ehci_otg_data = |
imx_mxc_ehci_data_entry_single(MX6Q, , OTG); |
struct imx_fsl_usb2_udc_data __maybe_unused imx6q_fsl_usb2_udc_data = |
imx_fsl_usb2_udc_data_entry_single(MX6Q); |
struct imx_fsl_usb2_otg_data __maybe_unused imx6q_fsl_usb2_otg_data = |
imx_fsl_usb2_otg_data_entry_single(MX6Q); |
|
/* Some phy and power's special controls for otg |
* 1. The external charger detector needs to be disabled |
* or the signal at DP will be poor |
* 2. The EN_USB_CLKS is always enabled. |
* The PLL's power is controlled by usb and others who |
* use pll3 too. |
*/ |
__raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B \ |
| BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B, \ |
anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT); |
__raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, |
anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); |
mx6_get_otghost_vbus_func(&mx6_set_usb_otg_vbus); |
dr_utmi_config.platform_driver_vbus = mx6_set_usb_otg_vbus; |
|
#ifdef CONFIG_USB_OTG |
/* wake_up_enable is useless, just for usb_register_remote_wakeup execution*/ |
dr_utmi_config.wake_up_enable = _device_wakeup_enable; |
dr_utmi_config.operating_mode = FSL_USB2_DR_OTG; |
dr_utmi_config.wakeup_pdata = &dr_wakeup_config; |
pdev[i] = imx6q_add_fsl_usb2_otg(&dr_utmi_config); <------------------------+
dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data;
i++;
#endif
#ifdef CONFIG_USB_EHCI_ARC_OTG -------------------------+
dr_utmi_config.operating_mode = DR_HOST_MODE; |
dr_utmi_config.wake_up_enable = _host_wakeup_enable; |
if (usb_icbug_swfix_need()) { |
dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend_swfix; |
dr_utmi_config.platform_rh_resume = _host_platform_rh_resume_swfix; |
} else { |
dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend; |
dr_utmi_config.platform_rh_resume = _host_platform_rh_resume; |
} |
dr_utmi_config.platform_set_disconnect_det = fsl_platform_otg_set_usb_phy_dis; |
dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend; |
dr_utmi_config.is_wakeup_event = _is_host_wakeup; |
dr_utmi_config.wakeup_pdata = &dr_wakeup_config; |
dr_utmi_config.wakeup_handler = host_wakeup_handler; |
dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on; |
pdev[i] = imx6q_add_fsl_ehci_otg(&dr_utmi_config); |
dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data; |
i++; |
#endif |
#ifdef CONFIG_USB_GADGET_ARC |
dr_utmi_config.operating_mode = DR_UDC_MODE; |
dr_utmi_config.wake_up_enable = _device_wakeup_enable; |
dr_utmi_config.platform_rh_suspend = NULL; |
dr_utmi_config.platform_rh_resume = NULL; |
dr_utmi_config.platform_set_disconnect_det = NULL; |
dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend; |
dr_utmi_config.is_wakeup_event = _is_device_wakeup; |
dr_utmi_config.wakeup_pdata = &dr_wakeup_config; |
dr_utmi_config.wakeup_handler = device_wakeup_handler; |
dr_utmi_config.charger_base_addr = anatop_base_addr; |
dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on; |
pdev[i] = imx6q_add_fsl_usb2_udc(&dr_utmi_config); |
dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data; |
i++; |
#endif |
devnum = i; |
/* register wakeup device */ |
pdev_wakeup = imx6q_add_fsl_usb2_otg_wakeup(&dr_wakeup_config); |
for (i = ; i < devnum; i++) { |
platform_device_add(pdev[i]); |
((struct fsl_usb2_platform_data *)(pdev[i]->dev.platform_data))->wakeup_pdata = |
(struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data); |
} |
|
return ; |
} |
module_init(mx6_usb_dr_init); |
|
<kernel path>$ make menuconfig |
| Symbol: USB_EHCI_ARC_OTG [=n] <--------------------------------*--------------------+
│ Type : boolean |
│ Prompt: Support for DR host port on Freescale controller |
│ Defined at drivers/usb/host/Kconfig: |
│ Depends on: USB_SUPPORT [=y] && USB_EHCI_ARC [=y] |
│ Location: |
│ -> Device Drivers |
│ -> USB support (USB_SUPPORT [=y]) |
│ -> Support for Freescale controller (USB_EHCI_ARC [=y]) |

I.MX6 OTG set as slave device hacking的更多相关文章

  1. I.MX6 Ethernet MAC (ENET) MAC Address hacking

    /********************************************************************* * I.MX6 Ethernet MAC (ENET) M ...

  2. I.MX6 天嵌 E9 U-boot menu hacking

    /************************************************************************************ * I.MX6 天嵌 E9 ...

  3. otg device id pin 探討

    Platform : Qualcomm MSM8937 PMIC : Qualcomm PMI8940 OTG base on USB2.0,增加 device 可當 host 也可當 periphe ...

  4. USB OTG原理+ ID 检测原理

    OTG 检测的原理是: USB OTG标准在完全兼容USB2.0标准的基础上,增添了电源管理(节省功耗)功能,它允许设备既可作为主机,也可作为外设操作(两用OTG).USB OTG技术可实现没有主机时 ...

  5. am335x Qt SocketCAN Demo hacking

    /*********************************************************************************** * am335x Qt Soc ...

  6. USB OTG原理和 ID 检测原理

    OTG 检测的原理是: USB OTG标准在完全兼容USB2.0标准的基础上,增添了 电源管理(节省功耗)功能,它允许设备既可作为主机,也可作为外设操作(两用OTG).USB OTG技术可实现没有主机 ...

  7. USB otg 学习笔记

    1 USB OTG的工作原理 OTG补充规范对USB2.0的最重要的扩展是其更具节能性的电源管理和允许设备以主机和外设两种形式工作.OTG有两种设备类型:两用OTG设备(Dualrole device ...

  8. [usb]usb otg和host

    USB OTG 设备既能做主机,又能做设备.USB HOST是指主机.当OTG 插到 HOST 上,OTG 的角色 就是 device.当device 插到 OTG 上,OTG 的角色就是 HOST. ...

  9. Arduino control Eeprom by IIC method of using device address in Arduino

    参考: 1.https://www.arduino.cc/ 2.https://www.arduino.cc/reference/en/ 3.https://www.arduino.cc/en/Ref ...

随机推荐

  1. [tixml]保存,读取

    保存: //xml的实体 TiXmlElement* rootElement = new TiXmlElement("spark"); rootElement->SetAtt ...

  2. Docker 容器十诫

    [编者按]本文作者为 Rafael Benevides,主要介绍使用 Docker 容器时应该注意的十个陷阱. Docker 容器十诫 当你刚开始使用容器时,会发现容器能解决许多问题,而且好处很多: ...

  3. MySQL数据库性能优化

    mysql查询优化: 1.新增字段索引,查询时若使用到or关键字,则两个字段都需建立索引才能生效 2.sql语句包含子查询,mysql会创建临时表查询结束后删除,影响效率,所以应尽可能使用join替代 ...

  4. Unity 中 ContextMenu 的用法

    在自定义脚本中的方法前加入  [ContextMenu("Execute")]  标签,然后将脚本挂载到对象上,可以再编辑模式下执行标记的方法: 自定义脚本如下: using Sy ...

  5. Myeclipse2016安装Aptana

    Myeclipse2016安装Aptana 想装个Aptana,装了半天,网上说的什么links方式啊,在线方式啊,都是什么的浮云. 所以自己来写个安装教程. 一.Aptana简要介绍 Aptana有 ...

  6. 探索Bioconductor数据包

    参考: R的bioconductor包TxDb.Hsapiens.UCSC.hg19.knownGene详解 Bioconductor的数据包library(org.Hs.eg.db)简介

  7. 20170503xlVBA房地产数据分类连接

    Sub NextSeven_CodeFrame4() Application.ScreenUpdating = False Application.DisplayAlerts = False Appl ...

  8. python-day13--装饰器

    1.开放封闭的原则: 1.对扩展是开放的 为什么要对扩展开放呢? 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新功能. 2.对 ...

  9. M爷的线段树

    M爷的线段树 - BUCTOJ 3305 一个长度为n的数列A.修改m次,每次给区间[L,R]中的每一个数加X.查询k次,每次查询第i个元素的值并输出.1<=n<=1e5 ,1<=m ...

  10. SQL Server数据库 优化查询速度

    查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 ...