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 ...
随机推荐
- shell 输出双引号
#!/bin/sh your_name='runoob' str="Hello, I know you are \"$your_name\"! \n" echo ...
- Ubuntu 定时任务
一.cron相关命令 #重载cron sudo service cron reload #查看cron状态 service cron status #查看cron pid pidof ...
- js实现滑动拼图验证码
js实现滑动拼图验证码,我这个样式是仿那些大网站做了, 学习用的,只用到前端. 小的个人网站感觉还可以用,大一点的别人用机器一下就破解了. 下面看图示: 样子大概是这样的. 源码在这 百度网盘: ...
- 解决Word 2013, Word 2016的保存太慢的问题
尝试下面步骤: 方法 一:文件〉选项〉高级〉,保存,关闭“允许后台保存”选项. 提示:禁止该项功能可能存在风险, 请及时保存文件. 方法二:禁用 Office 中的硬件加速 1.启动任一 Offic ...
- 20170501xlVBA销售订单整理一行转多行
Sub NextSeven_CodeFrame() Application.ScreenUpdating = False Application.DisplayAlerts = False Appli ...
- vue.js 过渡&动画
9-17 在add ,update, remove DOM时 提供多种方式的应用过度效果. 包括以下可选工具:(2大类,css和js) 在css过度和动画中自动应用class 配合使用第三方css动画 ...
- pandas的concat函数和append方法
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, nam ...
- 2-24-源码编译搭建LAMP环境-作业 ( By 小甘丶 )
安装上课的内容要求: 实验环境: VMware Virtual Machine : System Version: CentOS6.8 ( Gan35 ) IP Address : 192.168.3 ...
- nyoj-833-博弈
833-取石子(七) 内存限制:64MB 时间限制:1000ms 特判: No通过数:16 提交数:30 难度:1 题目描述: Yougth和Hrdv玩一个游戏,拿出n个石子摆成一圈,Yougth和H ...
- js实现个链表吧
存储多个元素,最常用的数据结构是数组.但是数组有个一缺点,从数组中添加或移除项的成本很高,因为需要移动元素.链表也可以存储有序的元素集合,但是和数组不同,链表中的元素在内存中不是连续放置的.每个元素存 ...