1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016, NVIDIA Corporation
7 #include <linux/module.h>
8 #include <linux/of_device.h>
9 #include <linux/reset.h>
11 #include <linux/usb/chipidea.h>
16 struct ci_hdrc_platform_data data
;
17 struct platform_device
*dev
;
23 struct tegra_udc_soc_info
{
27 static const struct tegra_udc_soc_info tegra20_udc_soc_info
= {
28 .flags
= CI_HDRC_REQUIRES_ALIGNED_DMA
,
31 static const struct tegra_udc_soc_info tegra30_udc_soc_info
= {
32 .flags
= CI_HDRC_REQUIRES_ALIGNED_DMA
,
35 static const struct tegra_udc_soc_info tegra114_udc_soc_info
= {
36 .flags
= CI_HDRC_REQUIRES_ALIGNED_DMA
,
39 static const struct tegra_udc_soc_info tegra124_udc_soc_info
= {
40 .flags
= CI_HDRC_REQUIRES_ALIGNED_DMA
,
43 static const struct of_device_id tegra_udc_of_match
[] = {
45 .compatible
= "nvidia,tegra20-udc",
46 .data
= &tegra20_udc_soc_info
,
48 .compatible
= "nvidia,tegra30-udc",
49 .data
= &tegra30_udc_soc_info
,
51 .compatible
= "nvidia,tegra114-udc",
52 .data
= &tegra114_udc_soc_info
,
54 .compatible
= "nvidia,tegra124-udc",
55 .data
= &tegra124_udc_soc_info
,
60 MODULE_DEVICE_TABLE(of
, tegra_udc_of_match
);
62 static int tegra_udc_probe(struct platform_device
*pdev
)
64 const struct tegra_udc_soc_info
*soc
;
65 struct tegra_udc
*udc
;
68 udc
= devm_kzalloc(&pdev
->dev
, sizeof(*udc
), GFP_KERNEL
);
72 soc
= of_device_get_match_data(&pdev
->dev
);
74 dev_err(&pdev
->dev
, "failed to match OF data\n");
78 udc
->phy
= devm_usb_get_phy_by_phandle(&pdev
->dev
, "nvidia,phy", 0);
79 if (IS_ERR(udc
->phy
)) {
80 err
= PTR_ERR(udc
->phy
);
81 dev_err(&pdev
->dev
, "failed to get PHY: %d\n", err
);
85 udc
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
86 if (IS_ERR(udc
->clk
)) {
87 err
= PTR_ERR(udc
->clk
);
88 dev_err(&pdev
->dev
, "failed to get clock: %d\n", err
);
92 err
= clk_prepare_enable(udc
->clk
);
94 dev_err(&pdev
->dev
, "failed to enable clock: %d\n", err
);
99 * Tegra's USB PHY driver doesn't implement optional phy_init()
100 * hook, so we have to power on UDC controller before ChipIdea
101 * driver initialization kicks in.
103 usb_phy_set_suspend(udc
->phy
, 0);
105 /* setup and register ChipIdea HDRC device */
106 udc
->data
.name
= "tegra-udc";
107 udc
->data
.flags
= soc
->flags
;
108 udc
->data
.usb_phy
= udc
->phy
;
109 udc
->data
.capoffset
= DEF_CAPOFFSET
;
111 udc
->dev
= ci_hdrc_add_device(&pdev
->dev
, pdev
->resource
,
112 pdev
->num_resources
, &udc
->data
);
113 if (IS_ERR(udc
->dev
)) {
114 err
= PTR_ERR(udc
->dev
);
115 dev_err(&pdev
->dev
, "failed to add HDRC device: %d\n", err
);
119 platform_set_drvdata(pdev
, udc
);
124 usb_phy_set_suspend(udc
->phy
, 1);
125 clk_disable_unprepare(udc
->clk
);
129 static int tegra_udc_remove(struct platform_device
*pdev
)
131 struct tegra_udc
*udc
= platform_get_drvdata(pdev
);
133 ci_hdrc_remove_device(udc
->dev
);
134 usb_phy_set_suspend(udc
->phy
, 1);
135 clk_disable_unprepare(udc
->clk
);
140 static struct platform_driver tegra_udc_driver
= {
143 .of_match_table
= tegra_udc_of_match
,
145 .probe
= tegra_udc_probe
,
146 .remove
= tegra_udc_remove
,
148 module_platform_driver(tegra_udc_driver
);
150 MODULE_DESCRIPTION("NVIDIA Tegra USB device mode driver");
151 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
152 MODULE_ALIAS("platform:tegra-udc");
153 MODULE_LICENSE("GPL v2");