xref: /rk3399_rockchip-uboot/drivers/phy/phy-uclass.c (revision 23558bb67a0df95b390ce6adea6c54d22bb67faa)
172e5016fSJean-Jacques Hiblot /*
272e5016fSJean-Jacques Hiblot  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
372e5016fSJean-Jacques Hiblot  * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
472e5016fSJean-Jacques Hiblot  *
572e5016fSJean-Jacques Hiblot  * SPDX-License-Identifier:	GPL-2.0+
672e5016fSJean-Jacques Hiblot  */
772e5016fSJean-Jacques Hiblot 
872e5016fSJean-Jacques Hiblot #include <common.h>
972e5016fSJean-Jacques Hiblot #include <dm.h>
1072e5016fSJean-Jacques Hiblot #include <generic-phy.h>
1172e5016fSJean-Jacques Hiblot 
1272e5016fSJean-Jacques Hiblot DECLARE_GLOBAL_DATA_PTR;
1372e5016fSJean-Jacques Hiblot 
1472e5016fSJean-Jacques Hiblot static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
1572e5016fSJean-Jacques Hiblot {
1672e5016fSJean-Jacques Hiblot 	return (struct phy_ops *)dev->driver->ops;
1772e5016fSJean-Jacques Hiblot }
1872e5016fSJean-Jacques Hiblot 
1972e5016fSJean-Jacques Hiblot static int generic_phy_xlate_offs_flags(struct phy *phy,
20*23558bb6SSimon Glass 					struct ofnode_phandle_args *args)
2172e5016fSJean-Jacques Hiblot {
2272e5016fSJean-Jacques Hiblot 	debug("%s(phy=%p)\n", __func__, phy);
2372e5016fSJean-Jacques Hiblot 
2472e5016fSJean-Jacques Hiblot 	if (args->args_count > 1) {
2572e5016fSJean-Jacques Hiblot 		debug("Invaild args_count: %d\n", args->args_count);
2672e5016fSJean-Jacques Hiblot 		return -EINVAL;
2772e5016fSJean-Jacques Hiblot 	}
2872e5016fSJean-Jacques Hiblot 
2972e5016fSJean-Jacques Hiblot 	if (args->args_count)
3072e5016fSJean-Jacques Hiblot 		phy->id = args->args[0];
3172e5016fSJean-Jacques Hiblot 	else
3272e5016fSJean-Jacques Hiblot 		phy->id = 0;
3372e5016fSJean-Jacques Hiblot 
3472e5016fSJean-Jacques Hiblot 	return 0;
3572e5016fSJean-Jacques Hiblot }
3672e5016fSJean-Jacques Hiblot 
3772e5016fSJean-Jacques Hiblot int generic_phy_get_by_index(struct udevice *dev, int index,
3872e5016fSJean-Jacques Hiblot 			     struct phy *phy)
3972e5016fSJean-Jacques Hiblot {
40*23558bb6SSimon Glass 	struct ofnode_phandle_args args;
4172e5016fSJean-Jacques Hiblot 	struct phy_ops *ops;
4272e5016fSJean-Jacques Hiblot 	int ret;
4372e5016fSJean-Jacques Hiblot 	struct udevice *phydev;
4472e5016fSJean-Jacques Hiblot 
4572e5016fSJean-Jacques Hiblot 	debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
4672e5016fSJean-Jacques Hiblot 
4772e5016fSJean-Jacques Hiblot 	assert(phy);
48*23558bb6SSimon Glass 	ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
4972e5016fSJean-Jacques Hiblot 					 &args);
5072e5016fSJean-Jacques Hiblot 	if (ret) {
51*23558bb6SSimon Glass 		debug("%s: dev_read_phandle_with_args failed: err=%d\n",
5272e5016fSJean-Jacques Hiblot 		      __func__, ret);
5372e5016fSJean-Jacques Hiblot 		return ret;
5472e5016fSJean-Jacques Hiblot 	}
5572e5016fSJean-Jacques Hiblot 
56*23558bb6SSimon Glass 	ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
5772e5016fSJean-Jacques Hiblot 	if (ret) {
58*23558bb6SSimon Glass 		debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
5972e5016fSJean-Jacques Hiblot 		      __func__, ret);
6072e5016fSJean-Jacques Hiblot 		return ret;
6172e5016fSJean-Jacques Hiblot 	}
6272e5016fSJean-Jacques Hiblot 
6372e5016fSJean-Jacques Hiblot 	phy->dev = phydev;
6472e5016fSJean-Jacques Hiblot 
6572e5016fSJean-Jacques Hiblot 	ops = phy_dev_ops(phydev);
6672e5016fSJean-Jacques Hiblot 
6772e5016fSJean-Jacques Hiblot 	if (ops->of_xlate)
6872e5016fSJean-Jacques Hiblot 		ret = ops->of_xlate(phy, &args);
6972e5016fSJean-Jacques Hiblot 	else
7072e5016fSJean-Jacques Hiblot 		ret = generic_phy_xlate_offs_flags(phy, &args);
7172e5016fSJean-Jacques Hiblot 	if (ret) {
7272e5016fSJean-Jacques Hiblot 		debug("of_xlate() failed: %d\n", ret);
7372e5016fSJean-Jacques Hiblot 		goto err;
7472e5016fSJean-Jacques Hiblot 	}
7572e5016fSJean-Jacques Hiblot 
7672e5016fSJean-Jacques Hiblot 	return 0;
7772e5016fSJean-Jacques Hiblot 
7872e5016fSJean-Jacques Hiblot err:
7972e5016fSJean-Jacques Hiblot 	return ret;
8072e5016fSJean-Jacques Hiblot }
8172e5016fSJean-Jacques Hiblot 
8272e5016fSJean-Jacques Hiblot int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
8372e5016fSJean-Jacques Hiblot 			    struct phy *phy)
8472e5016fSJean-Jacques Hiblot {
8572e5016fSJean-Jacques Hiblot 	int index;
8672e5016fSJean-Jacques Hiblot 
8772e5016fSJean-Jacques Hiblot 	debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
8872e5016fSJean-Jacques Hiblot 
89*23558bb6SSimon Glass 	index = dev_read_stringlist_search(dev, "phy-names", phy_name);
9072e5016fSJean-Jacques Hiblot 	if (index < 0) {
91*23558bb6SSimon Glass 		debug("dev_read_stringlist_search() failed: %d\n", index);
9272e5016fSJean-Jacques Hiblot 		return index;
9372e5016fSJean-Jacques Hiblot 	}
9472e5016fSJean-Jacques Hiblot 
9572e5016fSJean-Jacques Hiblot 	return generic_phy_get_by_index(dev, index, phy);
9672e5016fSJean-Jacques Hiblot }
9772e5016fSJean-Jacques Hiblot 
9872e5016fSJean-Jacques Hiblot int generic_phy_init(struct phy *phy)
9972e5016fSJean-Jacques Hiblot {
10072e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
10172e5016fSJean-Jacques Hiblot 
10272e5016fSJean-Jacques Hiblot 	return ops->init ? ops->init(phy) : 0;
10372e5016fSJean-Jacques Hiblot }
10472e5016fSJean-Jacques Hiblot 
10572e5016fSJean-Jacques Hiblot int generic_phy_reset(struct phy *phy)
10672e5016fSJean-Jacques Hiblot {
10772e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
10872e5016fSJean-Jacques Hiblot 
10972e5016fSJean-Jacques Hiblot 	return ops->reset ? ops->reset(phy) : 0;
11072e5016fSJean-Jacques Hiblot }
11172e5016fSJean-Jacques Hiblot 
11272e5016fSJean-Jacques Hiblot int generic_phy_exit(struct phy *phy)
11372e5016fSJean-Jacques Hiblot {
11472e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
11572e5016fSJean-Jacques Hiblot 
11672e5016fSJean-Jacques Hiblot 	return ops->exit ? ops->exit(phy) : 0;
11772e5016fSJean-Jacques Hiblot }
11872e5016fSJean-Jacques Hiblot 
11972e5016fSJean-Jacques Hiblot int generic_phy_power_on(struct phy *phy)
12072e5016fSJean-Jacques Hiblot {
12172e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
12272e5016fSJean-Jacques Hiblot 
12372e5016fSJean-Jacques Hiblot 	return ops->power_on ? ops->power_on(phy) : 0;
12472e5016fSJean-Jacques Hiblot }
12572e5016fSJean-Jacques Hiblot 
12672e5016fSJean-Jacques Hiblot int generic_phy_power_off(struct phy *phy)
12772e5016fSJean-Jacques Hiblot {
12872e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
12972e5016fSJean-Jacques Hiblot 
13072e5016fSJean-Jacques Hiblot 	return ops->power_off ? ops->power_off(phy) : 0;
13172e5016fSJean-Jacques Hiblot }
13272e5016fSJean-Jacques Hiblot 
13372e5016fSJean-Jacques Hiblot UCLASS_DRIVER(phy) = {
13472e5016fSJean-Jacques Hiblot 	.id		= UCLASS_PHY,
13572e5016fSJean-Jacques Hiblot 	.name		= "phy",
13672e5016fSJean-Jacques Hiblot };
137