2 * Copyright (c) 2016, NVIDIA Corporation
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
10 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/reset.h>
14 #include <linux/usb/chipidea.h>
19 struct ci_hdrc_platform_data data
;
20 struct platform_device
*dev
;
26 struct tegra_udc_soc_info
{
30 static const struct tegra_udc_soc_info tegra20_udc_soc_info
= {
31 .flags
= CI_HDRC_REQUIRES_ALIGNED_DMA
,
34 static const struct tegra_udc_soc_info tegra30_udc_soc_info
= {
38 static const struct tegra_udc_soc_info tegra114_udc_soc_info
= {
42 static const struct tegra_udc_soc_info tegra124_udc_soc_info
= {
46 static const struct of_device_id tegra_udc_of_match
[] = {
48 .compatible
= "nvidia,tegra20-udc",
49 .data
= &tegra20_udc_soc_info
,
51 .compatible
= "nvidia,tegra30-udc",
52 .data
= &tegra30_udc_soc_info
,
54 .compatible
= "nvidia,tegra114-udc",
55 .data
= &tegra114_udc_soc_info
,
57 .compatible
= "nvidia,tegra124-udc",
58 .data
= &tegra124_udc_soc_info
,
63 MODULE_DEVICE_TABLE(of
, tegra_udc_of_match
);
65 static int tegra_udc_probe(struct platform_device
*pdev
)
67 const struct tegra_udc_soc_info
*soc
;
68 struct tegra_udc
*udc
;
71 udc
= devm_kzalloc(&pdev
->dev
, sizeof(*udc
), GFP_KERNEL
);
75 soc
= of_device_get_match_data(&pdev
->dev
);
77 dev_err(&pdev
->dev
, "failed to match OF data\n");
81 udc
->phy
= devm_usb_get_phy_by_phandle(&pdev
->dev
, "nvidia,phy", 0);
82 if (IS_ERR(udc
->phy
)) {
83 err
= PTR_ERR(udc
->phy
);
84 dev_err(&pdev
->dev
, "failed to get PHY: %d\n", err
);
88 udc
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
89 if (IS_ERR(udc
->clk
)) {
90 err
= PTR_ERR(udc
->clk
);
91 dev_err(&pdev
->dev
, "failed to get clock: %d\n", err
);
95 err
= clk_prepare_enable(udc
->clk
);
97 dev_err(&pdev
->dev
, "failed to enable clock: %d\n", err
);
102 * Tegra's USB PHY driver doesn't implement optional phy_init()
103 * hook, so we have to power on UDC controller before ChipIdea
104 * driver initialization kicks in.
106 usb_phy_set_suspend(udc
->phy
, 0);
108 /* setup and register ChipIdea HDRC device */
109 udc
->data
.name
= "tegra-udc";
110 udc
->data
.flags
= soc
->flags
;
111 udc
->data
.usb_phy
= udc
->phy
;
112 udc
->data
.capoffset
= DEF_CAPOFFSET
;
114 udc
->dev
= ci_hdrc_add_device(&pdev
->dev
, pdev
->resource
,
115 pdev
->num_resources
, &udc
->data
);
116 if (IS_ERR(udc
->dev
)) {
117 err
= PTR_ERR(udc
->dev
);
118 dev_err(&pdev
->dev
, "failed to add HDRC device: %d\n", err
);
122 platform_set_drvdata(pdev
, udc
);
127 usb_phy_set_suspend(udc
->phy
, 1);
128 clk_disable_unprepare(udc
->clk
);
132 static int tegra_udc_remove(struct platform_device
*pdev
)
134 struct tegra_udc
*udc
= platform_get_drvdata(pdev
);
136 usb_phy_set_suspend(udc
->phy
, 1);
137 clk_disable_unprepare(udc
->clk
);
142 static struct platform_driver tegra_udc_driver
= {
145 .of_match_table
= tegra_udc_of_match
,
147 .probe
= tegra_udc_probe
,
148 .remove
= tegra_udc_remove
,
150 module_platform_driver(tegra_udc_driver
);
152 MODULE_DESCRIPTION("NVIDIA Tegra USB device mode driver");
153 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
154 MODULE_ALIAS("platform:tegra-udc");
155 MODULE_LICENSE("GPL v2");