1 /* 2 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 3 * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <generic-phy.h> 11 12 DECLARE_GLOBAL_DATA_PTR; 13 14 static inline struct phy_ops *phy_dev_ops(struct udevice *dev) 15 { 16 return (struct phy_ops *)dev->driver->ops; 17 } 18 19 static int generic_phy_xlate_offs_flags(struct phy *phy, 20 struct ofnode_phandle_args *args) 21 { 22 debug("%s(phy=%p)\n", __func__, phy); 23 24 if (args->args_count > 1) { 25 debug("Invaild args_count: %d\n", args->args_count); 26 return -EINVAL; 27 } 28 29 if (args->args_count) 30 phy->id = args->args[0]; 31 else 32 phy->id = 0; 33 34 return 0; 35 } 36 37 int generic_phy_get_by_index(struct udevice *dev, int index, 38 struct phy *phy) 39 { 40 struct ofnode_phandle_args args; 41 struct phy_ops *ops; 42 int ret; 43 struct udevice *phydev; 44 45 debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy); 46 47 assert(phy); 48 phy->dev = NULL; 49 ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index, 50 &args); 51 if (ret) { 52 debug("%s: dev_read_phandle_with_args failed: err=%d\n", 53 __func__, ret); 54 return ret; 55 } 56 57 ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev); 58 if (ret) { 59 debug("%s: uclass_get_device_by_ofnode failed: err=%d\n", 60 __func__, ret); 61 return ret; 62 } 63 64 phy->dev = phydev; 65 66 ops = phy_dev_ops(phydev); 67 68 if (ops->of_xlate) 69 ret = ops->of_xlate(phy, &args); 70 else 71 ret = generic_phy_xlate_offs_flags(phy, &args); 72 if (ret) { 73 debug("of_xlate() failed: %d\n", ret); 74 goto err; 75 } 76 77 return 0; 78 79 err: 80 return ret; 81 } 82 83 int generic_phy_get_by_name(struct udevice *dev, const char *phy_name, 84 struct phy *phy) 85 { 86 int index; 87 88 debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy); 89 90 index = dev_read_stringlist_search(dev, "phy-names", phy_name); 91 if (index < 0) { 92 debug("dev_read_stringlist_search() failed: %d\n", index); 93 return index; 94 } 95 96 return generic_phy_get_by_index(dev, index, phy); 97 } 98 99 int generic_phy_init(struct phy *phy) 100 { 101 struct phy_ops const *ops = phy_dev_ops(phy->dev); 102 103 return ops->init ? ops->init(phy) : 0; 104 } 105 106 int generic_phy_reset(struct phy *phy) 107 { 108 struct phy_ops const *ops = phy_dev_ops(phy->dev); 109 110 return ops->reset ? ops->reset(phy) : 0; 111 } 112 113 int generic_phy_exit(struct phy *phy) 114 { 115 struct phy_ops const *ops = phy_dev_ops(phy->dev); 116 117 return ops->exit ? ops->exit(phy) : 0; 118 } 119 120 int generic_phy_power_on(struct phy *phy) 121 { 122 struct phy_ops const *ops = phy_dev_ops(phy->dev); 123 124 return ops->power_on ? ops->power_on(phy) : 0; 125 } 126 127 int generic_phy_power_off(struct phy *phy) 128 { 129 struct phy_ops const *ops = phy_dev_ops(phy->dev); 130 131 return ops->power_off ? ops->power_off(phy) : 0; 132 } 133 134 UCLASS_DRIVER(phy) = { 135 .id = UCLASS_PHY, 136 .name = "phy", 137 }; 138