diff options
author | Valentine Barshak <valentine.barshak@cogentembedded.com> | 2014-01-24 17:28:47 -0500 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2014-02-04 00:28:33 -0500 |
commit | 1eabe028f8aacd7367fbdda9596cd3d64659a49f (patch) | |
tree | 082fa9a6fae0f4a3bb82312213e5f828540d7f5a | |
parent | ca1187521b78ce4f980cd1b457f8c634dd401021 (diff) |
ARM: shmobile: lager: Add USBHS support
This adds USBHS PHY and registers USBHS device if the driver is enabled.
Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
Acked-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r-- | arch/arm/mach-shmobile/board-lager.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 8dde4462f600..4a95a4593eb1 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/platform_data/camera-rcar.h> | 30 | #include <linux/platform_data/camera-rcar.h> |
31 | #include <linux/platform_data/gpio-rcar.h> | 31 | #include <linux/platform_data/gpio-rcar.h> |
32 | #include <linux/platform_data/rcar-du.h> | 32 | #include <linux/platform_data/rcar-du.h> |
33 | #include <linux/platform_data/usb-rcar-gen2-phy.h> | ||
33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
34 | #include <linux/phy.h> | 35 | #include <linux/phy.h> |
35 | #include <linux/regulator/driver.h> | 36 | #include <linux/regulator/driver.h> |
@@ -37,6 +38,8 @@ | |||
37 | #include <linux/regulator/gpio-regulator.h> | 38 | #include <linux/regulator/gpio-regulator.h> |
38 | #include <linux/regulator/machine.h> | 39 | #include <linux/regulator/machine.h> |
39 | #include <linux/sh_eth.h> | 40 | #include <linux/sh_eth.h> |
41 | #include <linux/usb/phy.h> | ||
42 | #include <linux/usb/renesas_usbhs.h> | ||
40 | #include <mach/common.h> | 43 | #include <mach/common.h> |
41 | #include <mach/irqs.h> | 44 | #include <mach/irqs.h> |
42 | #include <mach/r8a7790.h> | 45 | #include <mach/r8a7790.h> |
@@ -364,6 +367,131 @@ static const struct platform_device_info sata1_info __initconst = { | |||
364 | .dma_mask = DMA_BIT_MASK(32), | 367 | .dma_mask = DMA_BIT_MASK(32), |
365 | }; | 368 | }; |
366 | 369 | ||
370 | /* USBHS */ | ||
371 | #if IS_ENABLED(CONFIG_USB_RENESAS_USBHS_UDC) | ||
372 | static const struct resource usbhs_resources[] __initconst = { | ||
373 | DEFINE_RES_MEM(0xe6590000, 0x100), | ||
374 | DEFINE_RES_IRQ(gic_spi(107)), | ||
375 | }; | ||
376 | |||
377 | struct usbhs_private { | ||
378 | struct renesas_usbhs_platform_info info; | ||
379 | struct usb_phy *phy; | ||
380 | }; | ||
381 | |||
382 | #define usbhs_get_priv(pdev) \ | ||
383 | container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info) | ||
384 | |||
385 | static int usbhs_power_ctrl(struct platform_device *pdev, | ||
386 | void __iomem *base, int enable) | ||
387 | { | ||
388 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
389 | |||
390 | if (!priv->phy) | ||
391 | return -ENODEV; | ||
392 | |||
393 | if (enable) { | ||
394 | int retval = usb_phy_init(priv->phy); | ||
395 | |||
396 | if (!retval) | ||
397 | retval = usb_phy_set_suspend(priv->phy, 0); | ||
398 | return retval; | ||
399 | } | ||
400 | |||
401 | usb_phy_set_suspend(priv->phy, 1); | ||
402 | usb_phy_shutdown(priv->phy); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int usbhs_hardware_init(struct platform_device *pdev) | ||
407 | { | ||
408 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
409 | struct usb_phy *phy; | ||
410 | |||
411 | phy = usb_get_phy_dev(&pdev->dev, 0); | ||
412 | if (IS_ERR(phy)) | ||
413 | return PTR_ERR(phy); | ||
414 | |||
415 | priv->phy = phy; | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static int usbhs_hardware_exit(struct platform_device *pdev) | ||
420 | { | ||
421 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
422 | |||
423 | if (!priv->phy) | ||
424 | return 0; | ||
425 | |||
426 | usb_put_phy(priv->phy); | ||
427 | priv->phy = NULL; | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int usbhs_get_id(struct platform_device *pdev) | ||
432 | { | ||
433 | return USBHS_GADGET; | ||
434 | } | ||
435 | |||
436 | static u32 lager_usbhs_pipe_type[] = { | ||
437 | USB_ENDPOINT_XFER_CONTROL, | ||
438 | USB_ENDPOINT_XFER_ISOC, | ||
439 | USB_ENDPOINT_XFER_ISOC, | ||
440 | USB_ENDPOINT_XFER_BULK, | ||
441 | USB_ENDPOINT_XFER_BULK, | ||
442 | USB_ENDPOINT_XFER_BULK, | ||
443 | USB_ENDPOINT_XFER_INT, | ||
444 | USB_ENDPOINT_XFER_INT, | ||
445 | USB_ENDPOINT_XFER_INT, | ||
446 | USB_ENDPOINT_XFER_BULK, | ||
447 | USB_ENDPOINT_XFER_BULK, | ||
448 | USB_ENDPOINT_XFER_BULK, | ||
449 | USB_ENDPOINT_XFER_BULK, | ||
450 | USB_ENDPOINT_XFER_BULK, | ||
451 | USB_ENDPOINT_XFER_BULK, | ||
452 | USB_ENDPOINT_XFER_BULK, | ||
453 | }; | ||
454 | |||
455 | static struct usbhs_private usbhs_priv __initdata = { | ||
456 | .info = { | ||
457 | .platform_callback = { | ||
458 | .power_ctrl = usbhs_power_ctrl, | ||
459 | .hardware_init = usbhs_hardware_init, | ||
460 | .hardware_exit = usbhs_hardware_exit, | ||
461 | .get_id = usbhs_get_id, | ||
462 | }, | ||
463 | .driver_param = { | ||
464 | .buswait_bwait = 4, | ||
465 | .pipe_type = lager_usbhs_pipe_type, | ||
466 | .pipe_size = ARRAY_SIZE(lager_usbhs_pipe_type), | ||
467 | }, | ||
468 | } | ||
469 | }; | ||
470 | |||
471 | static void __init lager_register_usbhs(void) | ||
472 | { | ||
473 | usb_bind_phy("renesas_usbhs", 0, "usb_phy_rcar_gen2"); | ||
474 | platform_device_register_resndata(&platform_bus, | ||
475 | "renesas_usbhs", -1, | ||
476 | usbhs_resources, | ||
477 | ARRAY_SIZE(usbhs_resources), | ||
478 | &usbhs_priv.info, | ||
479 | sizeof(usbhs_priv.info)); | ||
480 | } | ||
481 | #else /* CONFIG_USB_RENESAS_USBHS_UDC */ | ||
482 | static inline void lager_register_usbhs(void) { } | ||
483 | #endif /* CONFIG_USB_RENESAS_USBHS_UDC */ | ||
484 | |||
485 | /* USBHS PHY */ | ||
486 | static const struct rcar_gen2_phy_platform_data usbhs_phy_pdata __initconst = { | ||
487 | .chan0_pci = 0, /* Channel 0 is USBHS */ | ||
488 | .chan2_pci = 1, /* Channel 2 is PCI USB */ | ||
489 | }; | ||
490 | |||
491 | static const struct resource usbhs_phy_resources[] __initconst = { | ||
492 | DEFINE_RES_MEM(0xe6590100, 0x100), | ||
493 | }; | ||
494 | |||
367 | static const struct pinctrl_map lager_pinctrl_map[] = { | 495 | static const struct pinctrl_map lager_pinctrl_map[] = { |
368 | /* DU (CN10: ARGB0, CN13: LVDS) */ | 496 | /* DU (CN10: ARGB0, CN13: LVDS) */ |
369 | PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", | 497 | PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", |
@@ -408,6 +536,9 @@ static const struct pinctrl_map lager_pinctrl_map[] = { | |||
408 | "vin1_data8", "vin1"), | 536 | "vin1_data8", "vin1"), |
409 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790", | 537 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790", |
410 | "vin1_clk", "vin1"), | 538 | "vin1_clk", "vin1"), |
539 | /* USB0 */ | ||
540 | PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7790", | ||
541 | "usb0", "usb0"), | ||
411 | }; | 542 | }; |
412 | 543 | ||
413 | static void __init lager_add_standard_devices(void) | 544 | static void __init lager_add_standard_devices(void) |
@@ -461,6 +592,13 @@ static void __init lager_add_standard_devices(void) | |||
461 | lager_add_camera1_device(); | 592 | lager_add_camera1_device(); |
462 | 593 | ||
463 | platform_device_register_full(&sata1_info); | 594 | platform_device_register_full(&sata1_info); |
595 | |||
596 | platform_device_register_resndata(&platform_bus, "usb_phy_rcar_gen2", | ||
597 | -1, usbhs_phy_resources, | ||
598 | ARRAY_SIZE(usbhs_phy_resources), | ||
599 | &usbhs_phy_pdata, | ||
600 | sizeof(usbhs_phy_pdata)); | ||
601 | lager_register_usbhs(); | ||
464 | } | 602 | } |
465 | 603 | ||
466 | /* | 604 | /* |