Merge tag 'u-boot-stm32-20211012' of https://source.denx.de/u-boot/custodians/u-boot-stm
[platform/kernel/u-boot.git] / drivers / phy / phy-uclass.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
4  * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
5  */
6
7 #define LOG_CATEGORY UCLASS_PHY
8
9 #include <common.h>
10 #include <dm.h>
11 #include <dm/device_compat.h>
12 #include <dm/devres.h>
13 #include <generic-phy.h>
14
15 static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
16 {
17         return (struct phy_ops *)dev->driver->ops;
18 }
19
20 static int generic_phy_xlate_offs_flags(struct phy *phy,
21                                         struct ofnode_phandle_args *args)
22 {
23         debug("%s(phy=%p)\n", __func__, phy);
24
25         if (args->args_count > 1) {
26                 debug("Invaild args_count: %d\n", args->args_count);
27                 return -EINVAL;
28         }
29
30         if (args->args_count)
31                 phy->id = args->args[0];
32         else
33                 phy->id = 0;
34
35         return 0;
36 }
37
38 int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy)
39 {
40         struct ofnode_phandle_args args;
41         struct phy_ops *ops;
42         struct udevice *phydev;
43         int i, ret;
44
45         debug("%s(node=%s, index=%d, phy=%p)\n",
46               __func__, ofnode_get_name(node), index, phy);
47
48         assert(phy);
49         phy->dev = NULL;
50         ret = ofnode_parse_phandle_with_args(node, "phys", "#phy-cells", 0,
51                                              index, &args);
52         if (ret) {
53                 debug("%s: dev_read_phandle_with_args failed: err=%d\n",
54                       __func__, ret);
55                 return ret;
56         }
57
58         ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
59         if (ret) {
60                 debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
61                       __func__, ret);
62
63                 /* Check if args.node's parent is a PHY provider */
64                 ret = uclass_get_device_by_ofnode(UCLASS_PHY,
65                                                   ofnode_get_parent(args.node),
66                                                   &phydev);
67                 if (ret)
68                         return ret;
69
70                 /* insert phy idx at first position into args array */
71                 for (i = args.args_count; i >= 1 ; i--)
72                         args.args[i] = args.args[i - 1];
73
74                 args.args_count++;
75                 args.args[0] = ofnode_read_u32_default(args.node, "reg", -1);
76         }
77
78         phy->dev = phydev;
79
80         ops = phy_dev_ops(phydev);
81
82         if (ops->of_xlate)
83                 ret = ops->of_xlate(phy, &args);
84         else
85                 ret = generic_phy_xlate_offs_flags(phy, &args);
86         if (ret) {
87                 debug("of_xlate() failed: %d\n", ret);
88                 goto err;
89         }
90
91         return 0;
92
93 err:
94         return ret;
95 }
96
97 int generic_phy_get_by_index(struct udevice *dev, int index,
98                              struct phy *phy)
99 {
100         return generic_phy_get_by_index_nodev(dev_ofnode(dev), index, phy);
101 }
102
103 int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
104                             struct phy *phy)
105 {
106         int index;
107
108         debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
109
110         index = dev_read_stringlist_search(dev, "phy-names", phy_name);
111         if (index < 0) {
112                 debug("dev_read_stringlist_search() failed: %d\n", index);
113                 return index;
114         }
115
116         return generic_phy_get_by_index(dev, index, phy);
117 }
118
119 int generic_phy_init(struct phy *phy)
120 {
121         struct phy_ops const *ops;
122         int ret;
123
124         if (!generic_phy_valid(phy))
125                 return 0;
126         ops = phy_dev_ops(phy->dev);
127         if (!ops->init)
128                 return 0;
129         ret = ops->init(phy);
130         if (ret)
131                 dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
132                         phy->dev->name, ret);
133
134         return ret;
135 }
136
137 int generic_phy_reset(struct phy *phy)
138 {
139         struct phy_ops const *ops;
140         int ret;
141
142         if (!generic_phy_valid(phy))
143                 return 0;
144         ops = phy_dev_ops(phy->dev);
145         if (!ops->reset)
146                 return 0;
147         ret = ops->reset(phy);
148         if (ret)
149                 dev_err(phy->dev, "PHY: Failed to reset %s: %d.\n",
150                         phy->dev->name, ret);
151
152         return ret;
153 }
154
155 int generic_phy_exit(struct phy *phy)
156 {
157         struct phy_ops const *ops;
158         int ret;
159
160         if (!generic_phy_valid(phy))
161                 return 0;
162         ops = phy_dev_ops(phy->dev);
163         if (!ops->exit)
164                 return 0;
165         ret = ops->exit(phy);
166         if (ret)
167                 dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n",
168                         phy->dev->name, ret);
169
170         return ret;
171 }
172
173 int generic_phy_power_on(struct phy *phy)
174 {
175         struct phy_ops const *ops;
176         int ret;
177
178         if (!generic_phy_valid(phy))
179                 return 0;
180         ops = phy_dev_ops(phy->dev);
181         if (!ops->power_on)
182                 return 0;
183         ret = ops->power_on(phy);
184         if (ret)
185                 dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",
186                         phy->dev->name, ret);
187
188         return ret;
189 }
190
191 int generic_phy_power_off(struct phy *phy)
192 {
193         struct phy_ops const *ops;
194         int ret;
195
196         if (!generic_phy_valid(phy))
197                 return 0;
198         ops = phy_dev_ops(phy->dev);
199         if (!ops->power_off)
200                 return 0;
201         ret = ops->power_off(phy);
202         if (ret)
203                 dev_err(phy->dev, "PHY: Failed to power off %s: %d.\n",
204                         phy->dev->name, ret);
205
206         return ret;
207 }
208
209 int generic_phy_configure(struct phy *phy, void *params)
210 {
211         struct phy_ops const *ops;
212
213         if (!generic_phy_valid(phy))
214                 return 0;
215         ops = phy_dev_ops(phy->dev);
216
217         return ops->configure ? ops->configure(phy, params) : 0;
218 }
219
220 int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk)
221 {
222         int i, ret, count;
223
224         bulk->count = 0;
225
226         /* Return if no phy declared */
227         if (!dev_read_prop(dev, "phys", NULL))
228                 return 0;
229
230         count = dev_count_phandle_with_args(dev, "phys", "#phy-cells", 0);
231         if (count < 1)
232                 return count;
233
234         bulk->phys = devm_kcalloc(dev, count, sizeof(struct phy), GFP_KERNEL);
235         if (!bulk->phys)
236                 return -ENOMEM;
237
238         for (i = 0; i < count; i++) {
239                 ret = generic_phy_get_by_index(dev, i, &bulk->phys[i]);
240                 if (ret) {
241                         pr_err("Failed to get PHY%d for %s\n", i, dev->name);
242                         return ret;
243                 }
244                 bulk->count++;
245         }
246
247         return 0;
248 }
249
250 int generic_phy_init_bulk(struct phy_bulk *bulk)
251 {
252         struct phy *phys = bulk->phys;
253         int i, ret;
254
255         for (i = 0; i < bulk->count; i++) {
256                 ret = generic_phy_init(&phys[i]);
257                 if (ret) {
258                         pr_err("Can't init PHY%d\n", i);
259                         goto phys_init_err;
260                 }
261         }
262
263         return 0;
264
265 phys_init_err:
266         for (; i > 0; i--)
267                 generic_phy_exit(&phys[i - 1]);
268
269         return ret;
270 }
271
272 int generic_phy_exit_bulk(struct phy_bulk *bulk)
273 {
274         struct phy *phys = bulk->phys;
275         int i, ret = 0;
276
277         for (i = 0; i < bulk->count; i++)
278                 ret |= generic_phy_exit(&phys[i]);
279
280         return ret;
281 }
282
283 int generic_phy_power_on_bulk(struct phy_bulk *bulk)
284 {
285         struct phy *phys = bulk->phys;
286         int i, ret;
287
288         for (i = 0; i < bulk->count; i++) {
289                 ret = generic_phy_power_on(&phys[i]);
290                 if (ret) {
291                         pr_err("Can't power on PHY%d\n", i);
292                         goto phys_poweron_err;
293                 }
294         }
295
296         return 0;
297
298 phys_poweron_err:
299         for (; i > 0; i--)
300                 generic_phy_power_off(&phys[i - 1]);
301
302         return ret;
303 }
304
305 int generic_phy_power_off_bulk(struct phy_bulk *bulk)
306 {
307         struct phy *phys = bulk->phys;
308         int i, ret = 0;
309
310         for (i = 0; i < bulk->count; i++)
311                 ret |= generic_phy_power_off(&phys[i]);
312
313         return ret;
314 }
315
316 UCLASS_DRIVER(phy) = {
317         .id             = UCLASS_PHY,
318         .name           = "phy",
319 };