summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/usb-as3525.c
blob: d798d4da8308ff3599d9c2fdbf1fe5d55354f5ca (plain)
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
139
140
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright © 2008 Rafaël Carré
 *
 * 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 "config.h"
#include "system.h"
#include "usb.h"
#ifdef HAVE_USBSTACK
#include "usb_core.h"
#endif
#include "power.h"
#include "as3525.h"
#include "usb_drv.h"
#if CONFIG_USBOTG == USBOTG_DESIGNWARE
#include "usb-designware.h"

const struct usb_dw_config usb_dw_config =
{
    .phytype = DWC_PHYTYPE_UTMI_16,

    /* Available FIFO memory: 0x535 words */
    .rx_fifosz   = 0x215,
    .nptx_fifosz = 0x20,   /* 1 dedicated FIFO for IN0 */
    .ptx_fifosz  = 0x100,  /* 3 dedicated FIFOs for IN1,IN3,IN5 */

#ifdef USB_DW_ARCH_SLAVE
    .disable_double_buffering = false,
#else
    .ahb_burst_len = HBSTLEN_INCR8,
    .ahb_threshold = 8,
#endif
};
#endif /* USBOTG_DESIGNWARE */

static int usb_status = USB_EXTRACTED;

void usb_enable(bool on)
{
#if defined(HAVE_USBSTACK)
    if (on){
        cpu_boost(1);
        usb_core_init();
    } else {
        usb_core_exit();
        cpu_boost(0);
    }
#else
    (void)on;
#endif
}

void usb_insert_int(void)
{
    usb_status = USB_INSERTED;
#ifdef USB_STATUS_BY_EVENT
    usb_status_event(USB_INSERTED);
#endif
}

void usb_remove_int(void)
{
    usb_status = USB_EXTRACTED;
#ifdef USB_STATUS_BY_EVENT
    usb_status_event(USB_EXTRACTED);
#endif
}

int usb_detect(void)
{
    return usb_status;
}

void usb_init_device(void)
{
#if CONFIG_USBOTG == USBOTG_DESIGNWARE
    /* 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();
}

void usb_dw_target_enable_clocks()
{
    bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
    CCU_USB = (CCU_USB & ~(3<<24)) | (1 << 24); /* ?? */
    /* PHY clock */
    CGU_USB = 1<<5  /* enable */
        | 0 << 2
        | 0; /* source = ? (24MHz crystal?) */

    /* Do something that is probably CCU related but undocumented*/
    CCU_USB |= 0x1000;
    CCU_USB &= ~0x300000;

    udelay(400);
}

void usb_dw_target_disable_clocks()
{
    CGU_USB = 0;
    bitclr32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);

    /* reset USB_PHY to prevent power consumption */
    CCU_SRC = CCU_SRC_USB_PHY_EN;
    CCU_SRL = CCU_SRL_MAGIC_NUMBER;
    CCU_SRL = 0;
}

void usb_dw_target_enable_irq()
{
    VIC_INT_ENABLE = INTERRUPT_USB;
}

void usb_dw_target_disable_irq()
{
    VIC_INT_EN_CLEAR = INTERRUPT_USB;
}

void usb_dw_target_clear_irq()
{
#endif /* USBOTG_DESIGNWARE */
}