Skip to content

Commit 9e99d2b

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

File tree

3 files changed

+228
-0
lines changed

3 files changed

+228
-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: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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 *nop = raw_to_generic_usb_phy(phye);
35+
36+
if (nop->rst_pin == PIN_NONE)
37+
{
38+
return RT_EOK;
39+
}
40+
41+
rt_pin_mode(nop->rst_pin, PIN_MODE_OUTPUT);
42+
43+
rt_pin_write(nop->rst_pin, nop->rst_active_val);
44+
rt_hw_us_delay(15000);
45+
46+
rt_pin_write(nop->rst_pin, !nop->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 *nop = raw_to_generic_usb_phy(phye);
56+
57+
if (nop->vcc && (err = rt_regulator_enable(nop->vcc)))
58+
{
59+
return err;
60+
}
61+
62+
if ((err = rt_clk_prepare_enable(nop->clk)))
63+
{
64+
return err;
65+
}
66+
67+
return generic_usb_phy_reset(phye);
68+
}
69+
70+
static rt_err_t generic_usb_phy_power_off(struct rt_phye *phye)
71+
{
72+
rt_err_t err;
73+
struct generic_usb_phy *nop = raw_to_generic_usb_phy(phye);
74+
75+
if (nop->vcc && (err = rt_regulator_disable(nop->vcc)))
76+
{
77+
return err;
78+
}
79+
80+
rt_clk_disable_unprepare(nop->clk);
81+
82+
return RT_EOK;
83+
}
84+
85+
const static struct rt_phye_ops generic_usb_phy_ops =
86+
{
87+
.reset = generic_usb_phy_reset,
88+
.power_on = generic_usb_phy_power_on,
89+
.power_off = generic_usb_phy_power_off,
90+
};
91+
92+
static void generic_usb_phy_free(struct generic_usb_phy *nop)
93+
{
94+
if (!rt_is_err_or_null(nop->clk))
95+
{
96+
rt_clk_put(nop->clk);
97+
}
98+
99+
if (!rt_is_err_or_null(nop->vcc))
100+
{
101+
rt_regulator_put(nop->vcc);
102+
}
103+
104+
if (!rt_is_err_or_null(nop->vbus))
105+
{
106+
rt_regulator_put(nop->vbus);
107+
}
108+
109+
rt_free(nop);
110+
}
111+
112+
static rt_err_t generic_usb_phy_probe(struct rt_platform_device *pdev)
113+
{
114+
rt_err_t err;
115+
rt_uint32_t rate;
116+
struct rt_phye *phy;
117+
struct rt_device *dev = &pdev->parent;
118+
struct generic_usb_phy *nop = rt_calloc(1, sizeof(*nop));
119+
120+
if (!nop)
121+
{
122+
return -RT_ENOMEM;
123+
}
124+
125+
nop->rst_pin = rt_pin_get_named_pin(dev, "reset", 0,
126+
RT_NULL, &nop->rst_active_val);
127+
128+
if (nop->rst_pin < 0 && nop->rst_pin != PIN_NONE)
129+
{
130+
err = nop->rst_pin;
131+
goto _fail;
132+
}
133+
134+
nop->clk = rt_clk_get_by_name(dev, "main_clk");
135+
136+
if (rt_is_err(nop->clk))
137+
{
138+
err = rt_ptr_err(nop->clk);
139+
goto _fail;
140+
}
141+
142+
if (!rt_dm_dev_prop_read_u32(dev, "clock-frequency", &rate))
143+
{
144+
rt_clk_set_rate(nop->clk, rate);
145+
}
146+
147+
nop->vcc = rt_regulator_get(dev, "vcc");
148+
149+
if (rt_is_err(nop->vcc))
150+
{
151+
err = rt_ptr_err(nop->vcc);
152+
goto _fail;
153+
}
154+
155+
nop->vbus = rt_regulator_get(dev, "vbus");
156+
157+
if (rt_is_err(nop->vbus))
158+
{
159+
err = rt_ptr_err(nop->vbus);
160+
goto _fail;
161+
}
162+
163+
if (nop->vbus && (err = rt_regulator_enable(nop->vbus)))
164+
{
165+
goto _fail;
166+
}
167+
168+
dev->user_data = nop;
169+
170+
phy = &nop->parent;
171+
phy->dev = dev;
172+
phy->ops = &generic_usb_phy_ops;
173+
174+
if ((err = rt_phye_register(phy)))
175+
{
176+
goto _fail;
177+
}
178+
179+
return RT_EOK;
180+
181+
_fail:
182+
generic_usb_phy_free(nop);
183+
184+
return err;
185+
}
186+
187+
static rt_err_t generic_usb_phy_remove(struct rt_platform_device *pdev)
188+
{
189+
struct generic_usb_phy *nop = pdev->parent.user_data;
190+
191+
rt_phye_unregister(&nop->parent);
192+
193+
rt_regulator_disable(nop->vbus);
194+
195+
generic_usb_phy_free(nop);
196+
197+
return RT_EOK;
198+
}
199+
200+
static const struct rt_ofw_node_id generic_usb_phy_ofw_ids[] =
201+
{
202+
{ .compatible = "usb-nop-xceiv" },
203+
{ /* sentinel */ }
204+
};
205+
206+
static struct rt_platform_driver generic_usb_phy_driver =
207+
{
208+
.name = "phy-generic-usb",
209+
.ids = generic_usb_phy_ofw_ids,
210+
211+
.probe = generic_usb_phy_probe,
212+
.remove = generic_usb_phy_remove,
213+
};
214+
215+
static int generic_usb_phy_drv_register(void)
216+
{
217+
rt_platform_driver_register(&generic_usb_phy_driver);
218+
219+
return 0;
220+
}
221+
INIT_PLATFORM_EXPORT(generic_usb_phy_drv_register);

0 commit comments

Comments
 (0)