I.MX6 OTG set as slave device hacking
/******************************************************************************
* 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的更多相关文章
- I.MX6 Ethernet MAC (ENET) MAC Address hacking
/********************************************************************* * I.MX6 Ethernet MAC (ENET) M ...
- I.MX6 天嵌 E9 U-boot menu hacking
/************************************************************************************ * I.MX6 天嵌 E9 ...
- otg device id pin 探討
Platform : Qualcomm MSM8937 PMIC : Qualcomm PMI8940 OTG base on USB2.0,增加 device 可當 host 也可當 periphe ...
- USB OTG原理+ ID 检测原理
OTG 检测的原理是: USB OTG标准在完全兼容USB2.0标准的基础上,增添了电源管理(节省功耗)功能,它允许设备既可作为主机,也可作为外设操作(两用OTG).USB OTG技术可实现没有主机时 ...
- am335x Qt SocketCAN Demo hacking
/*********************************************************************************** * am335x Qt Soc ...
- USB OTG原理和 ID 检测原理
OTG 检测的原理是: USB OTG标准在完全兼容USB2.0标准的基础上,增添了 电源管理(节省功耗)功能,它允许设备既可作为主机,也可作为外设操作(两用OTG).USB OTG技术可实现没有主机 ...
- USB otg 学习笔记
1 USB OTG的工作原理 OTG补充规范对USB2.0的最重要的扩展是其更具节能性的电源管理和允许设备以主机和外设两种形式工作.OTG有两种设备类型:两用OTG设备(Dualrole device ...
- [usb]usb otg和host
USB OTG 设备既能做主机,又能做设备.USB HOST是指主机.当OTG 插到 HOST 上,OTG 的角色 就是 device.当device 插到 OTG 上,OTG 的角色就是 HOST. ...
- 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 ...
随机推荐
- python 散列表查找
class HashTable: def __init__(self, size): self.elem = [None for i in range(size)] self.count = size ...
- Bate冲刺四——《WAP团队》
β冲刺第四天 1. 今日完成任务情况以及遇到的问题. ①马麒.杜有海:记录功能完善情况 ②郝明宇:记录验收情况 ③马宏伟.周欣:后台前端数据连接 ④乌勒扎:综合测试 2.成员时间贡献 成员 马宏 ...
- Idea设置默认不折叠一行的函数
- 多年未写过java了
java面试必须了解和记忆的知识点(linux,nginx,数据库之类的暂时不考虑了) java面试的115常见问题,这个博客还是不过的推荐一下吧 http://www.importnew.com/1 ...
- javascript变量声明及作用域总结
javascript变量声明及作用域总结 一.总结 一句话总结:还是得好好看书,光看视频是不得行的,浅学无用,要相互印证,要真正理解才有用,比如<Javascript权威指南> 书 1.j ...
- English trip -- Phonics 2 元音字母a
xu言: 欲速则不达,如果这是你生命中最后一天.你还愿意花这么多精力继续坚持你现在做的事吗?如果答案是否定的,那么你需要改变了! What makes a word? 单词构成 Word 单词: ...
- 当保存在Session中的对象,取出后,在外部发生改变时会怎样
return_reason_model model = new return_reason_model(); model.F_RetunrnReason = "; HttpContext.S ...
- Almost Acyclic Graph CodeForces - 915D (思维,图论)
大意: 给定无向图, 求是否能删除一条边后使图无环 直接枚举边判环复杂度过大, 实际上删除一条边可以看做将该边从一个顶点上拿开, 直接枚举顶点即可 复杂度$O(n(n+m))$ #include &l ...
- python-day43--单表查询之关键字执行优先级(重点)
一.关键字的执行优先级(重点) 1.关键字执行优先级 from where #约束条件(在数据产生之前执行) group by #分组 没有分组则默认一组 按照select后的字段取得一张新的虚拟表, ...
- 关于vue Unexpected identifier 问题
vue对于es6虽然自带babel转换 但是在index.html文件中并不会发生转换 因此在index.html中使用新的语法会导致低版本浏览器不识别代码因此报出Unexpected identif ...