aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs
diff options
context:
space:
mode:
authorUlrich Hecht <ulrich.hecht@gmail.com>2014-07-10 03:53:59 -0400
committerFelipe Balbi <balbi@ti.com>2014-07-16 11:06:32 -0400
commit8ecef00fe1f33658ee36e902dba6850b51312073 (patch)
tree208ab3f29e228e55fabac17423413d528152f7fa /drivers/usb/renesas_usbhs
parentf2267089ea17fa97b796b1b4247e3f8957655df3 (diff)
usb: renesas_usbhs: add R-Car Gen. 2 init and power control
In preparation for DT conversion to reduce reliance on platform device callbacks. Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/renesas_usbhs')
-rw-r--r--drivers/usb/renesas_usbhs/Makefile2
-rw-r--r--drivers/usb/renesas_usbhs/common.c66
-rw-r--r--drivers/usb/renesas_usbhs/common.h2
-rw-r--r--drivers/usb/renesas_usbhs/rcar2.c77
-rw-r--r--drivers/usb/renesas_usbhs/rcar2.h4
5 files changed, 145 insertions, 6 deletions
diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile
index bc8aef4311a1..9e47f477b6d2 100644
--- a/drivers/usb/renesas_usbhs/Makefile
+++ b/drivers/usb/renesas_usbhs/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o 5obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o
6 6
7renesas_usbhs-y := common.o mod.o pipe.o fifo.o 7renesas_usbhs-y := common.o mod.o pipe.o fifo.o rcar2.o
8 8
9ifneq ($(CONFIG_USB_RENESAS_USBHS_HCD),) 9ifneq ($(CONFIG_USB_RENESAS_USBHS_HCD),)
10 renesas_usbhs-y += mod_host.o 10 renesas_usbhs-y += mod_host.o
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index 17267b0a2e95..1b9bf8d83235 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -15,12 +15,14 @@
15 * 15 *
16 */ 16 */
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/gpio.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/pm_runtime.h> 21#include <linux/pm_runtime.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/sysfs.h> 23#include <linux/sysfs.h>
23#include "common.h" 24#include "common.h"
25#include "rcar2.h"
24 26
25/* 27/*
26 * image of renesas_usbhs 28 * image of renesas_usbhs
@@ -284,6 +286,8 @@ static void usbhsc_set_buswait(struct usbhs_priv *priv)
284/* 286/*
285 * platform default param 287 * platform default param
286 */ 288 */
289
290/* commonly used on old SH-Mobile SoCs */
287static u32 usbhsc_default_pipe_type[] = { 291static u32 usbhsc_default_pipe_type[] = {
288 USB_ENDPOINT_XFER_CONTROL, 292 USB_ENDPOINT_XFER_CONTROL,
289 USB_ENDPOINT_XFER_ISOC, 293 USB_ENDPOINT_XFER_ISOC,
@@ -297,6 +301,26 @@ static u32 usbhsc_default_pipe_type[] = {
297 USB_ENDPOINT_XFER_INT, 301 USB_ENDPOINT_XFER_INT,
298}; 302};
299 303
304/* commonly used on newer SH-Mobile and R-Car SoCs */
305static u32 usbhsc_new_pipe_type[] = {
306 USB_ENDPOINT_XFER_CONTROL,
307 USB_ENDPOINT_XFER_ISOC,
308 USB_ENDPOINT_XFER_ISOC,
309 USB_ENDPOINT_XFER_BULK,
310 USB_ENDPOINT_XFER_BULK,
311 USB_ENDPOINT_XFER_BULK,
312 USB_ENDPOINT_XFER_INT,
313 USB_ENDPOINT_XFER_INT,
314 USB_ENDPOINT_XFER_INT,
315 USB_ENDPOINT_XFER_BULK,
316 USB_ENDPOINT_XFER_BULK,
317 USB_ENDPOINT_XFER_BULK,
318 USB_ENDPOINT_XFER_BULK,
319 USB_ENDPOINT_XFER_BULK,
320 USB_ENDPOINT_XFER_BULK,
321 USB_ENDPOINT_XFER_BULK,
322};
323
300/* 324/*
301 * power control 325 * power control
302 */ 326 */
@@ -423,8 +447,7 @@ static int usbhs_probe(struct platform_device *pdev)
423 int ret; 447 int ret;
424 448
425 /* check platform information */ 449 /* check platform information */
426 if (!info || 450 if (!info) {
427 !info->platform_callback.get_id) {
428 dev_err(&pdev->dev, "no platform information\n"); 451 dev_err(&pdev->dev, "no platform information\n");
429 return -EINVAL; 452 return -EINVAL;
430 } 453 }
@@ -451,13 +474,32 @@ static int usbhs_probe(struct platform_device *pdev)
451 /* 474 /*
452 * care platform info 475 * care platform info
453 */ 476 */
454 memcpy(&priv->pfunc, 477
455 &info->platform_callback,
456 sizeof(struct renesas_usbhs_platform_callback));
457 memcpy(&priv->dparam, 478 memcpy(&priv->dparam,
458 &info->driver_param, 479 &info->driver_param,
459 sizeof(struct renesas_usbhs_driver_param)); 480 sizeof(struct renesas_usbhs_driver_param));
460 481
482 switch (priv->dparam.type) {
483 case USBHS_TYPE_R8A7790:
484 case USBHS_TYPE_R8A7791:
485 priv->pfunc = usbhs_rcar2_ops;
486 if (!priv->dparam.pipe_type) {
487 priv->dparam.pipe_type = usbhsc_new_pipe_type;
488 priv->dparam.pipe_size =
489 ARRAY_SIZE(usbhsc_new_pipe_type);
490 }
491 break;
492 default:
493 if (!info->platform_callback.get_id) {
494 dev_err(&pdev->dev, "no platform callbacks");
495 return -EINVAL;
496 }
497 memcpy(&priv->pfunc,
498 &info->platform_callback,
499 sizeof(struct renesas_usbhs_platform_callback));
500 break;
501 }
502
461 /* set driver callback functions for platform */ 503 /* set driver callback functions for platform */
462 dfunc = &info->driver_callback; 504 dfunc = &info->driver_callback;
463 dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; 505 dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug;
@@ -507,6 +549,20 @@ static int usbhs_probe(struct platform_device *pdev)
507 */ 549 */
508 usbhs_sys_clock_ctrl(priv, 0); 550 usbhs_sys_clock_ctrl(priv, 0);
509 551
552 /* check GPIO determining if USB function should be enabled */
553 if (priv->dparam.enable_gpio) {
554 gpio_request_one(priv->dparam.enable_gpio, GPIOF_IN, NULL);
555 ret = !gpio_get_value(priv->dparam.enable_gpio);
556 gpio_free(priv->dparam.enable_gpio);
557 if (ret) {
558 dev_warn(&pdev->dev,
559 "USB function not selected (GPIO %d)\n",
560 priv->dparam.enable_gpio);
561 ret = -ENOTSUPP;
562 goto probe_end_mod_exit;
563 }
564 }
565
510 /* 566 /*
511 * platform call 567 * platform call
512 * 568 *
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index c69dd2fba360..a7996da6a1bd 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -268,6 +268,8 @@ struct usbhs_priv {
268 * fifo control 268 * fifo control
269 */ 269 */
270 struct usbhs_fifo_info fifo_info; 270 struct usbhs_fifo_info fifo_info;
271
272 struct usb_phy *phy;
271}; 273};
272 274
273/* 275/*
diff --git a/drivers/usb/renesas_usbhs/rcar2.c b/drivers/usb/renesas_usbhs/rcar2.c
new file mode 100644
index 000000000000..e6b9dcc1c289
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/rcar2.c
@@ -0,0 +1,77 @@
1/*
2 * Renesas USB driver R-Car Gen. 2 initialization and power control
3 *
4 * Copyright (C) 2014 Ulrich Hecht
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 */
12
13#include <linux/gpio.h>
14#include <linux/of_gpio.h>
15#include <linux/platform_data/gpio-rcar.h>
16#include <linux/usb/phy.h>
17#include "common.h"
18#include "rcar2.h"
19
20static int usbhs_rcar2_hardware_init(struct platform_device *pdev)
21{
22 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
23 struct usb_phy *phy;
24
25 phy = usb_get_phy_dev(&pdev->dev, 0);
26 if (IS_ERR(phy))
27 return PTR_ERR(phy);
28
29 priv->phy = phy;
30 return 0;
31}
32
33static int usbhs_rcar2_hardware_exit(struct platform_device *pdev)
34{
35 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
36
37 if (!priv->phy)
38 return 0;
39
40 usb_put_phy(priv->phy);
41 priv->phy = NULL;
42
43 return 0;
44}
45
46static int usbhs_rcar2_power_ctrl(struct platform_device *pdev,
47 void __iomem *base, int enable)
48{
49 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
50
51 if (!priv->phy)
52 return -ENODEV;
53
54 if (enable) {
55 int retval = usb_phy_init(priv->phy);
56
57 if (!retval)
58 retval = usb_phy_set_suspend(priv->phy, 0);
59 return retval;
60 }
61
62 usb_phy_set_suspend(priv->phy, 1);
63 usb_phy_shutdown(priv->phy);
64 return 0;
65}
66
67static int usbhs_rcar2_get_id(struct platform_device *pdev)
68{
69 return USBHS_GADGET;
70}
71
72const struct renesas_usbhs_platform_callback usbhs_rcar2_ops = {
73 .hardware_init = usbhs_rcar2_hardware_init,
74 .hardware_exit = usbhs_rcar2_hardware_exit,
75 .power_ctrl = usbhs_rcar2_power_ctrl,
76 .get_id = usbhs_rcar2_get_id,
77};
diff --git a/drivers/usb/renesas_usbhs/rcar2.h b/drivers/usb/renesas_usbhs/rcar2.h
new file mode 100644
index 000000000000..f07f10d9b3b2
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/rcar2.h
@@ -0,0 +1,4 @@
1#include "common.h"
2
3extern const struct renesas_usbhs_platform_callback
4 usbhs_rcar2_ops;