+ * ci_otg_role - pick role based on ID pin state
+ * @ci: the controller
+ */
+enum ci_role ci_otg_role(struct ci_hdrc *ci)
+{
+ u32 sts = hw_read(ci, OP_OTGSC, ~0);
+ enum ci_role role = sts & OTGSC_ID
+ ? CI_ROLE_GADGET
+ : CI_ROLE_HOST;
+
+ return role;
+}
+
+/**
+ * ci_role_work - perform role changing based on ID pin
+ * @work: work struct
+ */
+static void ci_role_work(struct work_struct *work)
+{
+ struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
+ enum ci_role role = ci_otg_role(ci);
+
+ if (role != ci->role) {
+ dev_dbg(ci->dev, "switching from %s to %s\n",
+ ci_role(ci)->name, ci->roles[role]->name);
+
+ ci_role_stop(ci);
+ ci_role_start(ci, role);
+ }
+
+ enable_irq(ci->irq);
+}
+
+/**
+ * ci_hdrc_otg_init - initialize otg struct