xref: /openbmc/linux/drivers/usb/musb/sunxi.c (revision 7f8256ae)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Allwinner sun4i MUSB Glue Layer
4  *
5  * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
6  *
7  * Based on code from
8  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
9  */
10 
11 #include <linux/clk.h>
12 #include <linux/err.h>
13 #include <linux/extcon.h>
14 #include <linux/io.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/of_device.h>
19 #include <linux/phy/phy-sun4i-usb.h>
20 #include <linux/platform_device.h>
21 #include <linux/reset.h>
22 #include <linux/soc/sunxi/sunxi_sram.h>
23 #include <linux/usb/musb.h>
24 #include <linux/usb/of.h>
25 #include <linux/usb/usb_phy_generic.h>
26 #include <linux/workqueue.h>
27 #include "musb_core.h"
28 
29 /*
30  * Register offsets, note sunxi musb has a different layout then most
31  * musb implementations, we translate the layout in musb_readb & friends.
32  */
33 #define SUNXI_MUSB_POWER			0x0040
34 #define SUNXI_MUSB_DEVCTL			0x0041
35 #define SUNXI_MUSB_INDEX			0x0042
36 #define SUNXI_MUSB_VEND0			0x0043
37 #define SUNXI_MUSB_INTRTX			0x0044
38 #define SUNXI_MUSB_INTRRX			0x0046
39 #define SUNXI_MUSB_INTRTXE			0x0048
40 #define SUNXI_MUSB_INTRRXE			0x004a
41 #define SUNXI_MUSB_INTRUSB			0x004c
42 #define SUNXI_MUSB_INTRUSBE			0x0050
43 #define SUNXI_MUSB_FRAME			0x0054
44 #define SUNXI_MUSB_TXFIFOSZ			0x0090
45 #define SUNXI_MUSB_TXFIFOADD			0x0092
46 #define SUNXI_MUSB_RXFIFOSZ			0x0094
47 #define SUNXI_MUSB_RXFIFOADD			0x0096
48 #define SUNXI_MUSB_FADDR			0x0098
49 #define SUNXI_MUSB_TXFUNCADDR			0x0098
50 #define SUNXI_MUSB_TXHUBADDR			0x009a
51 #define SUNXI_MUSB_TXHUBPORT			0x009b
52 #define SUNXI_MUSB_RXFUNCADDR			0x009c
53 #define SUNXI_MUSB_RXHUBADDR			0x009e
54 #define SUNXI_MUSB_RXHUBPORT			0x009f
55 #define SUNXI_MUSB_CONFIGDATA			0x00c0
56 
57 /* VEND0 bits */
58 #define SUNXI_MUSB_VEND0_PIO_MODE		0
59 
60 /* flags */
61 #define SUNXI_MUSB_FL_ENABLED			0
62 #define SUNXI_MUSB_FL_HOSTMODE			1
63 #define SUNXI_MUSB_FL_HOSTMODE_PEND		2
64 #define SUNXI_MUSB_FL_VBUS_ON			3
65 #define SUNXI_MUSB_FL_PHY_ON			4
66 #define SUNXI_MUSB_FL_HAS_SRAM			5
67 #define SUNXI_MUSB_FL_HAS_RESET			6
68 #define SUNXI_MUSB_FL_NO_CONFIGDATA		7
69 #define SUNXI_MUSB_FL_PHY_MODE_PEND		8
70 
71 struct sunxi_musb_cfg {
72 	const struct musb_hdrc_config *hdrc_config;
73 	bool has_sram;
74 	bool has_reset;
75 	bool no_configdata;
76 };
77 
78 /* Our read/write methods need access and do not get passed in a musb ref :| */
79 static struct musb *sunxi_musb;
80 
81 struct sunxi_glue {
82 	struct device		*dev;
83 	struct musb		*musb;
84 	struct platform_device	*musb_pdev;
85 	struct clk		*clk;
86 	struct reset_control	*rst;
87 	struct phy		*phy;
88 	struct platform_device	*usb_phy;
89 	struct usb_phy		*xceiv;
90 	enum phy_mode		phy_mode;
91 	unsigned long		flags;
92 	struct work_struct	work;
93 	struct extcon_dev	*extcon;
94 	struct notifier_block	host_nb;
95 };
96 
97 /* phy_power_on / off may sleep, so we use a workqueue  */
98 static void sunxi_musb_work(struct work_struct *work)
99 {
100 	struct sunxi_glue *glue = container_of(work, struct sunxi_glue, work);
101 	bool vbus_on, phy_on;
102 
103 	if (!test_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags))
104 		return;
105 
106 	if (test_and_clear_bit(SUNXI_MUSB_FL_HOSTMODE_PEND, &glue->flags)) {
107 		struct musb *musb = glue->musb;
108 		unsigned long flags;
109 		u8 devctl;
110 
111 		spin_lock_irqsave(&musb->lock, flags);
112 
113 		devctl = readb(musb->mregs + SUNXI_MUSB_DEVCTL);
114 		if (test_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags)) {
115 			set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
116 			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
117 			MUSB_HST_MODE(musb);
118 			devctl |= MUSB_DEVCTL_SESSION;
119 		} else {
120 			clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
121 			musb->xceiv->otg->state = OTG_STATE_B_IDLE;
122 			MUSB_DEV_MODE(musb);
123 			devctl &= ~MUSB_DEVCTL_SESSION;
124 		}
125 		writeb(devctl, musb->mregs + SUNXI_MUSB_DEVCTL);
126 
127 		spin_unlock_irqrestore(&musb->lock, flags);
128 	}
129 
130 	vbus_on = test_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
131 	phy_on = test_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
132 
133 	if (phy_on != vbus_on) {
134 		if (vbus_on) {
135 			phy_power_on(glue->phy);
136 			set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
137 		} else {
138 			phy_power_off(glue->phy);
139 			clear_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
140 		}
141 	}
142 
143 	if (test_and_clear_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags))
144 		phy_set_mode(glue->phy, glue->phy_mode);
145 }
146 
147 static void sunxi_musb_set_vbus(struct musb *musb, int is_on)
148 {
149 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
150 
151 	if (is_on) {
152 		set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
153 		musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
154 	} else {
155 		clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
156 	}
157 
158 	schedule_work(&glue->work);
159 }
160 
161 static void sunxi_musb_pre_root_reset_end(struct musb *musb)
162 {
163 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
164 
165 	sun4i_usb_phy_set_squelch_detect(glue->phy, false);
166 }
167 
168 static void sunxi_musb_post_root_reset_end(struct musb *musb)
169 {
170 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
171 
172 	sun4i_usb_phy_set_squelch_detect(glue->phy, true);
173 }
174 
175 static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
176 {
177 	struct musb *musb = __hci;
178 	unsigned long flags;
179 
180 	spin_lock_irqsave(&musb->lock, flags);
181 
182 	musb->int_usb = readb(musb->mregs + SUNXI_MUSB_INTRUSB);
183 	if (musb->int_usb)
184 		writeb(musb->int_usb, musb->mregs + SUNXI_MUSB_INTRUSB);
185 
186 	if ((musb->int_usb & MUSB_INTR_RESET) && !is_host_active(musb)) {
187 		/* ep0 FADDR must be 0 when (re)entering peripheral mode */
188 		musb_ep_select(musb->mregs, 0);
189 		musb_writeb(musb->mregs, MUSB_FADDR, 0);
190 	}
191 
192 	musb->int_tx = readw(musb->mregs + SUNXI_MUSB_INTRTX);
193 	if (musb->int_tx)
194 		writew(musb->int_tx, musb->mregs + SUNXI_MUSB_INTRTX);
195 
196 	musb->int_rx = readw(musb->mregs + SUNXI_MUSB_INTRRX);
197 	if (musb->int_rx)
198 		writew(musb->int_rx, musb->mregs + SUNXI_MUSB_INTRRX);
199 
200 	musb_interrupt(musb);
201 
202 	spin_unlock_irqrestore(&musb->lock, flags);
203 
204 	return IRQ_HANDLED;
205 }
206 
207 static int sunxi_musb_host_notifier(struct notifier_block *nb,
208 				    unsigned long event, void *ptr)
209 {
210 	struct sunxi_glue *glue = container_of(nb, struct sunxi_glue, host_nb);
211 
212 	if (event)
213 		set_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags);
214 	else
215 		clear_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags);
216 
217 	set_bit(SUNXI_MUSB_FL_HOSTMODE_PEND, &glue->flags);
218 	schedule_work(&glue->work);
219 
220 	return NOTIFY_DONE;
221 }
222 
223 static int sunxi_musb_init(struct musb *musb)
224 {
225 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
226 	int ret;
227 
228 	sunxi_musb = musb;
229 	musb->phy = glue->phy;
230 	musb->xceiv = glue->xceiv;
231 
232 	if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) {
233 		ret = sunxi_sram_claim(musb->controller->parent);
234 		if (ret)
235 			return ret;
236 	}
237 
238 	ret = clk_prepare_enable(glue->clk);
239 	if (ret)
240 		goto error_sram_release;
241 
242 	if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) {
243 		ret = reset_control_deassert(glue->rst);
244 		if (ret)
245 			goto error_clk_disable;
246 	}
247 
248 	writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0);
249 
250 	/* Register notifier before calling phy_init() */
251 	ret = devm_extcon_register_notifier(glue->dev, glue->extcon,
252 					EXTCON_USB_HOST, &glue->host_nb);
253 	if (ret)
254 		goto error_reset_assert;
255 
256 	ret = phy_init(glue->phy);
257 	if (ret)
258 		goto error_reset_assert;
259 
260 	musb->isr = sunxi_musb_interrupt;
261 
262 	/* Stop the musb-core from doing runtime pm (not supported on sunxi) */
263 	pm_runtime_get(musb->controller);
264 
265 	return 0;
266 
267 error_reset_assert:
268 	if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags))
269 		reset_control_assert(glue->rst);
270 error_clk_disable:
271 	clk_disable_unprepare(glue->clk);
272 error_sram_release:
273 	if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags))
274 		sunxi_sram_release(musb->controller->parent);
275 	return ret;
276 }
277 
278 static int sunxi_musb_exit(struct musb *musb)
279 {
280 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
281 
282 	pm_runtime_put(musb->controller);
283 
284 	cancel_work_sync(&glue->work);
285 	if (test_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags))
286 		phy_power_off(glue->phy);
287 
288 	phy_exit(glue->phy);
289 
290 	if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags))
291 		reset_control_assert(glue->rst);
292 
293 	clk_disable_unprepare(glue->clk);
294 	if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags))
295 		sunxi_sram_release(musb->controller->parent);
296 
297 	devm_usb_put_phy(glue->dev, glue->xceiv);
298 
299 	return 0;
300 }
301 
302 static void sunxi_musb_enable(struct musb *musb)
303 {
304 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
305 
306 	glue->musb = musb;
307 
308 	/* musb_core does not call us in a balanced manner */
309 	if (test_and_set_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags))
310 		return;
311 
312 	schedule_work(&glue->work);
313 }
314 
315 static void sunxi_musb_disable(struct musb *musb)
316 {
317 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
318 
319 	clear_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags);
320 }
321 
322 static struct dma_controller *
323 sunxi_musb_dma_controller_create(struct musb *musb, void __iomem *base)
324 {
325 	return NULL;
326 }
327 
328 static void sunxi_musb_dma_controller_destroy(struct dma_controller *c)
329 {
330 }
331 
332 static int sunxi_musb_set_mode(struct musb *musb, u8 mode)
333 {
334 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
335 	enum phy_mode new_mode;
336 
337 	switch (mode) {
338 	case MUSB_HOST:
339 		new_mode = PHY_MODE_USB_HOST;
340 		break;
341 	case MUSB_PERIPHERAL:
342 		new_mode = PHY_MODE_USB_DEVICE;
343 		break;
344 	case MUSB_OTG:
345 		new_mode = PHY_MODE_USB_OTG;
346 		break;
347 	default:
348 		dev_err(musb->controller->parent,
349 			"Error requested mode not supported by this kernel\n");
350 		return -EINVAL;
351 	}
352 
353 	if (glue->phy_mode == new_mode)
354 		return 0;
355 
356 	if (musb->port_mode != MUSB_OTG) {
357 		dev_err(musb->controller->parent,
358 			"Error changing modes is only supported in dual role mode\n");
359 		return -EINVAL;
360 	}
361 
362 	if (musb->port1_status & USB_PORT_STAT_ENABLE)
363 		musb_root_disconnect(musb);
364 
365 	/*
366 	 * phy_set_mode may sleep, and we're called with a spinlock held,
367 	 * so let sunxi_musb_work deal with it.
368 	 */
369 	glue->phy_mode = new_mode;
370 	set_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags);
371 	schedule_work(&glue->work);
372 
373 	return 0;
374 }
375 
376 static int sunxi_musb_recover(struct musb *musb)
377 {
378 	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
379 
380 	/*
381 	 * Schedule a phy_set_mode with the current glue->phy_mode value,
382 	 * this will force end the current session.
383 	 */
384 	set_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags);
385 	schedule_work(&glue->work);
386 
387 	return 0;
388 }
389 
390 /*
391  * sunxi musb register layout
392  * 0x00 - 0x17	fifo regs, 1 long per fifo
393  * 0x40 - 0x57	generic control regs (power - frame)
394  * 0x80 - 0x8f	ep control regs (addressed through hw_ep->regs, indexed)
395  * 0x90 - 0x97	fifo control regs (indexed)
396  * 0x98 - 0x9f	multipoint / busctl regs (indexed)
397  * 0xc0		configdata reg
398  */
399 
400 static u32 sunxi_musb_fifo_offset(u8 epnum)
401 {
402 	return (epnum * 4);
403 }
404 
405 static u32 sunxi_musb_ep_offset(u8 epnum, u16 offset)
406 {
407 	WARN_ONCE(offset != 0,
408 		  "sunxi_musb_ep_offset called with non 0 offset\n");
409 
410 	return 0x80; /* indexed, so ignore epnum */
411 }
412 
413 static u32 sunxi_musb_busctl_offset(u8 epnum, u16 offset)
414 {
415 	return SUNXI_MUSB_TXFUNCADDR + offset;
416 }
417 
418 static u8 sunxi_musb_readb(void __iomem *addr, u32 offset)
419 {
420 	struct sunxi_glue *glue;
421 
422 	if (addr == sunxi_musb->mregs) {
423 		/* generic control or fifo control reg access */
424 		switch (offset) {
425 		case MUSB_FADDR:
426 			return readb(addr + SUNXI_MUSB_FADDR);
427 		case MUSB_POWER:
428 			return readb(addr + SUNXI_MUSB_POWER);
429 		case MUSB_INTRUSB:
430 			return readb(addr + SUNXI_MUSB_INTRUSB);
431 		case MUSB_INTRUSBE:
432 			return readb(addr + SUNXI_MUSB_INTRUSBE);
433 		case MUSB_INDEX:
434 			return readb(addr + SUNXI_MUSB_INDEX);
435 		case MUSB_TESTMODE:
436 			return 0; /* No testmode on sunxi */
437 		case MUSB_DEVCTL:
438 			return readb(addr + SUNXI_MUSB_DEVCTL);
439 		case MUSB_TXFIFOSZ:
440 			return readb(addr + SUNXI_MUSB_TXFIFOSZ);
441 		case MUSB_RXFIFOSZ:
442 			return readb(addr + SUNXI_MUSB_RXFIFOSZ);
443 		case MUSB_CONFIGDATA + 0x10: /* See musb_read_configdata() */
444 			glue = dev_get_drvdata(sunxi_musb->controller->parent);
445 			/* A33 saves a reg, and we get to hardcode this */
446 			if (test_bit(SUNXI_MUSB_FL_NO_CONFIGDATA,
447 				     &glue->flags))
448 				return 0xde;
449 
450 			return readb(addr + SUNXI_MUSB_CONFIGDATA);
451 		case MUSB_ULPI_BUSCONTROL:
452 			dev_warn(sunxi_musb->controller->parent,
453 				"sunxi-musb does not have ULPI bus control register\n");
454 			return 0;
455 		/* Offset for these is fixed by sunxi_musb_busctl_offset() */
456 		case SUNXI_MUSB_TXFUNCADDR:
457 		case SUNXI_MUSB_TXHUBADDR:
458 		case SUNXI_MUSB_TXHUBPORT:
459 		case SUNXI_MUSB_RXFUNCADDR:
460 		case SUNXI_MUSB_RXHUBADDR:
461 		case SUNXI_MUSB_RXHUBPORT:
462 			/* multipoint / busctl reg access */
463 			return readb(addr + offset);
464 		default:
465 			dev_err(sunxi_musb->controller->parent,
466 				"Error unknown readb offset %u\n", offset);
467 			return 0;
468 		}
469 	} else if (addr == (sunxi_musb->mregs + 0x80)) {
470 		/* ep control reg access */
471 		/* sunxi has a 2 byte hole before the txtype register */
472 		if (offset >= MUSB_TXTYPE)
473 			offset += 2;
474 		return readb(addr + offset);
475 	}
476 
477 	dev_err(sunxi_musb->controller->parent,
478 		"Error unknown readb at 0x%x bytes offset\n",
479 		(int)(addr - sunxi_musb->mregs));
480 	return 0;
481 }
482 
483 static void sunxi_musb_writeb(void __iomem *addr, unsigned offset, u8 data)
484 {
485 	if (addr == sunxi_musb->mregs) {
486 		/* generic control or fifo control reg access */
487 		switch (offset) {
488 		case MUSB_FADDR:
489 			return writeb(data, addr + SUNXI_MUSB_FADDR);
490 		case MUSB_POWER:
491 			return writeb(data, addr + SUNXI_MUSB_POWER);
492 		case MUSB_INTRUSB:
493 			return writeb(data, addr + SUNXI_MUSB_INTRUSB);
494 		case MUSB_INTRUSBE:
495 			return writeb(data, addr + SUNXI_MUSB_INTRUSBE);
496 		case MUSB_INDEX:
497 			return writeb(data, addr + SUNXI_MUSB_INDEX);
498 		case MUSB_TESTMODE:
499 			if (data)
500 				dev_warn(sunxi_musb->controller->parent,
501 					"sunxi-musb does not have testmode\n");
502 			return;
503 		case MUSB_DEVCTL:
504 			return writeb(data, addr + SUNXI_MUSB_DEVCTL);
505 		case MUSB_TXFIFOSZ:
506 			return writeb(data, addr + SUNXI_MUSB_TXFIFOSZ);
507 		case MUSB_RXFIFOSZ:
508 			return writeb(data, addr + SUNXI_MUSB_RXFIFOSZ);
509 		case MUSB_ULPI_BUSCONTROL:
510 			dev_warn(sunxi_musb->controller->parent,
511 				"sunxi-musb does not have ULPI bus control register\n");
512 			return;
513 		/* Offset for these is fixed by sunxi_musb_busctl_offset() */
514 		case SUNXI_MUSB_TXFUNCADDR:
515 		case SUNXI_MUSB_TXHUBADDR:
516 		case SUNXI_MUSB_TXHUBPORT:
517 		case SUNXI_MUSB_RXFUNCADDR:
518 		case SUNXI_MUSB_RXHUBADDR:
519 		case SUNXI_MUSB_RXHUBPORT:
520 			/* multipoint / busctl reg access */
521 			return writeb(data, addr + offset);
522 		default:
523 			dev_err(sunxi_musb->controller->parent,
524 				"Error unknown writeb offset %u\n", offset);
525 			return;
526 		}
527 	} else if (addr == (sunxi_musb->mregs + 0x80)) {
528 		/* ep control reg access */
529 		if (offset >= MUSB_TXTYPE)
530 			offset += 2;
531 		return writeb(data, addr + offset);
532 	}
533 
534 	dev_err(sunxi_musb->controller->parent,
535 		"Error unknown writeb at 0x%x bytes offset\n",
536 		(int)(addr - sunxi_musb->mregs));
537 }
538 
539 static u16 sunxi_musb_readw(void __iomem *addr, u32 offset)
540 {
541 	if (addr == sunxi_musb->mregs) {
542 		/* generic control or fifo control reg access */
543 		switch (offset) {
544 		case MUSB_INTRTX:
545 			return readw(addr + SUNXI_MUSB_INTRTX);
546 		case MUSB_INTRRX:
547 			return readw(addr + SUNXI_MUSB_INTRRX);
548 		case MUSB_INTRTXE:
549 			return readw(addr + SUNXI_MUSB_INTRTXE);
550 		case MUSB_INTRRXE:
551 			return readw(addr + SUNXI_MUSB_INTRRXE);
552 		case MUSB_FRAME:
553 			return readw(addr + SUNXI_MUSB_FRAME);
554 		case MUSB_TXFIFOADD:
555 			return readw(addr + SUNXI_MUSB_TXFIFOADD);
556 		case MUSB_RXFIFOADD:
557 			return readw(addr + SUNXI_MUSB_RXFIFOADD);
558 		case MUSB_HWVERS:
559 			return 0; /* sunxi musb version is not known */
560 		default:
561 			dev_err(sunxi_musb->controller->parent,
562 				"Error unknown readw offset %u\n", offset);
563 			return 0;
564 		}
565 	} else if (addr == (sunxi_musb->mregs + 0x80)) {
566 		/* ep control reg access */
567 		return readw(addr + offset);
568 	}
569 
570 	dev_err(sunxi_musb->controller->parent,
571 		"Error unknown readw at 0x%x bytes offset\n",
572 		(int)(addr - sunxi_musb->mregs));
573 	return 0;
574 }
575 
576 static void sunxi_musb_writew(void __iomem *addr, unsigned offset, u16 data)
577 {
578 	if (addr == sunxi_musb->mregs) {
579 		/* generic control or fifo control reg access */
580 		switch (offset) {
581 		case MUSB_INTRTX:
582 			return writew(data, addr + SUNXI_MUSB_INTRTX);
583 		case MUSB_INTRRX:
584 			return writew(data, addr + SUNXI_MUSB_INTRRX);
585 		case MUSB_INTRTXE:
586 			return writew(data, addr + SUNXI_MUSB_INTRTXE);
587 		case MUSB_INTRRXE:
588 			return writew(data, addr + SUNXI_MUSB_INTRRXE);
589 		case MUSB_FRAME:
590 			return writew(data, addr + SUNXI_MUSB_FRAME);
591 		case MUSB_TXFIFOADD:
592 			return writew(data, addr + SUNXI_MUSB_TXFIFOADD);
593 		case MUSB_RXFIFOADD:
594 			return writew(data, addr + SUNXI_MUSB_RXFIFOADD);
595 		default:
596 			dev_err(sunxi_musb->controller->parent,
597 				"Error unknown writew offset %u\n", offset);
598 			return;
599 		}
600 	} else if (addr == (sunxi_musb->mregs + 0x80)) {
601 		/* ep control reg access */
602 		return writew(data, addr + offset);
603 	}
604 
605 	dev_err(sunxi_musb->controller->parent,
606 		"Error unknown writew at 0x%x bytes offset\n",
607 		(int)(addr - sunxi_musb->mregs));
608 }
609 
610 static const struct musb_platform_ops sunxi_musb_ops = {
611 	.quirks		= MUSB_INDEXED_EP,
612 	.init		= sunxi_musb_init,
613 	.exit		= sunxi_musb_exit,
614 	.enable		= sunxi_musb_enable,
615 	.disable	= sunxi_musb_disable,
616 	.fifo_offset	= sunxi_musb_fifo_offset,
617 	.ep_offset	= sunxi_musb_ep_offset,
618 	.busctl_offset	= sunxi_musb_busctl_offset,
619 	.readb		= sunxi_musb_readb,
620 	.writeb		= sunxi_musb_writeb,
621 	.readw		= sunxi_musb_readw,
622 	.writew		= sunxi_musb_writew,
623 	.dma_init	= sunxi_musb_dma_controller_create,
624 	.dma_exit	= sunxi_musb_dma_controller_destroy,
625 	.set_mode	= sunxi_musb_set_mode,
626 	.recover	= sunxi_musb_recover,
627 	.set_vbus	= sunxi_musb_set_vbus,
628 	.pre_root_reset_end = sunxi_musb_pre_root_reset_end,
629 	.post_root_reset_end = sunxi_musb_post_root_reset_end,
630 };
631 
632 #define SUNXI_MUSB_RAM_BITS	11
633 
634 /* Allwinner OTG supports up to 5 endpoints */
635 static struct musb_fifo_cfg sunxi_musb_mode_cfg_5eps[] = {
636 	MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
637 	MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
638 	MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
639 	MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512),
640 	MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512),
641 	MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512),
642 	MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512),
643 	MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512),
644 	MUSB_EP_FIFO_SINGLE(5, FIFO_TX, 512),
645 	MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512),
646 };
647 
648 /* H3/V3s OTG supports only 4 endpoints */
649 static struct musb_fifo_cfg sunxi_musb_mode_cfg_4eps[] = {
650 	MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
651 	MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
652 	MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
653 	MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512),
654 	MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512),
655 	MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512),
656 	MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512),
657 	MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512),
658 };
659 
660 static const struct musb_hdrc_config sunxi_musb_hdrc_config_5eps = {
661 	.fifo_cfg       = sunxi_musb_mode_cfg_5eps,
662 	.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg_5eps),
663 	.multipoint	= true,
664 	.dyn_fifo	= true,
665 	/* Two FIFOs per endpoint, plus ep_0. */
666 	.num_eps	= (ARRAY_SIZE(sunxi_musb_mode_cfg_5eps) / 2) + 1,
667 	.ram_bits	= SUNXI_MUSB_RAM_BITS,
668 };
669 
670 static const struct musb_hdrc_config sunxi_musb_hdrc_config_4eps = {
671 	.fifo_cfg       = sunxi_musb_mode_cfg_4eps,
672 	.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg_4eps),
673 	.multipoint	= true,
674 	.dyn_fifo	= true,
675 	/* Two FIFOs per endpoint, plus ep_0. */
676 	.num_eps	= (ARRAY_SIZE(sunxi_musb_mode_cfg_4eps) / 2) + 1,
677 	.ram_bits	= SUNXI_MUSB_RAM_BITS,
678 };
679 
680 static int sunxi_musb_probe(struct platform_device *pdev)
681 {
682 	struct musb_hdrc_platform_data	pdata;
683 	struct platform_device_info	pinfo;
684 	struct sunxi_glue		*glue;
685 	struct device_node		*np = pdev->dev.of_node;
686 	const struct sunxi_musb_cfg	*cfg;
687 	int ret;
688 
689 	if (!np) {
690 		dev_err(&pdev->dev, "Error no device tree node found\n");
691 		return -EINVAL;
692 	}
693 
694 	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
695 	if (!glue)
696 		return -ENOMEM;
697 
698 	memset(&pdata, 0, sizeof(pdata));
699 	switch (usb_get_dr_mode(&pdev->dev)) {
700 #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST
701 	case USB_DR_MODE_HOST:
702 		pdata.mode = MUSB_HOST;
703 		glue->phy_mode = PHY_MODE_USB_HOST;
704 		break;
705 #endif
706 #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET
707 	case USB_DR_MODE_PERIPHERAL:
708 		pdata.mode = MUSB_PERIPHERAL;
709 		glue->phy_mode = PHY_MODE_USB_DEVICE;
710 		break;
711 #endif
712 #ifdef CONFIG_USB_MUSB_DUAL_ROLE
713 	case USB_DR_MODE_OTG:
714 		pdata.mode = MUSB_OTG;
715 		glue->phy_mode = PHY_MODE_USB_OTG;
716 		break;
717 #endif
718 	default:
719 		dev_err(&pdev->dev, "Invalid or missing 'dr_mode' property\n");
720 		return -EINVAL;
721 	}
722 	pdata.platform_ops	= &sunxi_musb_ops;
723 
724 	cfg = of_device_get_match_data(&pdev->dev);
725 	if (!cfg)
726 		return -EINVAL;
727 
728 	pdata.config = cfg->hdrc_config;
729 
730 	glue->dev = &pdev->dev;
731 	INIT_WORK(&glue->work, sunxi_musb_work);
732 	glue->host_nb.notifier_call = sunxi_musb_host_notifier;
733 
734 	if (cfg->has_sram)
735 		set_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags);
736 
737 	if (cfg->has_reset)
738 		set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
739 
740 	if (cfg->no_configdata)
741 		set_bit(SUNXI_MUSB_FL_NO_CONFIGDATA, &glue->flags);
742 
743 	glue->clk = devm_clk_get(&pdev->dev, NULL);
744 	if (IS_ERR(glue->clk)) {
745 		dev_err(&pdev->dev, "Error getting clock: %ld\n",
746 			PTR_ERR(glue->clk));
747 		return PTR_ERR(glue->clk);
748 	}
749 
750 	if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) {
751 		glue->rst = devm_reset_control_get(&pdev->dev, NULL);
752 		if (IS_ERR(glue->rst))
753 			return dev_err_probe(&pdev->dev, PTR_ERR(glue->rst),
754 					     "Error getting reset\n");
755 	}
756 
757 	glue->extcon = extcon_get_edev_by_phandle(&pdev->dev, 0);
758 	if (IS_ERR(glue->extcon))
759 		return dev_err_probe(&pdev->dev, PTR_ERR(glue->extcon),
760 				     "Invalid or missing extcon\n");
761 
762 	glue->phy = devm_phy_get(&pdev->dev, "usb");
763 	if (IS_ERR(glue->phy))
764 		return dev_err_probe(&pdev->dev, PTR_ERR(glue->phy),
765 				     "Error getting phy\n");
766 
767 	glue->usb_phy = usb_phy_generic_register();
768 	if (IS_ERR(glue->usb_phy)) {
769 		dev_err(&pdev->dev, "Error registering usb-phy %ld\n",
770 			PTR_ERR(glue->usb_phy));
771 		return PTR_ERR(glue->usb_phy);
772 	}
773 
774 	glue->xceiv = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
775 	if (IS_ERR(glue->xceiv)) {
776 		ret = PTR_ERR(glue->xceiv);
777 		dev_err(&pdev->dev, "Error getting usb-phy %d\n", ret);
778 		goto err_unregister_usb_phy;
779 	}
780 
781 	platform_set_drvdata(pdev, glue);
782 
783 	memset(&pinfo, 0, sizeof(pinfo));
784 	pinfo.name	 = "musb-hdrc";
785 	pinfo.id	= PLATFORM_DEVID_AUTO;
786 	pinfo.parent	= &pdev->dev;
787 	pinfo.fwnode	= of_fwnode_handle(pdev->dev.of_node);
788 	pinfo.of_node_reused = true;
789 	pinfo.res	= pdev->resource;
790 	pinfo.num_res	= pdev->num_resources;
791 	pinfo.data	= &pdata;
792 	pinfo.size_data = sizeof(pdata);
793 
794 	glue->musb_pdev = platform_device_register_full(&pinfo);
795 	if (IS_ERR(glue->musb_pdev)) {
796 		ret = PTR_ERR(glue->musb_pdev);
797 		dev_err(&pdev->dev, "Error registering musb dev: %d\n", ret);
798 		goto err_unregister_usb_phy;
799 	}
800 
801 	return 0;
802 
803 err_unregister_usb_phy:
804 	usb_phy_generic_unregister(glue->usb_phy);
805 	return ret;
806 }
807 
808 static void sunxi_musb_remove(struct platform_device *pdev)
809 {
810 	struct sunxi_glue *glue = platform_get_drvdata(pdev);
811 	struct platform_device *usb_phy = glue->usb_phy;
812 
813 	platform_device_unregister(glue->musb_pdev);
814 	usb_phy_generic_unregister(usb_phy);
815 }
816 
817 static const struct sunxi_musb_cfg sun4i_a10_musb_cfg = {
818 	.hdrc_config = &sunxi_musb_hdrc_config_5eps,
819 	.has_sram = true,
820 };
821 
822 static const struct sunxi_musb_cfg sun6i_a31_musb_cfg = {
823 	.hdrc_config = &sunxi_musb_hdrc_config_5eps,
824 	.has_reset = true,
825 };
826 
827 static const struct sunxi_musb_cfg sun8i_a33_musb_cfg = {
828 	.hdrc_config = &sunxi_musb_hdrc_config_5eps,
829 	.has_reset = true,
830 	.no_configdata = true,
831 };
832 
833 static const struct sunxi_musb_cfg sun8i_h3_musb_cfg = {
834 	.hdrc_config = &sunxi_musb_hdrc_config_4eps,
835 	.has_reset = true,
836 	.no_configdata = true,
837 };
838 
839 static const struct sunxi_musb_cfg suniv_f1c100s_musb_cfg = {
840 	.hdrc_config = &sunxi_musb_hdrc_config_5eps,
841 	.has_sram = true,
842 	.has_reset = true,
843 	.no_configdata = true,
844 };
845 
846 static const struct of_device_id sunxi_musb_match[] = {
847 	{ .compatible = "allwinner,sun4i-a10-musb",
848 	  .data = &sun4i_a10_musb_cfg, },
849 	{ .compatible = "allwinner,sun6i-a31-musb",
850 	  .data = &sun6i_a31_musb_cfg, },
851 	{ .compatible = "allwinner,sun8i-a33-musb",
852 	  .data = &sun8i_a33_musb_cfg, },
853 	{ .compatible = "allwinner,sun8i-h3-musb",
854 	  .data = &sun8i_h3_musb_cfg, },
855 	{ .compatible = "allwinner,suniv-f1c100s-musb",
856 	  .data = &suniv_f1c100s_musb_cfg, },
857 	{}
858 };
859 MODULE_DEVICE_TABLE(of, sunxi_musb_match);
860 
861 static struct platform_driver sunxi_musb_driver = {
862 	.probe = sunxi_musb_probe,
863 	.remove_new = sunxi_musb_remove,
864 	.driver = {
865 		.name = "musb-sunxi",
866 		.of_match_table = sunxi_musb_match,
867 	},
868 };
869 module_platform_driver(sunxi_musb_driver);
870 
871 MODULE_DESCRIPTION("Allwinner sunxi MUSB Glue Layer");
872 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
873 MODULE_LICENSE("GPL v2");
874