/******************************************************************************
* 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. js获取url 参数

    window.getRequest = function (url) { var theRequest = new Object(); var indexOf = url.indexOf(" ...

  2. deque_01

    A.头尾 添加/移除 A.1.deque::push_back(elemValue); A.2.deque::pop_back(); A.3.deque::push_front(elemValue); ...

  3. [ios]自定义UI

    参考:http://blog.sina.com.cn/s/blog_7b9d64af0101edqf.html 回忆一下,这么个场景. 我们在一个界面上,要排列多个相同的元素.你马上就可以想到: 1. ...

  4. YOLO V1论文理解

    摘要 作者提出了一种新的物体检测方法YOLO.YOLO之前的物体检测方法主要是通过region proposal产生大量的可能包含待检测物体的 potential bounding box,再用分类器 ...

  5. Codeforces 805D - Minimum number of steps

    805D - Minimum number of steps 思路:简单模拟,a每穿过后面一个b,b的个数+1,当这个a穿到最后,相当于把它后面的b的个数翻倍.每个a到达最后的步数相当于这个a与它后面 ...

  6. Lua面向对象 --- 封装

    工程结构: Player.lua: Player = {} function Player:new() local self = {} setmetatable(self, {__index = Pl ...

  7. 显示Unicode 字节的对应字符的小技巧

    在一段smali代码里看到这样的代码 const-string v0, "\u7528\u6237\u9a8c\u8bc1\u8fc7\u671f\uff0c\u8bf7\u91cd\u65 ...

  8. Eclipse 中 SDK无法更新---解决方法

    在SDK Manager -> tools -> options中: HTTP Proxy Server: mirrors.neusoft.edu.cn HTTP Proxy Port: ...

  9. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛

    题意:到一个城市得钱,离开要花钱.开始时有现金.城市是环形的,问从哪个开始,能在途中任意时刻金钱>=0; 一个开始指针i,一个结尾指针j.指示一个区间.如果符合条件++j,并将收益加入sum中( ...

  10. codeforces 1042c// Array Product// Codeforces Round #510(Div. 2)

    题意:给出一个数组,2种操作:.1:x*y然后x消失,2:除掉x(2操作最多只能进行一次).问最大的结果的一种操作方式.逻辑题,看能不能想全面. 1先数好0,正,负的数量,zero,pos,neg.如 ...