1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2014 Michael Sparmann
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <inttypes.h>
#include "config.h"
#include "usb.h"
#include "usb_drv.h"
#ifdef HAVE_USBSTACK
#include "usb_core.h"
#include "power.h"
#endif
#include "s5l87xx.h"
#include "usb-designware.h"
const struct usb_dw_config usb_dw_config =
{
/* PHY must run at 60MHz, otherwise there are spurious -EPROTO
errors, probably related with GHWCFG4_MIN_AHB_FREQ. */
.phytype = DWC_PHYTYPE_UTMI_8,
/*
* Total available FIFO memory: 0x500 words.
*/
.rx_fifosz = 0x220,
/* nptx_fifosz seems limited to 0x200 due to some internal counter
misbehaviour (TBC). */
.nptx_fifosz = 0x200,
/* ptx_fifosz is not writeable (fixed to 0x300), anyway it seems
internally limited to a small number, aroung 0x10..0x20 (TBC),
we use_ptxfifo_as_plain_buffer to deal with this issue. */
.ptx_fifosz = 0x80,
.use_ptxfifo_as_plain_buffer = true,
#ifdef USB_DW_ARCH_SLAVE
.disable_double_buffering = false,
#else
.ahb_burst_len = HBSTLEN_INCR4,
#endif
};
void usb_dw_target_enable_clocks()
{
PWRCON &= ~0x4000;
PWRCONEXT &= ~0x800;
OPHYPWR = 0; /* PHY: Power up */
udelay(10);
OPHYUNK1 = 1;
OPHYUNK2 = 0xe3f;
ORSTCON = 1; /* PHY: Assert Software Reset */
udelay(10);
ORSTCON = 0; /* PHY: Deassert Software Reset */
udelay(10);
OPHYUNK3 = 0x600;
OPHYCLK = USB_DW_CLOCK;
udelay(400);
}
void usb_dw_target_disable_clocks()
{
OPHYPWR = 0xf; /* PHY: Power down */
udelay(10);
ORSTCON = 7; /* PHY: Assert Software Reset */
udelay(10);
PWRCON |= 0x4000;
PWRCONEXT |= 0x800;
}
void usb_dw_target_enable_irq()
{
INTMSK |= INTMSK_USB_OTG;
}
void usb_dw_target_disable_irq()
{
INTMSK &= ~INTMSK_USB_OTG;
}
void usb_dw_target_clear_irq()
{
SRCPND |= INTMSK_USB_OTG;
}
/* RB API fuctions */
void usb_enable(bool on)
{
#ifdef HAVE_USBSTACK
if (on){
cpu_boost(1);
usb_core_init();
} else {
usb_core_exit();
cpu_boost(0);
}
#else
(void)on;
#endif
}
int usb_detect(void)
{
#ifdef HAVE_USBSTACK
if (power_input_status() & POWER_INPUT_USB)
return USB_INSERTED;
#endif
return USB_EXTRACTED;
}
void usb_init_device(void)
{
/* Power up the core clocks to allow writing
to some registers needed to power it down */
usb_dw_target_disable_irq();
usb_dw_target_enable_clocks();
usb_drv_exit();
}
|