参考文件:
kernel/drivers/usb/phy/phy-msm-usb.c
kernel/msm-3.18/drivers/usb/phy/phy-msm-usb.c
+//begin:stone modify for usb id
+static bool usb_id_flag = 1;
+bool get_usb_id(void)
+{
+ return usb_id_flag;
+}
+EXPORT_SYMBOL(get_usb_id);
+//end:stone modify for usb id
在msm_id_status_w函数中添加即可:
static void msm_id_status_w(struct work_struct *w)
{
struct msm_otg *motg = container_of(w, struct msm_otg,
id_status_work.work);
int work = 0;
int id_state = 0;
dev_dbg(motg->phy.dev, "ID status_w\n");
if (motg->pdata->pmic_id_irq)
id_state = msm_otg_read_pmic_id_state(motg);
else if (motg->ext_id_irq)
id_state = gpio_get_value(motg->pdata->usb_id_gpio);
else if (motg->phy_irq)
id_state = msm_otg_read_phy_id_state(motg);
//usb_otg: usb@78d9000 {中定义了:
//interrupt-names = "core_irq", "async_irq","phy_irq";
//motg->phy_irq = platform_get_irq_byname(pdev, "phy_irq");
//所以phy_irq不为空,走到这里
if (id_state) {
if (!test_and_set_bit(ID, &motg->inputs)) {
pr_debug("ID set\n");
msm_otg_dbg_log_event(&motg->phy, "ID SET",
motg->inputs, motg->phy.state);
work = 1;
}
} else {
if (test_and_clear_bit(ID, &motg->inputs)) {
pr_debug("ID clear\n");
msm_otg_dbg_log_event(&motg->phy, "ID CLEAR",
motg->inputs, motg->phy.state);
set_bit(A_BUS_REQ, &motg->inputs);
work = 1;
}
}
+//begin:stone modify for usb id
+usb_id_flag = !!id_state;
+printk(KERN_ERR "usb_id_flag=%d\n",usb_id_flag);
+//end:stone modify for usb id
if (work && (motg->phy.state != OTG_STATE_UNDEFINED)) {
msm_otg_dbg_log_event(&motg->phy,
"CHECK ID EVENT DURING SUSPEND",
atomic_read(&motg->pm_suspended),
motg->sm_work_pending);
if (atomic_read(&motg->pm_suspended)) {
motg->sm_work_pending = true;
} else if (!motg->sm_work_pending) {
/* process event only if previous one is not pending */
queue_work(motg->otg_wq, &motg->sm_work);
}
}
}
真正读取ID的函数是msm_otg_read_phy_id_state:
static bool msm_otg_read_phy_id_state(struct msm_otg *motg)
{
u8 val;
/*
* clear the pending/outstanding interrupts and
* read the ID status from the SRC_STATUS register.
*/
writeb_relaxed(USB_PHY_ID_MASK, USB2_PHY_USB_PHY_INTERRUPT_CLEAR1);
writeb_relaxed(0x1, USB2_PHY_USB_PHY_IRQ_CMD);
/*
* Databook says 200 usec delay is required for
* clearing the interrupts.
*/
udelay(200);
writeb_relaxed(0x0, USB2_PHY_USB_PHY_IRQ_CMD);
val = readb_relaxed(USB2_PHY_USB_PHY_INTERRUPT_SRC_STATUS);
if (val & USB_PHY_IDDIG_1_0)
return false; /* ID is grounded */
else
return true;
}