1 /**
2  * @file
3  *
4  * @brief Public APIs for MDIO drivers.
5  */
6 
7 /*
8  * Copyright (c) 2021 IP-Logix Inc.
9  * Copyright 2023 NXP
10  *
11  * SPDX-License-Identifier: Apache-2.0
12  */
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_MDIO_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_MDIO_H_
15 
16 /**
17  * @brief MDIO Interface
18  * @defgroup mdio_interface MDIO Interface
19  * @ingroup io_interfaces
20  * @{
21  */
22 #include <zephyr/types.h>
23 #include <zephyr/device.h>
24 #include <errno.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /**
31  * @cond INTERNAL_HIDDEN
32  *
33  * These are for internal use only, so skip these in
34  * public documentation.
35  */
36 __subsystem struct mdio_driver_api {
37 	/** Enable the MDIO bus device */
38 	void (*bus_enable)(const struct device *dev);
39 
40 	/** Disable the MDIO bus device */
41 	void (*bus_disable)(const struct device *dev);
42 
43 	/** Read data from MDIO bus */
44 	int (*read)(const struct device *dev, uint8_t prtad, uint8_t regad,
45 		    uint16_t *data);
46 
47 	/** Write data to MDIO bus */
48 	int (*write)(const struct device *dev, uint8_t prtad, uint8_t regad,
49 		     uint16_t data);
50 
51 	/** Read data from MDIO bus using Clause 45 access */
52 	int (*read_c45)(const struct device *dev, uint8_t prtad, uint8_t devad,
53 			uint16_t regad, uint16_t *data);
54 
55 	/** Write data to MDIO bus using Clause 45 access */
56 	int (*write_c45)(const struct device *dev, uint8_t prtad, uint8_t devad,
57 			 uint16_t regad, uint16_t data);
58 };
59 /**
60  * @endcond
61  */
62 
63 /**
64  * @brief      Enable MDIO bus
65  *
66  * @param[in]  dev   Pointer to the device structure for the controller
67  *
68  */
69 __syscall void mdio_bus_enable(const struct device *dev);
70 
z_impl_mdio_bus_enable(const struct device * dev)71 static inline void z_impl_mdio_bus_enable(const struct device *dev)
72 {
73 	const struct mdio_driver_api *api =
74 		(const struct mdio_driver_api *)dev->api;
75 
76 	if (api->bus_enable != NULL) {
77 		api->bus_enable(dev);
78 	}
79 }
80 
81 /**
82  * @brief      Disable MDIO bus and tri-state drivers
83  *
84  * @param[in]  dev   Pointer to the device structure for the controller
85  *
86  */
87 __syscall void mdio_bus_disable(const struct device *dev);
88 
z_impl_mdio_bus_disable(const struct device * dev)89 static inline void z_impl_mdio_bus_disable(const struct device *dev)
90 {
91 	const struct mdio_driver_api *api =
92 		(const struct mdio_driver_api *)dev->api;
93 
94 	if (api->bus_disable != NULL) {
95 		api->bus_disable(dev);
96 	}
97 }
98 
99 /**
100  * @brief      Read from MDIO Bus
101  *
102  * This routine provides a generic interface to perform a read on the
103  * MDIO bus.
104  *
105  * @param[in]  dev         Pointer to the device structure for the controller
106  * @param[in]  prtad       Port address
107  * @param[in]  regad       Register address
108  * @param      data        Pointer to receive read data
109  *
110  * @retval 0 If successful.
111  * @retval -EIO General input / output error.
112  * @retval -ETIMEDOUT If transaction timedout on the bus
113  * @retval -ENOSYS if read is not supported
114  */
115 __syscall int mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad,
116 			uint16_t *data);
117 
z_impl_mdio_read(const struct device * dev,uint8_t prtad,uint8_t regad,uint16_t * data)118 static inline int z_impl_mdio_read(const struct device *dev, uint8_t prtad,
119 				   uint8_t regad, uint16_t *data)
120 {
121 	const struct mdio_driver_api *api =
122 		(const struct mdio_driver_api *)dev->api;
123 
124 	if (api->read == NULL) {
125 		return -ENOSYS;
126 	}
127 
128 	return api->read(dev, prtad, regad, data);
129 }
130 
131 
132 /**
133  * @brief      Write to MDIO bus
134  *
135  * This routine provides a generic interface to perform a write on the
136  * MDIO bus.
137  *
138  * @param[in]  dev         Pointer to the device structure for the controller
139  * @param[in]  prtad       Port address
140  * @param[in]  regad       Register address
141  * @param[in]  data        Data to write
142  *
143  * @retval 0 If successful.
144  * @retval -EIO General input / output error.
145  * @retval -ETIMEDOUT If transaction timedout on the bus
146  * @retval -ENOSYS if write is not supported
147  */
148 __syscall int mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad,
149 			 uint16_t data);
150 
z_impl_mdio_write(const struct device * dev,uint8_t prtad,uint8_t regad,uint16_t data)151 static inline int z_impl_mdio_write(const struct device *dev, uint8_t prtad,
152 				    uint8_t regad, uint16_t data)
153 {
154 	const struct mdio_driver_api *api =
155 		(const struct mdio_driver_api *)dev->api;
156 
157 	if (api->write == NULL) {
158 		return -ENOSYS;
159 	}
160 
161 	return api->write(dev, prtad, regad, data);
162 }
163 
164 /**
165  * @brief      Read from MDIO Bus using Clause 45 access
166  *
167  * This routine provides an interface to perform a read on the MDIO bus using
168  * IEEE 802.3 Clause 45 access.
169  *
170  * @param[in]  dev         Pointer to the device structure for the controller
171  * @param[in]  prtad       Port address
172  * @param[in]  devad       Device address
173  * @param[in]  regad       Register address
174  * @param      data        Pointer to receive read data
175  *
176  * @retval 0 If successful.
177  * @retval -EIO General input / output error.
178  * @retval -ETIMEDOUT If transaction timedout on the bus
179  * @retval -ENOSYS if write using Clause 45 access is not supported
180  */
181 __syscall int mdio_read_c45(const struct device *dev, uint8_t prtad,
182 			    uint8_t devad, uint16_t regad, uint16_t *data);
183 
z_impl_mdio_read_c45(const struct device * dev,uint8_t prtad,uint8_t devad,uint16_t regad,uint16_t * data)184 static inline int z_impl_mdio_read_c45(const struct device *dev, uint8_t prtad,
185 				       uint8_t devad, uint16_t regad,
186 				       uint16_t *data)
187 {
188 	const struct mdio_driver_api *api =
189 		(const struct mdio_driver_api *)dev->api;
190 
191 	if (api->read_c45 == NULL) {
192 		return -ENOSYS;
193 	}
194 
195 	return api->read_c45(dev, prtad, devad, regad, data);
196 }
197 
198 /**
199  * @brief      Write to MDIO bus using Clause 45 access
200  *
201  * This routine provides an interface to perform a write on the MDIO bus using
202  * IEEE 802.3 Clause 45 access.
203  *
204  * @param[in]  dev         Pointer to the device structure for the controller
205  * @param[in]  prtad       Port address
206  * @param[in]  devad       Device address
207  * @param[in]  regad       Register address
208  * @param[in]  data        Data to write
209  *
210  * @retval 0 If successful.
211  * @retval -EIO General input / output error.
212  * @retval -ETIMEDOUT If transaction timedout on the bus
213  * @retval -ENOSYS if write using Clause 45 access is not supported
214  */
215 __syscall int mdio_write_c45(const struct device *dev, uint8_t prtad,
216 			     uint8_t devad, uint16_t regad, uint16_t data);
217 
z_impl_mdio_write_c45(const struct device * dev,uint8_t prtad,uint8_t devad,uint16_t regad,uint16_t data)218 static inline int z_impl_mdio_write_c45(const struct device *dev, uint8_t prtad,
219 					uint8_t devad, uint16_t regad,
220 					uint16_t data)
221 {
222 	const struct mdio_driver_api *api =
223 		(const struct mdio_driver_api *)dev->api;
224 
225 	if (api->write_c45 == NULL) {
226 		return -ENOSYS;
227 	}
228 
229 	return api->write_c45(dev, prtad, devad, regad, data);
230 }
231 
232 #ifdef __cplusplus
233 }
234 #endif
235 
236 /**
237  * @}
238  */
239 
240 #include <zephyr/syscalls/mdio.h>
241 
242 #endif /* ZEPHYR_INCLUDE_DRIVERS_MDIO_H_ */
243