| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-10-24 GuEe-GUI first version
- */
- #include <rtdevice.h>
- #include <rtthread.h>
- #define DBG_TAG "phye.generic.usb"
- #define DBG_LVL DBG_INFO
- #include <rtdbg.h>
- struct generic_usb_phy
- {
- struct rt_phye parent;
- rt_base_t rst_pin;
- rt_uint8_t rst_active_val;
- struct rt_clk *clk;
- struct rt_regulator *vcc;
- struct rt_regulator *vbus;
- };
- #define raw_to_generic_usb_phy(raw) rt_container_of(raw, struct generic_usb_phy, parent)
- static rt_err_t generic_usb_phy_reset(struct rt_phye *phye)
- {
- struct generic_usb_phy *usb_phy = raw_to_generic_usb_phy(phye);
- if (usb_phy->rst_pin == PIN_NONE)
- {
- return RT_EOK;
- }
- rt_pin_mode(usb_phy->rst_pin, PIN_MODE_OUTPUT);
- rt_pin_write(usb_phy->rst_pin, usb_phy->rst_active_val);
- rt_hw_us_delay(15000);
- rt_pin_write(usb_phy->rst_pin, !usb_phy->rst_active_val);
- rt_hw_us_delay(20000);
- return RT_EOK;
- }
- static rt_err_t generic_usb_phy_power_on(struct rt_phye *phye)
- {
- rt_err_t err;
- struct generic_usb_phy *usb_phy = raw_to_generic_usb_phy(phye);
- if (usb_phy->vcc && (err = rt_regulator_enable(usb_phy->vcc)))
- {
- return err;
- }
- if ((err = rt_clk_prepare_enable(usb_phy->clk)))
- {
- if (usb_phy->vcc)
- {
- rt_regulator_disable(usb_phy->vcc);
- }
- return err;
- }
- return generic_usb_phy_reset(phye);
- }
- static rt_err_t generic_usb_phy_power_off(struct rt_phye *phye)
- {
- rt_err_t err;
- struct generic_usb_phy *usb_phy = raw_to_generic_usb_phy(phye);
- if (usb_phy->vcc && (err = rt_regulator_disable(usb_phy->vcc)))
- {
- return err;
- }
- rt_clk_disable_unprepare(usb_phy->clk);
- return RT_EOK;
- }
- static const struct rt_phye_ops generic_usb_phy_ops =
- {
- .reset = generic_usb_phy_reset,
- .power_on = generic_usb_phy_power_on,
- .power_off = generic_usb_phy_power_off,
- };
- static void generic_usb_phy_free(struct generic_usb_phy *usb_phy)
- {
- if (!rt_is_err_or_null(usb_phy->clk))
- {
- rt_clk_put(usb_phy->clk);
- }
- if (!rt_is_err_or_null(usb_phy->vcc))
- {
- rt_regulator_put(usb_phy->vcc);
- }
- if (!rt_is_err_or_null(usb_phy->vbus))
- {
- rt_regulator_put(usb_phy->vbus);
- }
- rt_free(usb_phy);
- }
- static rt_err_t generic_usb_phy_probe(struct rt_platform_device *pdev)
- {
- rt_err_t err;
- rt_uint32_t rate;
- struct rt_phye *phy;
- struct rt_device *dev = &pdev->parent;
- struct generic_usb_phy *usb_phy = rt_calloc(1, sizeof(*usb_phy));
- if (!usb_phy)
- {
- return -RT_ENOMEM;
- }
- usb_phy->rst_pin = rt_pin_get_named_pin(dev, "reset", 0,
- RT_NULL, &usb_phy->rst_active_val);
- if (usb_phy->rst_pin < 0 && usb_phy->rst_pin != PIN_NONE)
- {
- err = usb_phy->rst_pin;
- goto _fail;
- }
- usb_phy->clk = rt_clk_get_by_name(dev, "main_clk");
- if (rt_is_err(usb_phy->clk))
- {
- err = rt_ptr_err(usb_phy->clk);
- goto _fail;
- }
- if (!rt_dm_dev_prop_read_u32(dev, "clock-frequency", &rate))
- {
- if ((err = rt_clk_set_rate(usb_phy->clk, rate)))
- {
- goto _fail;
- }
- }
- usb_phy->vcc = rt_regulator_get(dev, "vcc");
- if (rt_is_err(usb_phy->vcc))
- {
- err = rt_ptr_err(usb_phy->vcc);
- goto _fail;
- }
- usb_phy->vbus = rt_regulator_get(dev, "vbus");
- if (rt_is_err(usb_phy->vbus))
- {
- err = rt_ptr_err(usb_phy->vbus);
- goto _fail;
- }
- if (usb_phy->vbus && (err = rt_regulator_enable(usb_phy->vbus)))
- {
- goto _fail;
- }
- dev->user_data = usb_phy;
- phy = &usb_phy->parent;
- phy->dev = dev;
- phy->ops = &generic_usb_phy_ops;
- if ((err = rt_phye_register(phy)))
- {
- goto _fail;
- }
- return RT_EOK;
- _fail:
- generic_usb_phy_free(usb_phy);
- return err;
- }
- static rt_err_t generic_usb_phy_remove(struct rt_platform_device *pdev)
- {
- struct generic_usb_phy *usb_phy = pdev->parent.user_data;
- rt_phye_unregister(&usb_phy->parent);
- if (usb_phy->vbus)
- {
- rt_regulator_disable(usb_phy->vbus);
- }
- generic_usb_phy_free(usb_phy);
- return RT_EOK;
- }
- static const struct rt_ofw_node_id generic_usb_phy_ofw_ids[] =
- {
- { .compatible = "usb-nop-xceiv" },
- { /* sentinel */ }
- };
- static struct rt_platform_driver generic_usb_phy_driver =
- {
- .name = "phy-generic-usb",
- .ids = generic_usb_phy_ofw_ids,
- .probe = generic_usb_phy_probe,
- .remove = generic_usb_phy_remove,
- };
- static int generic_usb_phy_drv_register(void)
- {
- rt_platform_driver_register(&generic_usb_phy_driver);
- return 0;
- }
- INIT_PLATFORM_EXPORT(generic_usb_phy_drv_register);
|