blob: d9dfaa3cf40c43e70da0c48e41803083ec9e6bc9 [file] [log] [blame]
Li Jun57677be2014-04-23 15:56:44 +08001/*
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}