~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/usb/musb-new/musb_uboot.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <common.h>
 
2
#include <watchdog.h>
 
3
#include <asm/errno.h>
 
4
#include <linux/usb/ch9.h>
 
5
#include <linux/usb/gadget.h>
 
6
 
 
7
#define __UBOOT__
 
8
#include <usb.h>
 
9
#include "linux-compat.h"
 
10
#include "usb-compat.h"
 
11
#include "musb_core.h"
 
12
#include "musb_host.h"
 
13
#include "musb_gadget.h"
 
14
 
 
15
#ifdef CONFIG_MUSB_HOST
 
16
static struct musb *host;
 
17
static struct usb_hcd hcd;
 
18
static enum usb_device_speed host_speed;
 
19
 
 
20
static void musb_host_complete_urb(struct urb *urb)
 
21
{
 
22
        urb->dev->status &= ~USB_ST_NOT_PROC;
 
23
        urb->dev->act_len = urb->actual_length;
 
24
}
 
25
 
 
26
static struct usb_host_endpoint hep;
 
27
static struct urb urb;
 
28
 
 
29
static struct urb *construct_urb(struct usb_device *dev, int endpoint_type,
 
30
                                unsigned long pipe, void *buffer, int len,
 
31
                                struct devrequest *setup, int interval)
 
32
{
 
33
        int epnum = usb_pipeendpoint(pipe);
 
34
        int is_in = usb_pipein(pipe);
 
35
 
 
36
        memset(&urb, 0, sizeof(struct urb));
 
37
        memset(&hep, 0, sizeof(struct usb_host_endpoint));
 
38
        INIT_LIST_HEAD(&hep.urb_list);
 
39
        INIT_LIST_HEAD(&urb.urb_list);
 
40
        urb.ep = &hep;
 
41
        urb.complete = musb_host_complete_urb;
 
42
        urb.status = -EINPROGRESS;
 
43
        urb.dev = dev;
 
44
        urb.pipe = pipe;
 
45
        urb.transfer_buffer = buffer;
 
46
        urb.transfer_dma = (unsigned long)buffer;
 
47
        urb.transfer_buffer_length = len;
 
48
        urb.setup_packet = (unsigned char *)setup;
 
49
 
 
50
        urb.ep->desc.wMaxPacketSize =
 
51
                __cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
 
52
                                dev->epmaxpacketout[epnum]);
 
53
        urb.ep->desc.bmAttributes = endpoint_type;
 
54
        urb.ep->desc.bEndpointAddress =
 
55
                (is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
 
56
        urb.ep->desc.bInterval = interval;
 
57
 
 
58
        return &urb;
 
59
}
 
60
 
 
61
#define MUSB_HOST_TIMEOUT       0x3ffffff
 
62
 
 
63
static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 
64
{
 
65
        struct musb *host = hcd->hcd_priv;
 
66
        int ret;
 
67
        int timeout;
 
68
 
 
69
        ret = musb_urb_enqueue(hcd, urb, 0);
 
70
        if (ret < 0) {
 
71
                printf("Failed to enqueue URB to controller\n");
 
72
                return ret;
 
73
        }
 
74
 
 
75
        timeout = MUSB_HOST_TIMEOUT;
 
76
        do {
 
77
                if (ctrlc())
 
78
                        return -EIO;
 
79
                host->isr(0, host);
 
80
        } while ((urb->dev->status & USB_ST_NOT_PROC) && --timeout);
 
81
 
 
82
        return urb->status;
 
83
}
 
84
 
 
85
int submit_control_msg(struct usb_device *dev, unsigned long pipe,
 
86
                        void *buffer, int len, struct devrequest *setup)
 
87
{
 
88
        struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_CONTROL, pipe,
 
89
                                        buffer, len, setup, 0);
 
90
 
 
91
        /* Fix speed for non hub-attached devices */
 
92
        if (!dev->parent)
 
93
                dev->speed = host_speed;
 
94
 
 
95
        return submit_urb(&hcd, urb);
 
96
}
 
97
 
 
98
 
 
99
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 
100
                                        void *buffer, int len)
 
101
{
 
102
        struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_BULK, pipe,
 
103
                                        buffer, len, NULL, 0);
 
104
        return submit_urb(&hcd, urb);
 
105
}
 
106
 
 
107
int submit_int_msg(struct usb_device *dev, unsigned long pipe,
 
108
                                void *buffer, int len, int interval)
 
109
{
 
110
        struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_INT, pipe,
 
111
                                        buffer, len, NULL, interval);
 
112
        return submit_urb(&hcd, urb);
 
113
}
 
114
 
 
115
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 
116
{
 
117
        u8 power;
 
118
        void *mbase;
 
119
        int timeout = MUSB_HOST_TIMEOUT;
 
120
 
 
121
        if (!host) {
 
122
                printf("MUSB host is not registered\n");
 
123
                return -ENODEV;
 
124
        }
 
125
 
 
126
        musb_start(host);
 
127
        mbase = host->mregs;
 
128
        do {
 
129
                if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
 
130
                        break;
 
131
        } while (--timeout);
 
132
        if (!timeout)
 
133
                return -ENODEV;
 
134
 
 
135
        power = musb_readb(mbase, MUSB_POWER);
 
136
        musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
 
137
        udelay(30000);
 
138
        power = musb_readb(mbase, MUSB_POWER);
 
139
        musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
 
140
        host->isr(0, host);
 
141
        host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
 
142
                        USB_SPEED_HIGH :
 
143
                        (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
 
144
                        USB_SPEED_FULL : USB_SPEED_LOW;
 
145
        host->is_active = 1;
 
146
        hcd.hcd_priv = host;
 
147
 
 
148
        return 0;
 
149
}
 
150
 
 
151
int usb_lowlevel_stop(int index)
 
152
{
 
153
        if (!host) {
 
154
                printf("MUSB host is not registered\n");
 
155
                return -ENODEV;
 
156
        }
 
157
 
 
158
        musb_stop(host);
 
159
        return 0;
 
160
}
 
161
#endif /* CONFIG_MUSB_HOST */
 
162
 
 
163
#ifdef CONFIG_MUSB_GADGET
 
164
static struct musb *gadget;
 
165
 
 
166
int usb_gadget_handle_interrupts(void)
 
167
{
 
168
        WATCHDOG_RESET();
 
169
        if (!gadget || !gadget->isr)
 
170
                return -EINVAL;
 
171
 
 
172
        return gadget->isr(0, gadget);
 
173
}
 
174
 
 
175
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
176
{
 
177
        int ret;
 
178
 
 
179
        if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind ||
 
180
            !driver->setup) {
 
181
                printf("bad parameter.\n");
 
182
                return -EINVAL;
 
183
        }
 
184
 
 
185
        if (!gadget) {
 
186
                printf("Controller uninitialized\n");
 
187
                return -ENXIO;
 
188
        }
 
189
 
 
190
        ret = musb_gadget_start(&gadget->g, driver);
 
191
        if (ret < 0) {
 
192
                printf("gadget_start failed with %d\n", ret);
 
193
                return ret;
 
194
        }
 
195
 
 
196
        ret = driver->bind(&gadget->g);
 
197
        if (ret < 0) {
 
198
                printf("bind failed with %d\n", ret);
 
199
                return ret;
 
200
        }
 
201
 
 
202
        return 0;
 
203
}
 
204
 
 
205
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
206
{
 
207
        if (driver->disconnect)
 
208
                driver->disconnect(&gadget->g);
 
209
        if (driver->unbind)
 
210
                driver->unbind(&gadget->g);
 
211
        return 0;
 
212
}
 
213
#endif /* CONFIG_MUSB_GADGET */
 
214
 
 
215
int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
 
216
                        void *ctl_regs)
 
217
{
 
218
        struct musb **musbp;
 
219
 
 
220
        switch (plat->mode) {
 
221
#ifdef CONFIG_MUSB_HOST
 
222
        case MUSB_HOST:
 
223
                musbp = &host;
 
224
                break;
 
225
#endif
 
226
#ifdef CONFIG_MUSB_GADGET
 
227
        case MUSB_PERIPHERAL:
 
228
                musbp = &gadget;
 
229
                break;
 
230
#endif
 
231
        default:
 
232
                return -EINVAL;
 
233
        }
 
234
 
 
235
        *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs);
 
236
        if (!musbp) {
 
237
                printf("Failed to init the controller\n");
 
238
                return -EIO;
 
239
        }
 
240
 
 
241
        return 0;
 
242
}