aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
authorLi Jun <B47624@freescale.com>2014-04-23 03:56:44 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-04-24 15:56:34 -0400
commit57677be5ef838743561f4c1d16821dda0438d362 (patch)
treeb2c6c47afeb0ff704caeb50dd50cd8bb72540c34 /drivers/usb/chipidea
parentbe696aac3850f481a9d1dfea7ea1c9505ecc970b (diff)
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 <peter.chen@freescale.com> Signed-off-by: Li Jun <b47624@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r--drivers/usb/chipidea/Makefile1
-rw-r--r--drivers/usb/chipidea/ci.h17
-rw-r--r--drivers/usb/chipidea/otg.c4
-rw-r--r--drivers/usb/chipidea/otg_fsm.c63
-rw-r--r--drivers/usb/chipidea/otg_fsm.h29
5 files changed, 114 insertions, 0 deletions
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
6ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC) += udc.o 6ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC) += udc.o
7ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST) += host.o 7ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST) += host.o
8ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o 8ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o
9ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o
9 10
10# Glue/Bridge layers go here 11# Glue/Bridge layers go here
11 12
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 @@
17#include <linux/irqreturn.h> 17#include <linux/irqreturn.h>
18#include <linux/usb.h> 18#include <linux/usb.h>
19#include <linux/usb/gadget.h> 19#include <linux/usb/gadget.h>
20#include <linux/usb/otg-fsm.h>
20 21
21/****************************************************************************** 22/******************************************************************************
22 * DEFINE 23 * DEFINE
@@ -139,6 +140,7 @@ struct hw_bank {
139 * @roles: array of supported roles for this controller 140 * @roles: array of supported roles for this controller
140 * @role: current role 141 * @role: current role
141 * @is_otg: if the device is otg-capable 142 * @is_otg: if the device is otg-capable
143 * @fsm: otg finite state machine
142 * @work: work for role changing 144 * @work: work for role changing
143 * @wq: workqueue thread 145 * @wq: workqueue thread
144 * @qh_pool: allocation pool for queue heads 146 * @qh_pool: allocation pool for queue heads
@@ -174,6 +176,7 @@ struct ci_hdrc {
174 struct ci_role_driver *roles[CI_ROLE_END]; 176 struct ci_role_driver *roles[CI_ROLE_END];
175 enum ci_role role; 177 enum ci_role role;
176 bool is_otg; 178 bool is_otg;
179 struct otg_fsm fsm;
177 struct work_struct work; 180 struct work_struct work;
178 struct workqueue_struct *wq; 181 struct workqueue_struct *wq;
179 182
@@ -319,6 +322,20 @@ static inline u32 hw_test_and_write(struct ci_hdrc *ci, enum ci_hw_regs reg,
319 return (val & mask) >> __ffs(mask); 322 return (val & mask) >> __ffs(mask);
320} 323}
321 324
325/**
326 * ci_otg_is_fsm_mode: runtime check if otg controller
327 * is in otg fsm mode.
328 */
329static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
330{
331#ifdef CONFIG_USB_OTG_FSM
332 return ci->is_otg && ci->roles[CI_ROLE_HOST] &&
333 ci->roles[CI_ROLE_GADGET];
334#else
335 return false;
336#endif
337}
338
322u32 hw_read_intr_enable(struct ci_hdrc *ci); 339u32 hw_read_intr_enable(struct ci_hdrc *ci);
323 340
324u32 hw_read_intr_status(struct ci_hdrc *ci); 341u32 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 @@
22#include "ci.h" 22#include "ci.h"
23#include "bits.h" 23#include "bits.h"
24#include "otg.h" 24#include "otg.h"
25#include "otg_fsm.h"
25 26
26/** 27/**
27 * hw_read_otgsc returns otgsc register bits value. 28 * hw_read_otgsc returns otgsc register bits value.
@@ -116,6 +117,9 @@ int ci_hdrc_otg_init(struct ci_hdrc *ci)
116 return -ENODEV; 117 return -ENODEV;
117 } 118 }
118 119
120 if (ci_otg_is_fsm_mode(ci))
121 return ci_hdrc_otg_fsm_init(ci);
122
119 return 0; 123 return 0;
120} 124}
121 125
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 @@
1/*
2 * otg_fsm.c - ChipIdea USB IP core OTG FSM driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Jun Li
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 * This file mainly handles OTG fsm, it includes OTG fsm operations
15 * for HNP and SRP.
16 */
17
18#include <linux/usb/otg.h>
19#include <linux/usb/gadget.h>
20#include <linux/usb/hcd.h>
21#include <linux/usb/chipidea.h>
22
23#include "ci.h"
24#include "bits.h"
25#include "otg.h"
26#include "otg_fsm.h"
27
28int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
29{
30 struct usb_otg *otg;
31
32 otg = devm_kzalloc(ci->dev,
33 sizeof(struct usb_otg), GFP_KERNEL);
34 if (!otg) {
35 dev_err(ci->dev,
36 "Failed to allocate usb_otg structure for ci hdrc otg!\n");
37 return -ENOMEM;
38 }
39
40 otg->phy = ci->transceiver;
41 otg->gadget = &ci->gadget;
42 ci->fsm.otg = otg;
43 ci->transceiver->otg = ci->fsm.otg;
44 ci->fsm.power_up = 1;
45 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
46 ci->transceiver->state = OTG_STATE_UNDEFINED;
47
48 mutex_init(&ci->fsm.lock);
49
50 /* Enable A vbus valid irq */
51 hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE);
52
53 if (ci->fsm.id) {
54 ci->fsm.b_ssend_srp =
55 hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1;
56 ci->fsm.b_sess_vld =
57 hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0;
58 /* Enable BSV irq */
59 hw_write_otgsc(ci, OTGSC_BSVIE, OTGSC_BSVIE);
60 }
61
62 return 0;
63}
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 @@
1/*
2 * Copyright (C) 2014 Freescale Semiconductor, Inc.
3 *
4 * Author: Jun Li
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __DRIVERS_USB_CHIPIDEA_OTG_FSM_H
12#define __DRIVERS_USB_CHIPIDEA_OTG_FSM_H
13
14#include <linux/usb/otg-fsm.h>
15
16#ifdef CONFIG_USB_OTG_FSM
17
18int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci);
19
20#else
21
22static inline int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
23{
24 return 0;
25}
26
27#endif
28
29#endif /* __DRIVERS_USB_CHIPIDEA_OTG_FSM_H */