123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /*
- * 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
- */
- #define DBG_TAG "rtdm.phye"
- #define DBG_LVL DBG_INFO
- #include <rtdbg.h>
- #include <rtdevice.h>
- #include <rtthread.h>
- rt_err_t rt_phye_register(struct rt_phye *phye)
- {
- rt_err_t err;
- if (phye && phye->dev && phye->ops)
- {
- err = RT_EOK;
- rt_spin_lock_init(&phye->lock);
- rt_dm_dev_bind_fwdata(phye->dev, RT_NULL, phye);
- }
- else
- {
- err = -RT_EINVAL;
- }
- return err;
- }
- rt_err_t rt_phye_unregister(struct rt_phye *phye)
- {
- rt_err_t err;
- if (phye)
- {
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->dev->ref_count)
- {
- err = -RT_EBUSY;
- LOG_E("%s is busy in unregister", rt_dm_dev_get_name(phye->dev));
- }
- rt_dm_dev_unbind_fwdata(phye->dev, RT_NULL);
- rt_spin_unlock(&phye->lock);
- }
- else
- {
- err = -RT_EINVAL;
- }
- return err;
- }
- rt_err_t rt_phye_init(struct rt_phye *phye)
- {
- rt_err_t err;
- if (!phye)
- {
- return RT_EOK;
- }
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->init_count == 0 && phye->ops->init)
- {
- if ((err = phye->ops->init(phye)))
- {
- goto _out_lock;
- }
- }
- ++phye->init_count;
- _out_lock:
- rt_spin_unlock(&phye->lock);
- return err;
- }
- rt_err_t rt_phye_exit(struct rt_phye *phye)
- {
- rt_err_t err;
- if (!phye)
- {
- return RT_EOK;
- }
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->init_count == 1 && phye->ops->exit)
- {
- if ((err = phye->ops->exit(phye)))
- {
- goto _out_lock;
- }
- }
- if (phye->init_count)
- {
- --phye->init_count;
- }
- _out_lock:
- rt_spin_unlock(&phye->lock);
- return err;
- }
- rt_err_t rt_phye_reset(struct rt_phye *phye)
- {
- rt_err_t err;
- if (!phye)
- {
- return RT_EOK;
- }
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->ops->reset)
- {
- err = phye->ops->reset(phye);
- }
- rt_spin_unlock(&phye->lock);
- return err;
- }
- rt_err_t rt_phye_power_on(struct rt_phye *phye)
- {
- rt_err_t err;
- if (!phye)
- {
- return RT_EOK;
- }
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->power_count == 0 && phye->ops->power_on)
- {
- if ((err = phye->ops->power_on(phye)))
- {
- goto _out_lock;
- }
- }
- ++phye->power_count;
- _out_lock:
- rt_spin_unlock(&phye->lock);
- return err;
- }
- rt_err_t rt_phye_power_off(struct rt_phye *phye)
- {
- rt_err_t err;
- if (!phye)
- {
- return RT_EOK;
- }
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->power_count == 1 && phye->ops->power_off)
- {
- if ((err = phye->ops->power_off(phye)))
- {
- goto _out_lock;
- }
- }
- if (phye->power_count)
- {
- --phye->power_count;
- }
- _out_lock:
- rt_spin_unlock(&phye->lock);
- return err;
- }
- rt_err_t rt_phye_set_mode(struct rt_phye *phye, enum rt_phye_mode mode, int submode)
- {
- rt_err_t err;
- if (!phye)
- {
- return RT_EOK;
- }
- if (mode < RT_PHYE_MODE_MAX &&
- (submode == RT_PHYE_MODE_INVALID || submode >= RT_PHYE_MODE_MAX))
- {
- err = RT_EOK;
- rt_spin_lock(&phye->lock);
- if (phye->ops->set_mode)
- {
- err = phye->ops->set_mode(phye, mode, submode);
- }
- rt_spin_unlock(&phye->lock);
- }
- else
- {
- err = -RT_EINVAL;
- }
- return err;
- }
- static struct rt_phye *ofw_phye_get_by_index(struct rt_ofw_node *np, int index)
- {
- struct rt_phye *phye = RT_NULL;
- #ifdef RT_USING_OFW
- rt_err_t err;
- struct rt_ofw_node *phye_np;
- struct rt_ofw_cell_args phye_args;
- if (!rt_ofw_parse_phandle_cells(np, "phys", "#phy-cells", index, &phye_args))
- {
- phye_np = phye_args.data;
- if (!rt_ofw_data(phye_np))
- {
- rt_platform_ofw_request(phye_np);
- }
- phye = rt_ofw_data(phye_np);
- rt_ofw_node_put(phye_np);
- if (phye && phye->ops->ofw_parse)
- {
- if ((err = phye->ops->ofw_parse(phye, &phye_args)))
- {
- phye = rt_err_ptr(err);
- }
- }
- }
- #endif /* RT_USING_OFW */
- return phye;
- }
- struct rt_phye *rt_phye_get_by_index(struct rt_device *dev, int index)
- {
- struct rt_phye *phye = RT_NULL;
- if (!dev || index < 0)
- {
- return rt_err_ptr(-RT_EINVAL);
- }
- if (dev->ofw_node)
- {
- phye = ofw_phye_get_by_index(dev->ofw_node, index);
- }
- if (!rt_is_err_or_null(phye))
- {
- rt_spin_lock(&phye->lock);
- ++phye->dev->ref_count;
- rt_spin_unlock(&phye->lock);
- }
- return phye;
- }
- struct rt_phye *rt_phye_get_by_name(struct rt_device *dev, const char *id)
- {
- int index;
- if (!dev || !id)
- {
- return rt_err_ptr(-RT_EINVAL);
- }
- index = rt_dm_dev_prop_index_of_string(dev, "phy-names", id);
- if (index >= 0)
- {
- return rt_phye_get_by_index(dev, index);
- }
- return RT_NULL;
- }
- void rt_phye_put(struct rt_phye *phye)
- {
- if (phye)
- {
- rt_spin_lock(&phye->lock);
- --phye->dev->ref_count;
- rt_spin_unlock(&phye->lock);
- }
- }
|