From 57677be5ef838743561f4c1d16821dda0438d362 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Wed, 23 Apr 2014 15:56:44 +0800 Subject: [PATCH] usb: chipidea: usb OTG fsm initialization. This patch adds OTG fsm related initialization when do otg init, add a seperate file for OTG fsm related utilities. Signed-off-by: Peter Chen Signed-off-by: Li Jun Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/Makefile | 1 + drivers/usb/chipidea/ci.h | 17 +++++++++ drivers/usb/chipidea/otg.c | 4 +++ drivers/usb/chipidea/otg_fsm.c | 63 ++++++++++++++++++++++++++++++++++ drivers/usb/chipidea/otg_fsm.h | 29 ++++++++++++++++ 5 files changed, 114 insertions(+) create mode 100644 drivers/usb/chipidea/otg_fsm.c create mode 100644 drivers/usb/chipidea/otg_fsm.h diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 480bd4d5710a..2f099c7df7b5 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -6,6 +6,7 @@ ci_hdrc-y := core.o otg.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC) += udc.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST) += host.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o +ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o # Glue/Bridge layers go here diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 7ae8cb680321..bd3529f29e86 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -17,6 +17,7 @@ #include #include #include +#include /****************************************************************************** * DEFINE @@ -139,6 +140,7 @@ struct hw_bank { * @roles: array of supported roles for this controller * @role: current role * @is_otg: if the device is otg-capable + * @fsm: otg finite state machine * @work: work for role changing * @wq: workqueue thread * @qh_pool: allocation pool for queue heads @@ -174,6 +176,7 @@ struct ci_hdrc { struct ci_role_driver *roles[CI_ROLE_END]; enum ci_role role; bool is_otg; + struct otg_fsm fsm; struct work_struct work; struct workqueue_struct *wq; @@ -319,6 +322,20 @@ static inline u32 hw_test_and_write(struct ci_hdrc *ci, enum ci_hw_regs reg, return (val & mask) >> __ffs(mask); } +/** + * ci_otg_is_fsm_mode: runtime check if otg controller + * is in otg fsm mode. + */ +static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci) +{ +#ifdef CONFIG_USB_OTG_FSM + return ci->is_otg && ci->roles[CI_ROLE_HOST] && + ci->roles[CI_ROLE_GADGET]; +#else + return false; +#endif +} + u32 hw_read_intr_enable(struct ci_hdrc *ci); u32 hw_read_intr_status(struct ci_hdrc *ci); diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index c6943401a0b3..d76db51ecda7 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -22,6 +22,7 @@ #include "ci.h" #include "bits.h" #include "otg.h" +#include "otg_fsm.h" /** * hw_read_otgsc returns otgsc register bits value. @@ -116,6 +117,9 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci) return -ENODEV; } + if (ci_otg_is_fsm_mode(ci)) + return ci_hdrc_otg_fsm_init(ci); + return 0; } diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c new file mode 100644 index 000000000000..d9dfaa3cf40c --- /dev/null +++ b/drivers/usb/chipidea/otg_fsm.c @@ -0,0 +1,63 @@ +/* + * otg_fsm.c - ChipIdea USB IP core OTG FSM driver + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * Author: Jun Li + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * This file mainly handles OTG fsm, it includes OTG fsm operations + * for HNP and SRP. + */ + +#include +#include +#include +#include + +#include "ci.h" +#include "bits.h" +#include "otg.h" +#include "otg_fsm.h" + +int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) +{ + struct usb_otg *otg; + + otg = devm_kzalloc(ci->dev, + sizeof(struct usb_otg), GFP_KERNEL); + if (!otg) { + dev_err(ci->dev, + "Failed to allocate usb_otg structure for ci hdrc otg!\n"); + return -ENOMEM; + } + + otg->phy = ci->transceiver; + otg->gadget = &ci->gadget; + ci->fsm.otg = otg; + ci->transceiver->otg = ci->fsm.otg; + ci->fsm.power_up = 1; + ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; + ci->transceiver->state = OTG_STATE_UNDEFINED; + + mutex_init(&ci->fsm.lock); + + /* Enable A vbus valid irq */ + hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE); + + if (ci->fsm.id) { + ci->fsm.b_ssend_srp = + hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1; + ci->fsm.b_sess_vld = + hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0; + /* Enable BSV irq */ + hw_write_otgsc(ci, OTGSC_BSVIE, OTGSC_BSVIE); + } + + return 0; +} diff --git a/drivers/usb/chipidea/otg_fsm.h b/drivers/usb/chipidea/otg_fsm.h new file mode 100644 index 000000000000..bf20a851b601 --- /dev/null +++ b/drivers/usb/chipidea/otg_fsm.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * Author: Jun Li + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DRIVERS_USB_CHIPIDEA_OTG_FSM_H +#define __DRIVERS_USB_CHIPIDEA_OTG_FSM_H + +#include + +#ifdef CONFIG_USB_OTG_FSM + +int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci); + +#else + +static inline int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) +{ + return 0; +} + +#endif + +#endif /* __DRIVERS_USB_CHIPIDEA_OTG_FSM_H */ -- 2.39.2