]> git.sur5r.net Git - u-boot/blob - drivers/phy/phy-uclass.c
bdca4c0238ac037764e4228361a97b23ac1317f4
[u-boot] / drivers / phy / phy-uclass.c
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 static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
13 {
14         return (struct phy_ops *)dev->driver->ops;
15 }
16
17 static int generic_phy_xlate_offs_flags(struct phy *phy,
18                                         struct ofnode_phandle_args *args)
19 {
20         debug("%s(phy=%p)\n", __func__, phy);
21
22         if (args->args_count > 1) {
23                 debug("Invaild args_count: %d\n", args->args_count);
24                 return -EINVAL;
25         }
26
27         if (args->args_count)
28                 phy->id = args->args[0];
29         else
30                 phy->id = 0;
31
32         return 0;
33 }
34
35 int generic_phy_get_by_index(struct udevice *dev, int index,
36                              struct phy *phy)
37 {
38         struct ofnode_phandle_args args;
39         struct phy_ops *ops;
40         int ret;
41         struct udevice *phydev;
42
43         debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
44
45         assert(phy);
46         phy->dev = NULL;
47         ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
48                                          &args);
49         if (ret) {
50                 debug("%s: dev_read_phandle_with_args failed: err=%d\n",
51                       __func__, ret);
52                 return ret;
53         }
54
55         ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
56         if (ret) {
57                 debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
58                       __func__, ret);
59                 return ret;
60         }
61
62         phy->dev = phydev;
63
64         ops = phy_dev_ops(phydev);
65
66         if (ops->of_xlate)
67                 ret = ops->of_xlate(phy, &args);
68         else
69                 ret = generic_phy_xlate_offs_flags(phy, &args);
70         if (ret) {
71                 debug("of_xlate() failed: %d\n", ret);
72                 goto err;
73         }
74
75         return 0;
76
77 err:
78         return ret;
79 }
80
81 int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
82                             struct phy *phy)
83 {
84         int index;
85
86         debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
87
88         index = dev_read_stringlist_search(dev, "phy-names", phy_name);
89         if (index < 0) {
90                 debug("dev_read_stringlist_search() failed: %d\n", index);
91                 return index;
92         }
93
94         return generic_phy_get_by_index(dev, index, phy);
95 }
96
97 int generic_phy_init(struct phy *phy)
98 {
99         struct phy_ops const *ops = phy_dev_ops(phy->dev);
100
101         return ops->init ? ops->init(phy) : 0;
102 }
103
104 int generic_phy_reset(struct phy *phy)
105 {
106         struct phy_ops const *ops = phy_dev_ops(phy->dev);
107
108         return ops->reset ? ops->reset(phy) : 0;
109 }
110
111 int generic_phy_exit(struct phy *phy)
112 {
113         struct phy_ops const *ops = phy_dev_ops(phy->dev);
114
115         return ops->exit ? ops->exit(phy) : 0;
116 }
117
118 int generic_phy_power_on(struct phy *phy)
119 {
120         struct phy_ops const *ops = phy_dev_ops(phy->dev);
121
122         return ops->power_on ? ops->power_on(phy) : 0;
123 }
124
125 int generic_phy_power_off(struct phy *phy)
126 {
127         struct phy_ops const *ops = phy_dev_ops(phy->dev);
128
129         return ops->power_off ? ops->power_off(phy) : 0;
130 }
131
132 UCLASS_DRIVER(phy) = {
133         .id             = UCLASS_PHY,
134         .name           = "phy",
135 };