1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * phy.h -- generic phy header file |
4 | * |
5 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com |
6 | * |
7 | * Author: Kishon Vijay Abraham I <kishon@ti.com> |
8 | */ |
9 | |
10 | #ifndef __DRIVERS_PHY_H |
11 | #define __DRIVERS_PHY_H |
12 | |
13 | #include <linux/err.h> |
14 | #include <linux/of.h> |
15 | #include <linux/device.h> |
16 | #include <linux/pm_runtime.h> |
17 | #include <linux/regulator/consumer.h> |
18 | |
19 | #include <linux/phy/phy-dp.h> |
20 | #include <linux/phy/phy-lvds.h> |
21 | #include <linux/phy/phy-mipi-dphy.h> |
22 | |
23 | struct phy; |
24 | |
25 | enum phy_mode { |
26 | PHY_MODE_INVALID, |
27 | PHY_MODE_USB_HOST, |
28 | PHY_MODE_USB_HOST_LS, |
29 | PHY_MODE_USB_HOST_FS, |
30 | PHY_MODE_USB_HOST_HS, |
31 | PHY_MODE_USB_HOST_SS, |
32 | PHY_MODE_USB_DEVICE, |
33 | PHY_MODE_USB_DEVICE_LS, |
34 | PHY_MODE_USB_DEVICE_FS, |
35 | PHY_MODE_USB_DEVICE_HS, |
36 | PHY_MODE_USB_DEVICE_SS, |
37 | PHY_MODE_USB_OTG, |
38 | PHY_MODE_UFS_HS_A, |
39 | PHY_MODE_UFS_HS_B, |
40 | PHY_MODE_PCIE, |
41 | PHY_MODE_ETHERNET, |
42 | PHY_MODE_MIPI_DPHY, |
43 | PHY_MODE_SATA, |
44 | PHY_MODE_LVDS, |
45 | PHY_MODE_DP |
46 | }; |
47 | |
48 | enum phy_media { |
49 | PHY_MEDIA_DEFAULT, |
50 | PHY_MEDIA_SR, |
51 | PHY_MEDIA_DAC, |
52 | }; |
53 | |
54 | /** |
55 | * union phy_configure_opts - Opaque generic phy configuration |
56 | * |
57 | * @mipi_dphy: Configuration set applicable for phys supporting |
58 | * the MIPI_DPHY phy mode. |
59 | * @dp: Configuration set applicable for phys supporting |
60 | * the DisplayPort protocol. |
61 | * @lvds: Configuration set applicable for phys supporting |
62 | * the LVDS phy mode. |
63 | */ |
64 | union phy_configure_opts { |
65 | struct phy_configure_opts_mipi_dphy mipi_dphy; |
66 | struct phy_configure_opts_dp dp; |
67 | struct phy_configure_opts_lvds lvds; |
68 | }; |
69 | |
70 | /** |
71 | * struct phy_ops - set of function pointers for performing phy operations |
72 | * @init: operation to be performed for initializing phy |
73 | * @exit: operation to be performed while exiting |
74 | * @power_on: powering on the phy |
75 | * @power_off: powering off the phy |
76 | * @set_mode: set the mode of the phy |
77 | * @set_media: set the media type of the phy (optional) |
78 | * @set_speed: set the speed of the phy (optional) |
79 | * @reset: resetting the phy |
80 | * @calibrate: calibrate the phy |
81 | * @release: ops to be performed while the consumer relinquishes the PHY |
82 | * @owner: the module owner containing the ops |
83 | */ |
84 | struct phy_ops { |
85 | int (*init)(struct phy *phy); |
86 | int (*exit)(struct phy *phy); |
87 | int (*power_on)(struct phy *phy); |
88 | int (*power_off)(struct phy *phy); |
89 | int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); |
90 | int (*set_media)(struct phy *phy, enum phy_media media); |
91 | int (*set_speed)(struct phy *phy, int speed); |
92 | |
93 | /** |
94 | * @configure: |
95 | * |
96 | * Optional. |
97 | * |
98 | * Used to change the PHY parameters. phy_init() must have |
99 | * been called on the phy. |
100 | * |
101 | * Returns: 0 if successful, an negative error code otherwise |
102 | */ |
103 | int (*configure)(struct phy *phy, union phy_configure_opts *opts); |
104 | |
105 | /** |
106 | * @validate: |
107 | * |
108 | * Optional. |
109 | * |
110 | * Used to check that the current set of parameters can be |
111 | * handled by the phy. Implementations are free to tune the |
112 | * parameters passed as arguments if needed by some |
113 | * implementation detail or constraints. It must not change |
114 | * any actual configuration of the PHY, so calling it as many |
115 | * times as deemed fit by the consumer must have no side |
116 | * effect. |
117 | * |
118 | * Returns: 0 if the configuration can be applied, an negative |
119 | * error code otherwise |
120 | */ |
121 | int (*validate)(struct phy *phy, enum phy_mode mode, int submode, |
122 | union phy_configure_opts *opts); |
123 | int (*reset)(struct phy *phy); |
124 | int (*calibrate)(struct phy *phy); |
125 | |
126 | /* notify phy connect status change */ |
127 | int (*connect)(struct phy *phy, int port); |
128 | int (*disconnect)(struct phy *phy, int port); |
129 | |
130 | void (*release)(struct phy *phy); |
131 | struct module *owner; |
132 | }; |
133 | |
134 | /** |
135 | * struct phy_attrs - represents phy attributes |
136 | * @bus_width: Data path width implemented by PHY |
137 | * @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer) |
138 | * @mode: PHY mode |
139 | */ |
140 | struct phy_attrs { |
141 | u32 bus_width; |
142 | u32 max_link_rate; |
143 | enum phy_mode mode; |
144 | }; |
145 | |
146 | /** |
147 | * struct phy - represents the phy device |
148 | * @dev: phy device |
149 | * @id: id of the phy device |
150 | * @ops: function pointers for performing phy operations |
151 | * @mutex: mutex to protect phy_ops |
152 | * @init_count: used to protect when the PHY is used by multiple consumers |
153 | * @power_count: used to protect when the PHY is used by multiple consumers |
154 | * @attrs: used to specify PHY specific attributes |
155 | * @pwr: power regulator associated with the phy |
156 | * @debugfs: debugfs directory |
157 | */ |
158 | struct phy { |
159 | struct device dev; |
160 | int id; |
161 | const struct phy_ops *ops; |
162 | struct mutex mutex; |
163 | int init_count; |
164 | int power_count; |
165 | struct phy_attrs attrs; |
166 | struct regulator *pwr; |
167 | struct dentry *debugfs; |
168 | }; |
169 | |
170 | /** |
171 | * struct phy_provider - represents the phy provider |
172 | * @dev: phy provider device |
173 | * @children: can be used to override the default (dev->of_node) child node |
174 | * @owner: the module owner having of_xlate |
175 | * @list: to maintain a linked list of PHY providers |
176 | * @of_xlate: function pointer to obtain phy instance from phy pointer |
177 | */ |
178 | struct phy_provider { |
179 | struct device *dev; |
180 | struct device_node *children; |
181 | struct module *owner; |
182 | struct list_head list; |
183 | struct phy * (*of_xlate)(struct device *dev, |
184 | const struct of_phandle_args *args); |
185 | }; |
186 | |
187 | /** |
188 | * struct phy_lookup - PHY association in list of phys managed by the phy driver |
189 | * @node: list node |
190 | * @dev_id: the device of the association |
191 | * @con_id: connection ID string on device |
192 | * @phy: the phy of the association |
193 | */ |
194 | struct phy_lookup { |
195 | struct list_head node; |
196 | const char *dev_id; |
197 | const char *con_id; |
198 | struct phy *phy; |
199 | }; |
200 | |
201 | #define to_phy(a) (container_of((a), struct phy, dev)) |
202 | |
203 | #define of_phy_provider_register(dev, xlate) \ |
204 | __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
205 | |
206 | #define devm_of_phy_provider_register(dev, xlate) \ |
207 | __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
208 | |
209 | #define of_phy_provider_register_full(dev, children, xlate) \ |
210 | __of_phy_provider_register(dev, children, THIS_MODULE, xlate) |
211 | |
212 | #define devm_of_phy_provider_register_full(dev, children, xlate) \ |
213 | __devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate) |
214 | |
215 | static inline void phy_set_drvdata(struct phy *phy, void *data) |
216 | { |
217 | dev_set_drvdata(dev: &phy->dev, data); |
218 | } |
219 | |
220 | static inline void *phy_get_drvdata(struct phy *phy) |
221 | { |
222 | return dev_get_drvdata(dev: &phy->dev); |
223 | } |
224 | |
225 | #if IS_ENABLED(CONFIG_GENERIC_PHY) |
226 | int phy_pm_runtime_get(struct phy *phy); |
227 | int phy_pm_runtime_get_sync(struct phy *phy); |
228 | int phy_pm_runtime_put(struct phy *phy); |
229 | int phy_pm_runtime_put_sync(struct phy *phy); |
230 | void phy_pm_runtime_allow(struct phy *phy); |
231 | void phy_pm_runtime_forbid(struct phy *phy); |
232 | int phy_init(struct phy *phy); |
233 | int phy_exit(struct phy *phy); |
234 | int phy_power_on(struct phy *phy); |
235 | int phy_power_off(struct phy *phy); |
236 | int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); |
237 | #define phy_set_mode(phy, mode) \ |
238 | phy_set_mode_ext(phy, mode, 0) |
239 | int phy_set_media(struct phy *phy, enum phy_media media); |
240 | int phy_set_speed(struct phy *phy, int speed); |
241 | int phy_configure(struct phy *phy, union phy_configure_opts *opts); |
242 | int phy_validate(struct phy *phy, enum phy_mode mode, int submode, |
243 | union phy_configure_opts *opts); |
244 | |
245 | static inline enum phy_mode phy_get_mode(struct phy *phy) |
246 | { |
247 | return phy->attrs.mode; |
248 | } |
249 | int phy_reset(struct phy *phy); |
250 | int phy_calibrate(struct phy *phy); |
251 | int phy_notify_connect(struct phy *phy, int port); |
252 | int phy_notify_disconnect(struct phy *phy, int port); |
253 | static inline int phy_get_bus_width(struct phy *phy) |
254 | { |
255 | return phy->attrs.bus_width; |
256 | } |
257 | static inline void phy_set_bus_width(struct phy *phy, int bus_width) |
258 | { |
259 | phy->attrs.bus_width = bus_width; |
260 | } |
261 | struct phy *phy_get(struct device *dev, const char *string); |
262 | struct phy *devm_phy_get(struct device *dev, const char *string); |
263 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); |
264 | struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, |
265 | const char *con_id); |
266 | struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np, |
267 | const char *con_id); |
268 | struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, |
269 | int index); |
270 | void of_phy_put(struct phy *phy); |
271 | void phy_put(struct device *dev, struct phy *phy); |
272 | void devm_phy_put(struct device *dev, struct phy *phy); |
273 | struct phy *of_phy_get(struct device_node *np, const char *con_id); |
274 | struct phy *of_phy_simple_xlate(struct device *dev, |
275 | const struct of_phandle_args *args); |
276 | struct phy *phy_create(struct device *dev, struct device_node *node, |
277 | const struct phy_ops *ops); |
278 | struct phy *devm_phy_create(struct device *dev, struct device_node *node, |
279 | const struct phy_ops *ops); |
280 | void phy_destroy(struct phy *phy); |
281 | void devm_phy_destroy(struct device *dev, struct phy *phy); |
282 | struct phy_provider *__of_phy_provider_register(struct device *dev, |
283 | struct device_node *children, struct module *owner, |
284 | struct phy * (*of_xlate)(struct device *dev, |
285 | const struct of_phandle_args *args)); |
286 | struct phy_provider *__devm_of_phy_provider_register(struct device *dev, |
287 | struct device_node *children, struct module *owner, |
288 | struct phy * (*of_xlate)(struct device *dev, |
289 | const struct of_phandle_args *args)); |
290 | void of_phy_provider_unregister(struct phy_provider *phy_provider); |
291 | void devm_of_phy_provider_unregister(struct device *dev, |
292 | struct phy_provider *phy_provider); |
293 | int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); |
294 | void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); |
295 | #else |
296 | static inline int phy_pm_runtime_get(struct phy *phy) |
297 | { |
298 | if (!phy) |
299 | return 0; |
300 | return -ENOSYS; |
301 | } |
302 | |
303 | static inline int phy_pm_runtime_get_sync(struct phy *phy) |
304 | { |
305 | if (!phy) |
306 | return 0; |
307 | return -ENOSYS; |
308 | } |
309 | |
310 | static inline int phy_pm_runtime_put(struct phy *phy) |
311 | { |
312 | if (!phy) |
313 | return 0; |
314 | return -ENOSYS; |
315 | } |
316 | |
317 | static inline int phy_pm_runtime_put_sync(struct phy *phy) |
318 | { |
319 | if (!phy) |
320 | return 0; |
321 | return -ENOSYS; |
322 | } |
323 | |
324 | static inline void phy_pm_runtime_allow(struct phy *phy) |
325 | { |
326 | return; |
327 | } |
328 | |
329 | static inline void phy_pm_runtime_forbid(struct phy *phy) |
330 | { |
331 | return; |
332 | } |
333 | |
334 | static inline int phy_init(struct phy *phy) |
335 | { |
336 | if (!phy) |
337 | return 0; |
338 | return -ENOSYS; |
339 | } |
340 | |
341 | static inline int phy_exit(struct phy *phy) |
342 | { |
343 | if (!phy) |
344 | return 0; |
345 | return -ENOSYS; |
346 | } |
347 | |
348 | static inline int phy_power_on(struct phy *phy) |
349 | { |
350 | if (!phy) |
351 | return 0; |
352 | return -ENOSYS; |
353 | } |
354 | |
355 | static inline int phy_power_off(struct phy *phy) |
356 | { |
357 | if (!phy) |
358 | return 0; |
359 | return -ENOSYS; |
360 | } |
361 | |
362 | static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, |
363 | int submode) |
364 | { |
365 | if (!phy) |
366 | return 0; |
367 | return -ENOSYS; |
368 | } |
369 | |
370 | #define phy_set_mode(phy, mode) \ |
371 | phy_set_mode_ext(phy, mode, 0) |
372 | |
373 | static inline int phy_set_media(struct phy *phy, enum phy_media media) |
374 | { |
375 | if (!phy) |
376 | return 0; |
377 | return -ENODEV; |
378 | } |
379 | |
380 | static inline int phy_set_speed(struct phy *phy, int speed) |
381 | { |
382 | if (!phy) |
383 | return 0; |
384 | return -ENODEV; |
385 | } |
386 | |
387 | static inline enum phy_mode phy_get_mode(struct phy *phy) |
388 | { |
389 | return PHY_MODE_INVALID; |
390 | } |
391 | |
392 | static inline int phy_reset(struct phy *phy) |
393 | { |
394 | if (!phy) |
395 | return 0; |
396 | return -ENOSYS; |
397 | } |
398 | |
399 | static inline int phy_calibrate(struct phy *phy) |
400 | { |
401 | if (!phy) |
402 | return 0; |
403 | return -ENOSYS; |
404 | } |
405 | |
406 | static inline int phy_notify_connect(struct phy *phy, int index) |
407 | { |
408 | if (!phy) |
409 | return 0; |
410 | return -ENOSYS; |
411 | } |
412 | |
413 | static inline int phy_notify_disconnect(struct phy *phy, int index) |
414 | { |
415 | if (!phy) |
416 | return 0; |
417 | return -ENOSYS; |
418 | } |
419 | |
420 | static inline int phy_configure(struct phy *phy, |
421 | union phy_configure_opts *opts) |
422 | { |
423 | if (!phy) |
424 | return 0; |
425 | |
426 | return -ENOSYS; |
427 | } |
428 | |
429 | static inline int phy_validate(struct phy *phy, enum phy_mode mode, int submode, |
430 | union phy_configure_opts *opts) |
431 | { |
432 | if (!phy) |
433 | return 0; |
434 | |
435 | return -ENOSYS; |
436 | } |
437 | |
438 | static inline int phy_get_bus_width(struct phy *phy) |
439 | { |
440 | return -ENOSYS; |
441 | } |
442 | |
443 | static inline void phy_set_bus_width(struct phy *phy, int bus_width) |
444 | { |
445 | return; |
446 | } |
447 | |
448 | static inline struct phy *phy_get(struct device *dev, const char *string) |
449 | { |
450 | return ERR_PTR(-ENOSYS); |
451 | } |
452 | |
453 | static inline struct phy *devm_phy_get(struct device *dev, const char *string) |
454 | { |
455 | return ERR_PTR(-ENOSYS); |
456 | } |
457 | |
458 | static inline struct phy *devm_phy_optional_get(struct device *dev, |
459 | const char *string) |
460 | { |
461 | return NULL; |
462 | } |
463 | |
464 | static inline struct phy *devm_of_phy_get(struct device *dev, |
465 | struct device_node *np, |
466 | const char *con_id) |
467 | { |
468 | return ERR_PTR(-ENOSYS); |
469 | } |
470 | |
471 | static inline struct phy *devm_of_phy_optional_get(struct device *dev, |
472 | struct device_node *np, |
473 | const char *con_id) |
474 | { |
475 | return NULL; |
476 | } |
477 | |
478 | static inline struct phy *devm_of_phy_get_by_index(struct device *dev, |
479 | struct device_node *np, |
480 | int index) |
481 | { |
482 | return ERR_PTR(-ENOSYS); |
483 | } |
484 | |
485 | static inline void of_phy_put(struct phy *phy) |
486 | { |
487 | } |
488 | |
489 | static inline void phy_put(struct device *dev, struct phy *phy) |
490 | { |
491 | } |
492 | |
493 | static inline void devm_phy_put(struct device *dev, struct phy *phy) |
494 | { |
495 | } |
496 | |
497 | static inline struct phy *of_phy_get(struct device_node *np, const char *con_id) |
498 | { |
499 | return ERR_PTR(-ENOSYS); |
500 | } |
501 | |
502 | static inline struct phy *of_phy_simple_xlate(struct device *dev, |
503 | const struct of_phandle_args *args) |
504 | { |
505 | return ERR_PTR(-ENOSYS); |
506 | } |
507 | |
508 | static inline struct phy *phy_create(struct device *dev, |
509 | struct device_node *node, |
510 | const struct phy_ops *ops) |
511 | { |
512 | return ERR_PTR(-ENOSYS); |
513 | } |
514 | |
515 | static inline struct phy *devm_phy_create(struct device *dev, |
516 | struct device_node *node, |
517 | const struct phy_ops *ops) |
518 | { |
519 | return ERR_PTR(-ENOSYS); |
520 | } |
521 | |
522 | static inline void phy_destroy(struct phy *phy) |
523 | { |
524 | } |
525 | |
526 | static inline void devm_phy_destroy(struct device *dev, struct phy *phy) |
527 | { |
528 | } |
529 | |
530 | static inline struct phy_provider *__of_phy_provider_register( |
531 | struct device *dev, struct device_node *children, struct module *owner, |
532 | struct phy * (*of_xlate)(struct device *dev, |
533 | const struct of_phandle_args *args)) |
534 | { |
535 | return ERR_PTR(-ENOSYS); |
536 | } |
537 | |
538 | static inline struct phy_provider *__devm_of_phy_provider_register(struct device |
539 | *dev, struct device_node *children, struct module *owner, |
540 | struct phy * (*of_xlate)(struct device *dev, |
541 | const struct of_phandle_args *args)) |
542 | { |
543 | return ERR_PTR(-ENOSYS); |
544 | } |
545 | |
546 | static inline void of_phy_provider_unregister(struct phy_provider *phy_provider) |
547 | { |
548 | } |
549 | |
550 | static inline void devm_of_phy_provider_unregister(struct device *dev, |
551 | struct phy_provider *phy_provider) |
552 | { |
553 | } |
554 | static inline int |
555 | phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) |
556 | { |
557 | return 0; |
558 | } |
559 | static inline void phy_remove_lookup(struct phy *phy, const char *con_id, |
560 | const char *dev_id) { } |
561 | #endif |
562 | |
563 | #endif /* __DRIVERS_PHY_H */ |
564 | |