xref: /rk3399_rockchip-uboot/drivers/phy/phy-uclass.c (revision b9688df3cbf4bf92fa96e1cc9ff7be510e06b54b)
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,
2023558bb6SSimon 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 {
4023558bb6SSimon 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*b9688df3SPatrice Chotard 	phy->dev = NULL;
4923558bb6SSimon Glass 	ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
5072e5016fSJean-Jacques Hiblot 					 &args);
5172e5016fSJean-Jacques Hiblot 	if (ret) {
5223558bb6SSimon Glass 		debug("%s: dev_read_phandle_with_args failed: err=%d\n",
5372e5016fSJean-Jacques Hiblot 		      __func__, ret);
5472e5016fSJean-Jacques Hiblot 		return ret;
5572e5016fSJean-Jacques Hiblot 	}
5672e5016fSJean-Jacques Hiblot 
5723558bb6SSimon Glass 	ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
5872e5016fSJean-Jacques Hiblot 	if (ret) {
5923558bb6SSimon Glass 		debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
6072e5016fSJean-Jacques Hiblot 		      __func__, ret);
6172e5016fSJean-Jacques Hiblot 		return ret;
6272e5016fSJean-Jacques Hiblot 	}
6372e5016fSJean-Jacques Hiblot 
6472e5016fSJean-Jacques Hiblot 	phy->dev = phydev;
6572e5016fSJean-Jacques Hiblot 
6672e5016fSJean-Jacques Hiblot 	ops = phy_dev_ops(phydev);
6772e5016fSJean-Jacques Hiblot 
6872e5016fSJean-Jacques Hiblot 	if (ops->of_xlate)
6972e5016fSJean-Jacques Hiblot 		ret = ops->of_xlate(phy, &args);
7072e5016fSJean-Jacques Hiblot 	else
7172e5016fSJean-Jacques Hiblot 		ret = generic_phy_xlate_offs_flags(phy, &args);
7272e5016fSJean-Jacques Hiblot 	if (ret) {
7372e5016fSJean-Jacques Hiblot 		debug("of_xlate() failed: %d\n", ret);
7472e5016fSJean-Jacques Hiblot 		goto err;
7572e5016fSJean-Jacques Hiblot 	}
7672e5016fSJean-Jacques Hiblot 
7772e5016fSJean-Jacques Hiblot 	return 0;
7872e5016fSJean-Jacques Hiblot 
7972e5016fSJean-Jacques Hiblot err:
8072e5016fSJean-Jacques Hiblot 	return ret;
8172e5016fSJean-Jacques Hiblot }
8272e5016fSJean-Jacques Hiblot 
8372e5016fSJean-Jacques Hiblot int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
8472e5016fSJean-Jacques Hiblot 			    struct phy *phy)
8572e5016fSJean-Jacques Hiblot {
8672e5016fSJean-Jacques Hiblot 	int index;
8772e5016fSJean-Jacques Hiblot 
8872e5016fSJean-Jacques Hiblot 	debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
8972e5016fSJean-Jacques Hiblot 
9023558bb6SSimon Glass 	index = dev_read_stringlist_search(dev, "phy-names", phy_name);
9172e5016fSJean-Jacques Hiblot 	if (index < 0) {
9223558bb6SSimon Glass 		debug("dev_read_stringlist_search() failed: %d\n", index);
9372e5016fSJean-Jacques Hiblot 		return index;
9472e5016fSJean-Jacques Hiblot 	}
9572e5016fSJean-Jacques Hiblot 
9672e5016fSJean-Jacques Hiblot 	return generic_phy_get_by_index(dev, index, phy);
9772e5016fSJean-Jacques Hiblot }
9872e5016fSJean-Jacques Hiblot 
9972e5016fSJean-Jacques Hiblot int generic_phy_init(struct phy *phy)
10072e5016fSJean-Jacques Hiblot {
10172e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
10272e5016fSJean-Jacques Hiblot 
10372e5016fSJean-Jacques Hiblot 	return ops->init ? ops->init(phy) : 0;
10472e5016fSJean-Jacques Hiblot }
10572e5016fSJean-Jacques Hiblot 
10672e5016fSJean-Jacques Hiblot int generic_phy_reset(struct phy *phy)
10772e5016fSJean-Jacques Hiblot {
10872e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
10972e5016fSJean-Jacques Hiblot 
11072e5016fSJean-Jacques Hiblot 	return ops->reset ? ops->reset(phy) : 0;
11172e5016fSJean-Jacques Hiblot }
11272e5016fSJean-Jacques Hiblot 
11372e5016fSJean-Jacques Hiblot int generic_phy_exit(struct phy *phy)
11472e5016fSJean-Jacques Hiblot {
11572e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
11672e5016fSJean-Jacques Hiblot 
11772e5016fSJean-Jacques Hiblot 	return ops->exit ? ops->exit(phy) : 0;
11872e5016fSJean-Jacques Hiblot }
11972e5016fSJean-Jacques Hiblot 
12072e5016fSJean-Jacques Hiblot int generic_phy_power_on(struct phy *phy)
12172e5016fSJean-Jacques Hiblot {
12272e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
12372e5016fSJean-Jacques Hiblot 
12472e5016fSJean-Jacques Hiblot 	return ops->power_on ? ops->power_on(phy) : 0;
12572e5016fSJean-Jacques Hiblot }
12672e5016fSJean-Jacques Hiblot 
12772e5016fSJean-Jacques Hiblot int generic_phy_power_off(struct phy *phy)
12872e5016fSJean-Jacques Hiblot {
12972e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
13072e5016fSJean-Jacques Hiblot 
13172e5016fSJean-Jacques Hiblot 	return ops->power_off ? ops->power_off(phy) : 0;
13272e5016fSJean-Jacques Hiblot }
13372e5016fSJean-Jacques Hiblot 
13472e5016fSJean-Jacques Hiblot UCLASS_DRIVER(phy) = {
13572e5016fSJean-Jacques Hiblot 	.id		= UCLASS_PHY,
13672e5016fSJean-Jacques Hiblot 	.name		= "phy",
13772e5016fSJean-Jacques Hiblot };
138