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 | void (*release)(struct phy *phy); |
126 | struct module *owner; |
127 | }; |
128 | |
129 | /** |
130 | * struct phy_attrs - represents phy attributes |
131 | * @bus_width: Data path width implemented by PHY |
132 | * @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer) |
133 | * @mode: PHY mode |
134 | */ |
135 | struct phy_attrs { |
136 | u32 bus_width; |
137 | u32 max_link_rate; |
138 | enum phy_mode mode; |
139 | }; |
140 | |
141 | /** |
142 | * struct phy - represents the phy device |
143 | * @dev: phy device |
144 | * @id: id of the phy device |
145 | * @ops: function pointers for performing phy operations |
146 | * @mutex: mutex to protect phy_ops |
147 | * @init_count: used to protect when the PHY is used by multiple consumers |
148 | * @power_count: used to protect when the PHY is used by multiple consumers |
149 | * @attrs: used to specify PHY specific attributes |
150 | * @pwr: power regulator associated with the phy |
151 | * @debugfs: debugfs directory |
152 | */ |
153 | struct phy { |
154 | struct device dev; |
155 | int id; |
156 | const struct phy_ops *ops; |
157 | struct mutex mutex; |
158 | int init_count; |
159 | int power_count; |
160 | struct phy_attrs attrs; |
161 | struct regulator *pwr; |
162 | struct dentry *debugfs; |
163 | }; |
164 | |
165 | /** |
166 | * struct phy_provider - represents the phy provider |
167 | * @dev: phy provider device |
168 | * @children: can be used to override the default (dev->of_node) child node |
169 | * @owner: the module owner having of_xlate |
170 | * @list: to maintain a linked list of PHY providers |
171 | * @of_xlate: function pointer to obtain phy instance from phy pointer |
172 | */ |
173 | struct phy_provider { |
174 | struct device *dev; |
175 | struct device_node *children; |
176 | struct module *owner; |
177 | struct list_head list; |
178 | struct phy * (*of_xlate)(struct device *dev, |
179 | struct of_phandle_args *args); |
180 | }; |
181 | |
182 | /** |
183 | * struct phy_lookup - PHY association in list of phys managed by the phy driver |
184 | * @node: list node |
185 | * @dev_id: the device of the association |
186 | * @con_id: connection ID string on device |
187 | * @phy: the phy of the association |
188 | */ |
189 | struct phy_lookup { |
190 | struct list_head node; |
191 | const char *dev_id; |
192 | const char *con_id; |
193 | struct phy *phy; |
194 | }; |
195 | |
196 | #define to_phy(a) (container_of((a), struct phy, dev)) |
197 | |
198 | #define of_phy_provider_register(dev, xlate) \ |
199 | __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
200 | |
201 | #define devm_of_phy_provider_register(dev, xlate) \ |
202 | __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
203 | |
204 | #define of_phy_provider_register_full(dev, children, xlate) \ |
205 | __of_phy_provider_register(dev, children, THIS_MODULE, xlate) |
206 | |
207 | #define devm_of_phy_provider_register_full(dev, children, xlate) \ |
208 | __devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate) |
209 | |
210 | static inline void phy_set_drvdata(struct phy *phy, void *data) |
211 | { |
212 | dev_set_drvdata(dev: &phy->dev, data); |
213 | } |
214 | |
215 | static inline void *phy_get_drvdata(struct phy *phy) |
216 | { |
217 | return dev_get_drvdata(dev: &phy->dev); |
218 | } |
219 | |
220 | #if IS_ENABLED(CONFIG_GENERIC_PHY) |
221 | int phy_pm_runtime_get(struct phy *phy); |
222 | int phy_pm_runtime_get_sync(struct phy *phy); |
223 | int phy_pm_runtime_put(struct phy *phy); |
224 | int phy_pm_runtime_put_sync(struct phy *phy); |
225 | void phy_pm_runtime_allow(struct phy *phy); |
226 | void phy_pm_runtime_forbid(struct phy *phy); |
227 | int phy_init(struct phy *phy); |
228 | int phy_exit(struct phy *phy); |
229 | int phy_power_on(struct phy *phy); |
230 | int phy_power_off(struct phy *phy); |
231 | int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); |
232 | #define phy_set_mode(phy, mode) \ |
233 | phy_set_mode_ext(phy, mode, 0) |
234 | int phy_set_media(struct phy *phy, enum phy_media media); |
235 | int phy_set_speed(struct phy *phy, int speed); |
236 | int phy_configure(struct phy *phy, union phy_configure_opts *opts); |
237 | int phy_validate(struct phy *phy, enum phy_mode mode, int submode, |
238 | union phy_configure_opts *opts); |
239 | |
240 | static inline enum phy_mode phy_get_mode(struct phy *phy) |
241 | { |
242 | return phy->attrs.mode; |
243 | } |
244 | int phy_reset(struct phy *phy); |
245 | int phy_calibrate(struct phy *phy); |
246 | static inline int phy_get_bus_width(struct phy *phy) |
247 | { |
248 | return phy->attrs.bus_width; |
249 | } |
250 | static inline void phy_set_bus_width(struct phy *phy, int bus_width) |
251 | { |
252 | phy->attrs.bus_width = bus_width; |
253 | } |
254 | struct phy *phy_get(struct device *dev, const char *string); |
255 | struct phy *devm_phy_get(struct device *dev, const char *string); |
256 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); |
257 | struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, |
258 | const char *con_id); |
259 | struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np, |
260 | const char *con_id); |
261 | struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, |
262 | int index); |
263 | void of_phy_put(struct phy *phy); |
264 | void phy_put(struct device *dev, struct phy *phy); |
265 | void devm_phy_put(struct device *dev, struct phy *phy); |
266 | struct phy *of_phy_get(struct device_node *np, const char *con_id); |
267 | struct phy *of_phy_simple_xlate(struct device *dev, |
268 | struct of_phandle_args *args); |
269 | struct phy *phy_create(struct device *dev, struct device_node *node, |
270 | const struct phy_ops *ops); |
271 | struct phy *devm_phy_create(struct device *dev, struct device_node *node, |
272 | const struct phy_ops *ops); |
273 | void phy_destroy(struct phy *phy); |
274 | void devm_phy_destroy(struct device *dev, struct phy *phy); |
275 | struct phy_provider *__of_phy_provider_register(struct device *dev, |
276 | struct device_node *children, struct module *owner, |
277 | struct phy * (*of_xlate)(struct device *dev, |
278 | struct of_phandle_args *args)); |
279 | struct phy_provider *__devm_of_phy_provider_register(struct device *dev, |
280 | struct device_node *children, struct module *owner, |
281 | struct phy * (*of_xlate)(struct device *dev, |
282 | struct of_phandle_args *args)); |
283 | void of_phy_provider_unregister(struct phy_provider *phy_provider); |
284 | void devm_of_phy_provider_unregister(struct device *dev, |
285 | struct phy_provider *phy_provider); |
286 | int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); |
287 | void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); |
288 | #else |
289 | static inline int phy_pm_runtime_get(struct phy *phy) |
290 | { |
291 | if (!phy) |
292 | return 0; |
293 | return -ENOSYS; |
294 | } |
295 | |
296 | static inline int phy_pm_runtime_get_sync(struct phy *phy) |
297 | { |
298 | if (!phy) |
299 | return 0; |
300 | return -ENOSYS; |
301 | } |
302 | |
303 | static inline int phy_pm_runtime_put(struct phy *phy) |
304 | { |
305 | if (!phy) |
306 | return 0; |
307 | return -ENOSYS; |
308 | } |
309 | |
310 | static inline int phy_pm_runtime_put_sync(struct phy *phy) |
311 | { |
312 | if (!phy) |
313 | return 0; |
314 | return -ENOSYS; |
315 | } |
316 | |
317 | static inline void phy_pm_runtime_allow(struct phy *phy) |
318 | { |
319 | return; |
320 | } |
321 | |
322 | static inline void phy_pm_runtime_forbid(struct phy *phy) |
323 | { |
324 | return; |
325 | } |
326 | |
327 | static inline int phy_init(struct phy *phy) |
328 | { |
329 | if (!phy) |
330 | return 0; |
331 | return -ENOSYS; |
332 | } |
333 | |
334 | static inline int phy_exit(struct phy *phy) |
335 | { |
336 | if (!phy) |
337 | return 0; |
338 | return -ENOSYS; |
339 | } |
340 | |
341 | static inline int phy_power_on(struct phy *phy) |
342 | { |
343 | if (!phy) |
344 | return 0; |
345 | return -ENOSYS; |
346 | } |
347 | |
348 | static inline int phy_power_off(struct phy *phy) |
349 | { |
350 | if (!phy) |
351 | return 0; |
352 | return -ENOSYS; |
353 | } |
354 | |
355 | static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, |
356 | int submode) |
357 | { |
358 | if (!phy) |
359 | return 0; |
360 | return -ENOSYS; |
361 | } |
362 | |
363 | #define phy_set_mode(phy, mode) \ |
364 | phy_set_mode_ext(phy, mode, 0) |
365 | |
366 | static inline int phy_set_media(struct phy *phy, enum phy_media media) |
367 | { |
368 | if (!phy) |
369 | return 0; |
370 | return -ENODEV; |
371 | } |
372 | |
373 | static inline int phy_set_speed(struct phy *phy, int speed) |
374 | { |
375 | if (!phy) |
376 | return 0; |
377 | return -ENODEV; |
378 | } |
379 | |
380 | static inline enum phy_mode phy_get_mode(struct phy *phy) |
381 | { |
382 | return PHY_MODE_INVALID; |
383 | } |
384 | |
385 | static inline int phy_reset(struct phy *phy) |
386 | { |
387 | if (!phy) |
388 | return 0; |
389 | return -ENOSYS; |
390 | } |
391 | |
392 | static inline int phy_calibrate(struct phy *phy) |
393 | { |
394 | if (!phy) |
395 | return 0; |
396 | return -ENOSYS; |
397 | } |
398 | |
399 | static inline int phy_configure(struct phy *phy, |
400 | union phy_configure_opts *opts) |
401 | { |
402 | if (!phy) |
403 | return 0; |
404 | |
405 | return -ENOSYS; |
406 | } |
407 | |
408 | static inline int phy_validate(struct phy *phy, enum phy_mode mode, int submode, |
409 | union phy_configure_opts *opts) |
410 | { |
411 | if (!phy) |
412 | return 0; |
413 | |
414 | return -ENOSYS; |
415 | } |
416 | |
417 | static inline int phy_get_bus_width(struct phy *phy) |
418 | { |
419 | return -ENOSYS; |
420 | } |
421 | |
422 | static inline void phy_set_bus_width(struct phy *phy, int bus_width) |
423 | { |
424 | return; |
425 | } |
426 | |
427 | static inline struct phy *phy_get(struct device *dev, const char *string) |
428 | { |
429 | return ERR_PTR(-ENOSYS); |
430 | } |
431 | |
432 | static inline struct phy *devm_phy_get(struct device *dev, const char *string) |
433 | { |
434 | return ERR_PTR(-ENOSYS); |
435 | } |
436 | |
437 | static inline struct phy *devm_phy_optional_get(struct device *dev, |
438 | const char *string) |
439 | { |
440 | return NULL; |
441 | } |
442 | |
443 | static inline struct phy *devm_of_phy_get(struct device *dev, |
444 | struct device_node *np, |
445 | const char *con_id) |
446 | { |
447 | return ERR_PTR(-ENOSYS); |
448 | } |
449 | |
450 | static inline struct phy *devm_of_phy_optional_get(struct device *dev, |
451 | struct device_node *np, |
452 | const char *con_id) |
453 | { |
454 | return NULL; |
455 | } |
456 | |
457 | static inline struct phy *devm_of_phy_get_by_index(struct device *dev, |
458 | struct device_node *np, |
459 | int index) |
460 | { |
461 | return ERR_PTR(-ENOSYS); |
462 | } |
463 | |
464 | static inline void of_phy_put(struct phy *phy) |
465 | { |
466 | } |
467 | |
468 | static inline void phy_put(struct device *dev, struct phy *phy) |
469 | { |
470 | } |
471 | |
472 | static inline void devm_phy_put(struct device *dev, struct phy *phy) |
473 | { |
474 | } |
475 | |
476 | static inline struct phy *of_phy_get(struct device_node *np, const char *con_id) |
477 | { |
478 | return ERR_PTR(-ENOSYS); |
479 | } |
480 | |
481 | static inline struct phy *of_phy_simple_xlate(struct device *dev, |
482 | struct of_phandle_args *args) |
483 | { |
484 | return ERR_PTR(-ENOSYS); |
485 | } |
486 | |
487 | static inline struct phy *phy_create(struct device *dev, |
488 | struct device_node *node, |
489 | const struct phy_ops *ops) |
490 | { |
491 | return ERR_PTR(-ENOSYS); |
492 | } |
493 | |
494 | static inline struct phy *devm_phy_create(struct device *dev, |
495 | struct device_node *node, |
496 | const struct phy_ops *ops) |
497 | { |
498 | return ERR_PTR(-ENOSYS); |
499 | } |
500 | |
501 | static inline void phy_destroy(struct phy *phy) |
502 | { |
503 | } |
504 | |
505 | static inline void devm_phy_destroy(struct device *dev, struct phy *phy) |
506 | { |
507 | } |
508 | |
509 | static inline struct phy_provider *__of_phy_provider_register( |
510 | struct device *dev, struct device_node *children, struct module *owner, |
511 | struct phy * (*of_xlate)(struct device *dev, |
512 | struct of_phandle_args *args)) |
513 | { |
514 | return ERR_PTR(-ENOSYS); |
515 | } |
516 | |
517 | static inline struct phy_provider *__devm_of_phy_provider_register(struct device |
518 | *dev, struct device_node *children, struct module *owner, |
519 | struct phy * (*of_xlate)(struct device *dev, |
520 | struct of_phandle_args *args)) |
521 | { |
522 | return ERR_PTR(-ENOSYS); |
523 | } |
524 | |
525 | static inline void of_phy_provider_unregister(struct phy_provider *phy_provider) |
526 | { |
527 | } |
528 | |
529 | static inline void devm_of_phy_provider_unregister(struct device *dev, |
530 | struct phy_provider *phy_provider) |
531 | { |
532 | } |
533 | static inline int |
534 | phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) |
535 | { |
536 | return 0; |
537 | } |
538 | static inline void phy_remove_lookup(struct phy *phy, const char *con_id, |
539 | const char *dev_id) { } |
540 | #endif |
541 | |
542 | #endif /* __DRIVERS_PHY_H */ |
543 | |