blob: 5a227c0ffd99636bee2ea4aab0c25f154d1a9a2c [file] [log] [blame]
Jassi Brar9c5cb7f2020-07-29 20:51:27 -05001// SPDX-License-Identifier: GPL-2.0+
2
Jassi Brar9c5cb7f2020-07-29 20:51:27 -05003#include <linux/errno.h>
4#include <linux/delay.h>
5#include <asm/gpio.h>
6#include <linux/list.h>
7#include <linux/bitfield.h>
8#include <linux/usb/ch9.h>
9#include <linux/usb/gadget.h>
10#include <malloc.h>
11#include <spi.h>
12#include <dm.h>
13#include <g_dnl.h>
14
15#define MAX3420_MAX_EPS 4
16#define EP_MAX_PACKET 64 /* Same for all Endpoints */
17#define EPNAME_SIZE 16 /* Buffer size for endpoint name */
18
19#define MAX3420_SPI_DIR_RD 0 /* read register from MAX3420 */
20#define MAX3420_SPI_DIR_WR 1 /* write register to MAX3420 */
21
22/* SPI commands: */
23#define MAX3420_SPI_ACK_MASK BIT(0)
24#define MAX3420_SPI_DIR_MASK BIT(1)
25#define MAX3420_SPI_REG_MASK GENMASK(7, 3)
26
27#define MAX3420_REG_EP0FIFO 0
28#define MAX3420_REG_EP1FIFO 1
29#define MAX3420_REG_EP2FIFO 2
30#define MAX3420_REG_EP3FIFO 3
31#define MAX3420_REG_SUDFIFO 4
32#define MAX3420_REG_EP0BC 5
33#define MAX3420_REG_EP1BC 6
34#define MAX3420_REG_EP2BC 7
35#define MAX3420_REG_EP3BC 8
36
37#define MAX3420_REG_EPSTALLS 9
38 #define bACKSTAT BIT(6)
39 #define bSTLSTAT BIT(5)
40 #define bSTLEP3IN BIT(4)
41 #define bSTLEP2IN BIT(3)
42 #define bSTLEP1OUT BIT(2)
43 #define bSTLEP0OUT BIT(1)
44 #define bSTLEP0IN BIT(0)
45
46#define MAX3420_REG_CLRTOGS 10
47 #define bEP3DISAB BIT(7)
48 #define bEP2DISAB BIT(6)
49 #define bEP1DISAB BIT(5)
50 #define bCTGEP3IN BIT(4)
51 #define bCTGEP2IN BIT(3)
52 #define bCTGEP1OUT BIT(2)
53
54#define MAX3420_REG_EPIRQ 11
55#define MAX3420_REG_EPIEN 12
56 #define bSUDAVIRQ BIT(5)
57 #define bIN3BAVIRQ BIT(4)
58 #define bIN2BAVIRQ BIT(3)
59 #define bOUT1DAVIRQ BIT(2)
60 #define bOUT0DAVIRQ BIT(1)
61 #define bIN0BAVIRQ BIT(0)
62
63#define MAX3420_REG_USBIRQ 13
64#define MAX3420_REG_USBIEN 14
65 #define bOSCOKIRQ BIT(0)
66 #define bRWUDNIRQ BIT(1)
67 #define bBUSACTIRQ BIT(2)
68 #define bURESIRQ BIT(3)
69 #define bSUSPIRQ BIT(4)
70 #define bNOVBUSIRQ BIT(5)
71 #define bVBUSIRQ BIT(6)
72 #define bURESDNIRQ BIT(7)
73
74#define MAX3420_REG_USBCTL 15
75 #define bHOSCSTEN BIT(7)
76 #define bVBGATE BIT(6)
77 #define bCHIPRES BIT(5)
78 #define bPWRDOWN BIT(4)
79 #define bCONNECT BIT(3)
80 #define bSIGRWU BIT(2)
81
82#define MAX3420_REG_CPUCTL 16
83 #define bIE BIT(0)
84
85#define MAX3420_REG_PINCTL 17
86 #define bEP3INAK BIT(7)
87 #define bEP2INAK BIT(6)
88 #define bEP0INAK BIT(5)
89 #define bFDUPSPI BIT(4)
90 #define bINTLEVEL BIT(3)
91 #define bPOSINT BIT(2)
92 #define bGPXB BIT(1)
93 #define bGPXA BIT(0)
94
95#define MAX3420_REG_REVISION 18
96
97#define MAX3420_REG_FNADDR 19
98 #define FNADDR_MASK 0x7f
99
100#define MAX3420_REG_IOPINS 20
101#define MAX3420_REG_IOPINS2 21
102#define MAX3420_REG_GPINIRQ 22
103#define MAX3420_REG_GPINIEN 23
104#define MAX3420_REG_GPINPOL 24
105#define MAX3420_REG_HIRQ 25
106#define MAX3420_REG_HIEN 26
107#define MAX3420_REG_MODE 27
108#define MAX3420_REG_PERADDR 28
109#define MAX3420_REG_HCTL 29
110#define MAX3420_REG_HXFR 30
111#define MAX3420_REG_HRSL 31
112
113struct max3420_req {
114 struct usb_request usb_req;
115 struct list_head queue;
116 struct max3420_ep *ep;
117};
118
119struct max3420_ep {
120 struct max3420_udc *udc;
121 struct list_head queue;
122 char name[EPNAME_SIZE];
123 unsigned int maxpacket;
124 struct usb_ep ep_usb;
125 int halted;
126 int id;
127};
128
129struct max3420_udc {
130 struct max3420_ep ep[MAX3420_MAX_EPS];
131 struct usb_gadget_driver *driver;
132 bool softconnect;
133 struct usb_ctrlrequest setup;
134 struct max3420_req ep0req;
135 struct usb_gadget gadget;
136 struct spi_slave *slave;
137 struct udevice *dev;
138 u8 ep0buf[64];
139 int remote_wkp;
140 bool suspended;
141};
142
143#define to_max3420_req(r) container_of((r), struct max3420_req, usb_req)
144#define to_max3420_ep(e) container_of((e), struct max3420_ep, ep_usb)
145#define to_udc(g) container_of((g), struct max3420_udc, gadget)
146
147static void spi_ack_ctrl(struct max3420_udc *udc)
148{
149 struct spi_slave *slave = udc->slave;
150 u8 txdata[1];
151
152 txdata[0] = FIELD_PREP(MAX3420_SPI_ACK_MASK, 1);
153 spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_ONCE);
154}
155
156static u8 spi_rd8_ack(struct max3420_udc *udc, u8 reg, int ackstat)
157{
158 struct spi_slave *slave = udc->slave;
159 u8 txdata[2], rxdata[2];
160
161 txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
162 FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_RD) |
163 FIELD_PREP(MAX3420_SPI_ACK_MASK, ackstat ? 1 : 0);
164
165 rxdata[0] = 0;
166 rxdata[1] = 0;
167 spi_xfer(slave, sizeof(txdata), txdata, rxdata, SPI_XFER_ONCE);
168
169 return rxdata[1];
170}
171
172static u8 spi_rd8(struct max3420_udc *udc, u8 reg)
173{
174 return spi_rd8_ack(udc, reg, 0);
175}
176
177static void spi_wr8_ack(struct max3420_udc *udc, u8 reg, u8 val, int ackstat)
178{
179 struct spi_slave *slave = udc->slave;
180 u8 txdata[2];
181
182 txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
183 FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_WR) |
184 FIELD_PREP(MAX3420_SPI_ACK_MASK, ackstat ? 1 : 0);
185 txdata[1] = val;
186
187 spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_ONCE);
188}
189
190static void spi_wr8(struct max3420_udc *udc, u8 reg, u8 val)
191{
192 spi_wr8_ack(udc, reg, val, 0);
193}
194
195static void spi_rd_buf(struct max3420_udc *udc, u8 reg, void *buf, u8 len)
196{
197 struct spi_slave *slave = udc->slave;
198 u8 txdata[1];
199
200 txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
201 FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_RD);
202
203 spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_BEGIN);
204 spi_xfer(slave, len * 8, NULL, buf, SPI_XFER_END);
205}
206
207static void spi_wr_buf(struct max3420_udc *udc, u8 reg, void *buf, u8 len)
208{
209 struct spi_slave *slave = udc->slave;
210 u8 txdata[1];
211
212 txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
213 FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_WR);
214
215 spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_BEGIN);
216 spi_xfer(slave, len * 8, buf, NULL, SPI_XFER_END);
217}
218
219/* 0 if not-connected */
220int g_dnl_board_usb_cable_connected(void)
221{
222 return 1;
223}
224
225static void spi_max3420_enable(struct max3420_ep *ep, int enable)
226{
227 struct max3420_udc *udc = ep->udc;
228 u8 epdis, epien;
229
230 if (ep->id == 0)
231 return;
232
233 epien = spi_rd8(udc, MAX3420_REG_EPIEN);
234 epdis = spi_rd8(udc, MAX3420_REG_CLRTOGS);
235
236 if (enable) {
237 epdis &= ~BIT(ep->id + 4);
238 epien |= BIT(ep->id + 1);
239 } else {
240 epdis |= BIT(ep->id + 4);
241 epien &= ~BIT(ep->id + 1);
242 }
243
244 spi_wr8(udc, MAX3420_REG_CLRTOGS, epdis);
245 spi_wr8(udc, MAX3420_REG_EPIEN, epien);
246}
247
248static int
249max3420_ep_enable(struct usb_ep *_ep,
250 const struct usb_endpoint_descriptor *desc)
251{
252 struct max3420_ep *ep = to_max3420_ep(_ep);
253
254 _ep->desc = desc;
255 _ep->maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
256
257 spi_max3420_enable(ep, 1);
258
259 return 0;
260}
261
262static void max3420_req_done(struct max3420_req *req, int status)
263{
264 struct max3420_ep *ep = req->ep;
265
266 if (req->usb_req.status == -EINPROGRESS)
267 req->usb_req.status = status;
268 else
269 status = req->usb_req.status;
270
271 if (status && status != -ESHUTDOWN)
272 dev_err(ep->udc->dev, "%s done %p, status %d\n",
273 ep->ep_usb.name, req, status);
274
275 if (req->usb_req.complete)
276 req->usb_req.complete(&ep->ep_usb, &req->usb_req);
277}
278
279static void max3420_ep_nuke(struct max3420_ep *ep, int status)
280{
281 struct max3420_req *req, *r;
282
283 list_for_each_entry_safe(req, r, &ep->queue, queue) {
284 list_del_init(&req->queue);
285 max3420_req_done(req, status);
286 }
287}
288
289static int max3420_ep_disable(struct usb_ep *_ep)
290{
291 struct max3420_ep *ep = to_max3420_ep(_ep);
292
293 _ep->desc = NULL;
294 max3420_ep_nuke(ep, -ESHUTDOWN);
295 spi_max3420_enable(ep, 0);
296
297 return 0;
298}
299
300static struct usb_request *
301max3420_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
302{
303 struct max3420_ep *ep = to_max3420_ep(_ep);
304 struct max3420_req *req = kzalloc(sizeof(*req), gfp_flags);
305
306 if (!req)
307 return NULL;
308
309 req->ep = ep;
310 INIT_LIST_HEAD(&req->queue);
311
312 return &req->usb_req;
313}
314
315static void
316max3420_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
317{
318 kfree(to_max3420_req(_req));
319}
320
321static int
322max3420_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
323{
324 struct max3420_req *req = to_max3420_req(_req);
325 struct max3420_ep *ep = to_max3420_ep(_ep);
326
327 _req->status = -EINPROGRESS;
328 _req->actual = 0;
329 list_add_tail(&req->queue, &ep->queue);
330
331 return 0;
332}
333
334static int max3420_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
335{
336 struct max3420_req *req = to_max3420_req(_req);
337
338 list_del_init(&req->queue);
339 max3420_req_done(req, -ECONNRESET);
340
341 return 0;
342}
343
344static int max3420_ep_set_halt(struct usb_ep *_ep, int halt)
345{
346 struct max3420_ep *ep = to_max3420_ep(_ep);
347 struct max3420_udc *udc = ep->udc;
348 u8 epstalls;
349
350 if (ep->id == 0) /* can't stall EP0 */
351 return 0;
352
353 epstalls = spi_rd8(udc, MAX3420_REG_EPSTALLS);
354 if (halt) {
355 ep->halted = 1;
356 epstalls |= BIT(ep->id + 1);
357 } else {
358 u8 clrtogs;
359
360 ep->halted = 0;
361 epstalls &= ~BIT(ep->id + 1);
362 clrtogs = spi_rd8(udc, MAX3420_REG_CLRTOGS);
363 clrtogs |= BIT(ep->id + 1);
364 spi_wr8(udc, MAX3420_REG_CLRTOGS, clrtogs);
365 }
366 spi_wr8(udc, MAX3420_REG_EPSTALLS, epstalls | bACKSTAT);
367
368 return 0;
369}
370
371static const struct usb_ep_ops max3420_ep_ops = {
372 .enable = max3420_ep_enable,
373 .disable = max3420_ep_disable,
374 .alloc_request = max3420_ep_alloc_request,
375 .free_request = max3420_ep_free_request,
376 .queue = max3420_ep_queue,
377 .dequeue = max3420_ep_dequeue,
378 .set_halt = max3420_ep_set_halt,
379};
380
381static void __max3420_stop(struct max3420_udc *udc)
382{
383 u8 val;
384
385 /* Disable IRQ to CPU */
386 spi_wr8(udc, MAX3420_REG_CPUCTL, 0);
387
388 val = spi_rd8(udc, MAX3420_REG_USBCTL);
389 val |= bPWRDOWN;
390 val |= bHOSCSTEN;
391 spi_wr8(udc, MAX3420_REG_USBCTL, val);
392}
393
394static void __max3420_start(struct max3420_udc *udc)
395{
396 u8 val;
397
398 /* configure SPI */
399 spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
400
401 /* Chip Reset */
402 spi_wr8(udc, MAX3420_REG_USBCTL, bCHIPRES);
403 mdelay(5);
404 spi_wr8(udc, MAX3420_REG_USBCTL, 0);
405
406 /* Poll for OSC to stabilize */
407 while (1) {
408 val = spi_rd8(udc, MAX3420_REG_USBIRQ);
409 if (val & bOSCOKIRQ)
410 break;
411 cond_resched();
412 }
413
414 /* Enable PULL-UP only when Vbus detected */
415 val = spi_rd8(udc, MAX3420_REG_USBCTL);
416 val |= bVBGATE | bCONNECT;
417 spi_wr8(udc, MAX3420_REG_USBCTL, val);
418
419 val = bURESDNIRQ | bURESIRQ;
420 spi_wr8(udc, MAX3420_REG_USBIEN, val);
421
422 /* Enable only EP0 interrupts */
423 val = bIN0BAVIRQ | bOUT0DAVIRQ | bSUDAVIRQ;
424 spi_wr8(udc, MAX3420_REG_EPIEN, val);
425
426 /* Enable IRQ to CPU */
427 spi_wr8(udc, MAX3420_REG_CPUCTL, bIE);
428}
429
430static int max3420_udc_start(struct usb_gadget *gadget,
431 struct usb_gadget_driver *driver)
432{
433 struct max3420_udc *udc = to_udc(gadget);
434
435 udc->driver = driver;
436 udc->remote_wkp = 0;
437 udc->softconnect = true;
438
439 __max3420_start(udc);
440
441 return 0;
442}
443
444static int max3420_udc_stop(struct usb_gadget *gadget)
445{
446 struct max3420_udc *udc = to_udc(gadget);
447
448 udc->driver = NULL;
449 udc->softconnect = false;
450
451 __max3420_stop(udc);
452
453 return 0;
454}
455
456static int max3420_wakeup(struct usb_gadget *gadget)
457{
458 struct max3420_udc *udc = to_udc(gadget);
459 u8 usbctl;
460
461 /* Only if wakeup allowed by host */
462 if (!udc->remote_wkp || !udc->suspended)
463 return 0;
464
465 /* Set Remote-Wakeup Signal*/
466 usbctl = spi_rd8(udc, MAX3420_REG_USBCTL);
467 usbctl |= bSIGRWU;
468 spi_wr8(udc, MAX3420_REG_USBCTL, usbctl);
469
470 mdelay(5);
471
472 /* Clear Remote-WkUp Signal*/
473 usbctl = spi_rd8(udc, MAX3420_REG_USBCTL);
474 usbctl &= ~bSIGRWU;
475 spi_wr8(udc, MAX3420_REG_USBCTL, usbctl);
476
477 udc->suspended = false;
478
479 return 0;
480}
481
482static const struct usb_gadget_ops max3420_udc_ops = {
483 .udc_start = max3420_udc_start,
484 .udc_stop = max3420_udc_stop,
485 .wakeup = max3420_wakeup,
486};
487
488static struct usb_endpoint_descriptor ep0_desc = {
489 .bLength = USB_DT_ENDPOINT_SIZE,
490 .bDescriptorType = USB_DT_ENDPOINT,
491 .bEndpointAddress = USB_DIR_OUT,
492 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
493 .wMaxPacketSize = cpu_to_le16(EP_MAX_PACKET),
494};
495
496static void max3420_getstatus(struct max3420_udc *udc)
497{
498 struct max3420_ep *ep;
499 u16 status = 0;
500
501 switch (udc->setup.bRequestType & USB_RECIP_MASK) {
502 case USB_RECIP_DEVICE:
503 /* Get device status */
504 status = 0 << USB_DEVICE_SELF_POWERED;
505 status |= (udc->remote_wkp << USB_DEVICE_REMOTE_WAKEUP);
506 break;
507 case USB_RECIP_INTERFACE:
508 if (udc->driver->setup(&udc->gadget, &udc->setup) < 0)
509 goto stall;
510 break;
511 case USB_RECIP_ENDPOINT:
512 ep = &udc->ep[udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK];
513 if (ep->halted)
514 status = 1 << USB_ENDPOINT_HALT;
515 break;
516 default:
517 goto stall;
518 }
519
520 status = cpu_to_le16(status);
521 spi_wr_buf(udc, MAX3420_REG_EP0FIFO, &status, 2);
522 spi_wr8_ack(udc, MAX3420_REG_EP0BC, 2, 1);
523 return;
524stall:
525 dev_err(udc->dev, "Can't respond to getstatus request\n");
526 spi_wr8(udc, MAX3420_REG_EPSTALLS, bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
527}
528
529static void max3420_set_clear_feature(struct max3420_udc *udc)
530{
531 int set = udc->setup.bRequest == USB_REQ_SET_FEATURE;
532 struct max3420_ep *ep;
533 int id;
534
535 switch (udc->setup.bRequestType) {
536 case USB_RECIP_DEVICE:
537 if (udc->setup.wValue != USB_DEVICE_REMOTE_WAKEUP)
538 break;
539
540 if (udc->setup.bRequest == USB_REQ_SET_FEATURE)
541 udc->remote_wkp = 1;
542 else
543 udc->remote_wkp = 0;
544
545 return spi_ack_ctrl(udc);
546
547 case USB_RECIP_ENDPOINT:
548 if (udc->setup.wValue != USB_ENDPOINT_HALT)
549 break;
550
551 id = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK;
552 ep = &udc->ep[id];
553
554 max3420_ep_set_halt(&ep->ep_usb, set);
555 return;
556 default:
557 break;
558 }
559
560 dev_err(udc->dev, "Can't respond to SET/CLEAR FEATURE\n");
561 spi_wr8(udc, MAX3420_REG_EPSTALLS, bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
562}
563
564static void max3420_handle_setup(struct max3420_udc *udc)
565{
566 struct usb_ctrlrequest setup;
567 u8 addr;
568
569 spi_rd_buf(udc, MAX3420_REG_SUDFIFO, (void *)&setup, 8);
570
571 udc->setup = setup;
572 udc->setup.wValue = cpu_to_le16(setup.wValue);
573 udc->setup.wIndex = cpu_to_le16(setup.wIndex);
574 udc->setup.wLength = cpu_to_le16(setup.wLength);
575
576 switch (udc->setup.bRequest) {
577 case USB_REQ_GET_STATUS:
578 /* Data+Status phase form udc */
579 if ((udc->setup.bRequestType &
580 (USB_DIR_IN | USB_TYPE_MASK)) !=
581 (USB_DIR_IN | USB_TYPE_STANDARD)) {
582 break;
583 }
584 return max3420_getstatus(udc);
585 case USB_REQ_SET_ADDRESS:
586 /* Status phase from udc */
587 if (udc->setup.bRequestType != (USB_DIR_OUT |
588 USB_TYPE_STANDARD | USB_RECIP_DEVICE))
589 break;
590 addr = spi_rd8_ack(udc, MAX3420_REG_FNADDR, 1);
591 dev_dbg(udc->dev, "Assigned Address=%d/%d\n",
592 udc->setup.wValue, addr);
593 return;
594 case USB_REQ_CLEAR_FEATURE:
595 case USB_REQ_SET_FEATURE:
596 /* Requests with no data phase, status phase from udc */
597 if ((udc->setup.bRequestType & USB_TYPE_MASK)
598 != USB_TYPE_STANDARD)
599 break;
600 return max3420_set_clear_feature(udc);
601 default:
602 break;
603 }
604
605 if (udc->driver->setup(&udc->gadget, &setup) < 0) {
606 /* Stall EP0 */
607 spi_wr8(udc, MAX3420_REG_EPSTALLS,
608 bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
609 }
610}
611
612static int do_data(struct max3420_udc *udc, int ep_id, int in)
613{
614 struct max3420_ep *ep = &udc->ep[ep_id];
615 struct max3420_req *req;
616 int done, length, psz;
617 void *buf;
618
619 if (list_empty(&ep->queue))
620 return 0;
621
622 req = list_first_entry(&ep->queue, struct max3420_req, queue);
623 buf = req->usb_req.buf + req->usb_req.actual;
624
625 psz = ep->ep_usb.maxpacket;
626 length = req->usb_req.length - req->usb_req.actual;
627 length = min(length, psz);
628
629 if (length == 0) {
630 done = 1;
631 goto xfer_done;
632 }
633
634 done = 0;
635 if (in) {
636 spi_wr_buf(udc, MAX3420_REG_EP0FIFO + ep_id, buf, length);
637 spi_wr8(udc, MAX3420_REG_EP0BC + ep_id, length);
638 if (length < psz)
639 done = 1;
640 } else {
641 psz = spi_rd8(udc, MAX3420_REG_EP0BC + ep_id);
642 length = min(length, psz);
643 spi_rd_buf(udc, MAX3420_REG_EP0FIFO + ep_id, buf, length);
644 if (length < ep->ep_usb.maxpacket)
645 done = 1;
646 }
647
648 req->usb_req.actual += length;
649
650 if (req->usb_req.actual == req->usb_req.length)
651 done = 1;
652
653xfer_done:
654 if (done) {
655 list_del_init(&req->queue);
656
657 if (ep_id == 0)
658 spi_ack_ctrl(udc);
659
660 max3420_req_done(req, 0);
661 }
662
663 return 1;
664}
665
666static int max3420_handle_irqs(struct max3420_udc *udc)
667{
668 u8 epien, epirq, usbirq, usbien, reg[4];
669 int ret = 0;
670
671 spi_rd_buf(udc, MAX3420_REG_EPIRQ, reg, 4);
672 epirq = reg[0];
673 epien = reg[1];
674 usbirq = reg[2];
675 usbien = reg[3];
676
677 usbirq &= usbien;
678 epirq &= epien;
679
680 if (epirq & bSUDAVIRQ) {
681 spi_wr8(udc, MAX3420_REG_EPIRQ, bSUDAVIRQ);
682 max3420_handle_setup(udc);
683 return 1;
684 }
685
686 if (usbirq & bVBUSIRQ) {
687 spi_wr8(udc, MAX3420_REG_USBIRQ, bVBUSIRQ);
688 dev_dbg(udc->dev, "Cable plugged in\n");
689 g_dnl_clear_detach();
690 return 1;
691 }
692
693 if (usbirq & bNOVBUSIRQ) {
694 spi_wr8(udc, MAX3420_REG_USBIRQ, bNOVBUSIRQ);
695 dev_dbg(udc->dev, "Cable pulled out\n");
696 g_dnl_trigger_detach();
697 return 1;
698 }
699
700 if (usbirq & bURESIRQ) {
701 spi_wr8(udc, MAX3420_REG_USBIRQ, bURESIRQ);
702 return 1;
703 }
704
705 if (usbirq & bURESDNIRQ) {
706 spi_wr8(udc, MAX3420_REG_USBIRQ, bURESDNIRQ);
707 spi_wr8(udc, MAX3420_REG_USBIEN, bURESDNIRQ | bURESIRQ);
708 spi_wr8(udc, MAX3420_REG_EPIEN, bSUDAVIRQ
709 | bIN0BAVIRQ | bOUT0DAVIRQ);
710 return 1;
711 }
712
713 if (usbirq & bSUSPIRQ) {
714 spi_wr8(udc, MAX3420_REG_USBIRQ, bSUSPIRQ);
715 dev_dbg(udc->dev, "USB Suspend - Enter\n");
716 udc->suspended = true;
717 return 1;
718 }
719
720 if (usbirq & bBUSACTIRQ) {
721 spi_wr8(udc, MAX3420_REG_USBIRQ, bBUSACTIRQ);
722 dev_dbg(udc->dev, "USB Suspend - Exit\n");
723 udc->suspended = false;
724 return 1;
725 }
726
727 if (usbirq & bRWUDNIRQ) {
728 spi_wr8(udc, MAX3420_REG_USBIRQ, bRWUDNIRQ);
729 dev_dbg(udc->dev, "Asked Host to wakeup\n");
730 return 1;
731 }
732
733 if (usbirq & bOSCOKIRQ) {
734 spi_wr8(udc, MAX3420_REG_USBIRQ, bOSCOKIRQ);
735 dev_dbg(udc->dev, "Osc stabilized, start work\n");
736 return 1;
737 }
738
739 if (epirq & bOUT0DAVIRQ && do_data(udc, 0, 0)) {
740 spi_wr8_ack(udc, MAX3420_REG_EPIRQ, bOUT0DAVIRQ, 1);
741 ret = 1;
742 }
743
744 if (epirq & bIN0BAVIRQ && do_data(udc, 0, 1))
745 ret = 1;
746
747 if (epirq & bOUT1DAVIRQ && do_data(udc, 1, 0)) {
748 spi_wr8_ack(udc, MAX3420_REG_EPIRQ, bOUT1DAVIRQ, 1);
749 ret = 1;
750 }
751
752 if (epirq & bIN2BAVIRQ && do_data(udc, 2, 1))
753 ret = 1;
754
755 if (epirq & bIN3BAVIRQ && do_data(udc, 3, 1))
756 ret = 1;
757
758 return ret;
759}
760
761static int max3420_irq(struct max3420_udc *udc)
762{
763 do_data(udc, 0, 1); /* get done with the EP0 ZLP */
764
765 return max3420_handle_irqs(udc);
766}
767
768static void max3420_setup_eps(struct max3420_udc *udc)
769{
770 int i;
771
772 INIT_LIST_HEAD(&udc->gadget.ep_list);
773 INIT_LIST_HEAD(&udc->ep[0].ep_usb.ep_list);
774
775 for (i = 0; i < MAX3420_MAX_EPS; i++) {
776 struct max3420_ep *ep = &udc->ep[i];
777
778 INIT_LIST_HEAD(&ep->queue);
779
780 ep->id = i;
781 ep->udc = udc;
782 ep->ep_usb.ops = &max3420_ep_ops;
783 ep->ep_usb.name = ep->name;
784 ep->ep_usb.maxpacket = EP_MAX_PACKET;
785
786 if (i == 0) {
787 ep->ep_usb.desc = &ep0_desc;
788 snprintf(ep->name, EPNAME_SIZE, "ep0");
789 continue;
790 }
791
792 list_add_tail(&ep->ep_usb.ep_list, &udc->gadget.ep_list);
793
794 if (i == 1)
795 snprintf(ep->name, EPNAME_SIZE, "ep1out-bulk");
796 else
797 snprintf(ep->name, EPNAME_SIZE, "ep%din-bulk", i);
798 };
799}
800
801static void max3420_setup_spi(struct max3420_udc *udc)
802{
803 u8 reg[8];
804
805 spi_claim_bus(udc->slave);
806 spi_rd_buf(udc, MAX3420_REG_EPIRQ, reg, 8);
807 /* configure SPI */
808 spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
809}
810
811int dm_usb_gadget_handle_interrupts(struct udevice *dev)
812{
813 struct max3420_udc *udc = dev_get_priv(dev);
814
815 return max3420_irq(udc);
816}
817
818static int max3420_udc_probe(struct udevice *dev)
819{
820 struct max3420_udc *udc = dev_get_priv(dev);
Simon Glassb75b15b2020-12-03 16:55:23 -0700821 struct dm_spi_slave_plat *slave_pdata;
Jassi Brar9c5cb7f2020-07-29 20:51:27 -0500822 struct udevice *bus = dev->parent;
Simon Glass75e534b2020-12-16 21:20:07 -0700823 int busnum = dev_seq(bus);
Jassi Brar9c5cb7f2020-07-29 20:51:27 -0500824 unsigned int cs;
825 uint speed, mode;
826 struct udevice *spid;
827
Simon Glass71fa5b42020-12-03 16:55:18 -0700828 slave_pdata = dev_get_parent_plat(dev);
Jassi Brar9c5cb7f2020-07-29 20:51:27 -0500829 cs = slave_pdata->cs;
830 speed = slave_pdata->max_hz;
831 mode = slave_pdata->mode;
Patrice Chotard86e06ae2022-03-30 09:33:13 +0200832 _spi_get_bus_and_cs(busnum, cs, speed, mode, false, "spi_generic_drv",
833 NULL, &spid, &udc->slave);
Jassi Brar9c5cb7f2020-07-29 20:51:27 -0500834
835 udc->dev = dev;
836 udc->gadget.ep0 = &udc->ep[0].ep_usb;
837 udc->gadget.max_speed = USB_SPEED_FULL;
838 udc->gadget.speed = USB_SPEED_FULL;
839 udc->gadget.is_dualspeed = 0;
840 udc->gadget.ops = &max3420_udc_ops;
841 udc->gadget.name = "max3420-udc";
842
843 max3420_setup_eps(udc);
844 max3420_setup_spi(udc);
845
846 usb_add_gadget_udc((struct device *)dev, &udc->gadget);
847
848 return 0;
849}
850
851static int max3420_udc_remove(struct udevice *dev)
852{
853 struct max3420_udc *udc = dev_get_priv(dev);
854
855 usb_del_gadget_udc(&udc->gadget);
856
857 spi_release_bus(udc->slave);
858
859 return 0;
860}
861
862static const struct udevice_id max3420_ids[] = {
863 { .compatible = "maxim,max3421-udc" },
864 { }
865};
866
867U_BOOT_DRIVER(max3420_generic_udc) = {
868 .name = "max3420-udc",
869 .id = UCLASS_USB_GADGET_GENERIC,
870 .of_match = max3420_ids,
871 .probe = max3420_udc_probe,
872 .remove = max3420_udc_remove,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700873 .priv_auto = sizeof(struct max3420_udc),
Jassi Brar9c5cb7f2020-07-29 20:51:27 -0500874};