Skip to content

Commit 829d9dd

Browse files
committed
[DM/PHYE] Support USB generic PHYE.
Signed-off-by: GuEe-GUI <[email protected]>
1 parent 2fb53c8 commit 829d9dd

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

components/drivers/phye/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ menuconfig RT_USING_PHYE
66
This framework will be of use only to devices that use
77
external PHY (PHY functionality is not embedded within the controller).
88

9+
config RT_PHYE_GENERIC_USB
10+
bool "Generic USB"
11+
depends on RT_USING_PHYE
12+
913
if RT_USING_PHYE
1014
osource "$(SOC_DM_PHYE_DIR)/Kconfig"
1115
endif

components/drivers/phye/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ CPPPATH = [cwd + '/../include']
1010

1111
src = ['phye.c']
1212

13+
if GetDepend(['RT_PHYE_GENERIC_USB']):
14+
src += ['phye-generic-usb.c']
15+
1316
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
1417

1518
Return('group')
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-10-24 GuEe-GUI first version
9+
*/
10+
11+
#include <rtdevice.h>
12+
#include <rtthread.h>
13+
14+
#define DBG_TAG "phye.generic.usb"
15+
#define DBG_LVL DBG_INFO
16+
#include <rtdbg.h>
17+
18+
struct generic_usb_phy
19+
{
20+
struct rt_phye parent;
21+
22+
rt_base_t rst_pin;
23+
rt_uint8_t rst_active_val;
24+
25+
struct rt_clk *clk;
26+
struct rt_regulator *vcc;
27+
struct rt_regulator *vbus;
28+
};
29+
30+
#define raw_to_generic_usb_phy(raw) rt_container_of(raw, struct generic_usb_phy, parent)
31+
32+
static rt_err_t generic_usb_phy_reset(struct rt_phye *phye)
33+
{
34+
struct generic_usb_phy *usb_phy = raw_to_generic_usb_phy(phye);
35+
36+
if (usb_phy->rst_pin == PIN_NONE)
37+
{
38+
return RT_EOK;
39+
}
40+
41+
rt_pin_mode(usb_phy->rst_pin, PIN_MODE_OUTPUT);
42+
43+
rt_pin_write(usb_phy->rst_pin, usb_phy->rst_active_val);
44+
rt_hw_us_delay(15000);
45+
46+
rt_pin_write(usb_phy->rst_pin, !usb_phy->rst_active_val);
47+
rt_hw_us_delay(20000);
48+
49+
return RT_EOK;
50+
}
51+
52+
static rt_err_t generic_usb_phy_power_on(struct rt_phye *phye)
53+
{
54+
rt_err_t err;
55+
struct generic_usb_phy *usb_phy = raw_to_generic_usb_phy(phye);
56+
57+
if (usb_phy->vcc && (err = rt_regulator_enable(usb_phy->vcc)))
58+
{
59+
return err;
60+
}
61+
62+
if ((err = rt_clk_prepare_enable(usb_phy->clk)))
63+
{
64+
if (usb_phy->vcc)
65+
{
66+
rt_regulator_disable(usb_phy->vcc);
67+
}
68+
69+
return err;
70+
}
71+
72+
return generic_usb_phy_reset(phye);
73+
}
74+
75+
static rt_err_t generic_usb_phy_power_off(struct rt_phye *phye)
76+
{
77+
rt_err_t err;
78+
struct generic_usb_phy *usb_phy = raw_to_generic_usb_phy(phye);
79+
80+
if (usb_phy->vcc && (err = rt_regulator_disable(usb_phy->vcc)))
81+
{
82+
return err;
83+
}
84+
85+
rt_clk_disable_unprepare(usb_phy->clk);
86+
87+
return RT_EOK;
88+
}
89+
90+
static const struct rt_phye_ops generic_usb_phy_ops =
91+
{
92+
.reset = generic_usb_phy_reset,
93+
.power_on = generic_usb_phy_power_on,
94+
.power_off = generic_usb_phy_power_off,
95+
};
96+
97+
static void generic_usb_phy_free(struct generic_usb_phy *usb_phy)
98+
{
99+
if (!rt_is_err_or_null(usb_phy->clk))
100+
{
101+
rt_clk_put(usb_phy->clk);
102+
}
103+
104+
if (!rt_is_err_or_null(usb_phy->vcc))
105+
{
106+
rt_regulator_put(usb_phy->vcc);
107+
}
108+
109+
if (!rt_is_err_or_null(usb_phy->vbus))
110+
{
111+
rt_regulator_put(usb_phy->vbus);
112+
}
113+
114+
rt_free(usb_phy);
115+
}
116+
117+
static rt_err_t generic_usb_phy_probe(struct rt_platform_device *pdev)
118+
{
119+
rt_err_t err;
120+
rt_uint32_t rate;
121+
struct rt_phye *phy;
122+
struct rt_device *dev = &pdev->parent;
123+
struct generic_usb_phy *usb_phy = rt_calloc(1, sizeof(*usb_phy));
124+
125+
if (!usb_phy)
126+
{
127+
return -RT_ENOMEM;
128+
}
129+
130+
usb_phy->rst_pin = rt_pin_get_named_pin(dev, "reset", 0,
131+
RT_NULL, &usb_phy->rst_active_val);
132+
133+
if (usb_phy->rst_pin < 0 && usb_phy->rst_pin != PIN_NONE)
134+
{
135+
err = usb_phy->rst_pin;
136+
goto _fail;
137+
}
138+
139+
usb_phy->clk = rt_clk_get_by_name(dev, "main_clk");
140+
141+
if (rt_is_err(usb_phy->clk))
142+
{
143+
err = rt_ptr_err(usb_phy->clk);
144+
goto _fail;
145+
}
146+
147+
if (!rt_dm_dev_prop_read_u32(dev, "clock-frequency", &rate))
148+
{
149+
if ((err = rt_clk_set_rate(usb_phy->clk, rate)))
150+
{
151+
goto _fail;
152+
}
153+
}
154+
155+
usb_phy->vcc = rt_regulator_get(dev, "vcc");
156+
157+
if (rt_is_err(usb_phy->vcc))
158+
{
159+
err = rt_ptr_err(usb_phy->vcc);
160+
goto _fail;
161+
}
162+
163+
usb_phy->vbus = rt_regulator_get(dev, "vbus");
164+
165+
if (rt_is_err(usb_phy->vbus))
166+
{
167+
err = rt_ptr_err(usb_phy->vbus);
168+
goto _fail;
169+
}
170+
171+
if (usb_phy->vbus && (err = rt_regulator_enable(usb_phy->vbus)))
172+
{
173+
goto _fail;
174+
}
175+
176+
dev->user_data = usb_phy;
177+
178+
phy = &usb_phy->parent;
179+
phy->dev = dev;
180+
phy->ops = &generic_usb_phy_ops;
181+
182+
if ((err = rt_phye_register(phy)))
183+
{
184+
goto _fail;
185+
}
186+
187+
return RT_EOK;
188+
189+
_fail:
190+
generic_usb_phy_free(usb_phy);
191+
192+
return err;
193+
}
194+
195+
static rt_err_t generic_usb_phy_remove(struct rt_platform_device *pdev)
196+
{
197+
struct generic_usb_phy *usb_phy = pdev->parent.user_data;
198+
199+
rt_phye_unregister(&usb_phy->parent);
200+
201+
if (usb_phy->vbus)
202+
{
203+
rt_regulator_disable(usb_phy->vbus);
204+
}
205+
206+
generic_usb_phy_free(usb_phy);
207+
208+
return RT_EOK;
209+
}
210+
211+
static const struct rt_ofw_node_id generic_usb_phy_ofw_ids[] =
212+
{
213+
{ .compatible = "usb-nop-xceiv" },
214+
{ /* sentinel */ }
215+
};
216+
217+
static struct rt_platform_driver generic_usb_phy_driver =
218+
{
219+
.name = "phy-generic-usb",
220+
.ids = generic_usb_phy_ofw_ids,
221+
222+
.probe = generic_usb_phy_probe,
223+
.remove = generic_usb_phy_remove,
224+
};
225+
226+
static int generic_usb_phy_drv_register(void)
227+
{
228+
rt_platform_driver_register(&generic_usb_phy_driver);
229+
230+
return 0;
231+
}
232+
INIT_PLATFORM_EXPORT(generic_usb_phy_drv_register);

0 commit comments

Comments
 (0)