172e5016fSJean-Jacques Hiblot /* 272e5016fSJean-Jacques Hiblot * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 372e5016fSJean-Jacques Hiblot * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> 472e5016fSJean-Jacques Hiblot * 572e5016fSJean-Jacques Hiblot * SPDX-License-Identifier: GPL-2.0+ 672e5016fSJean-Jacques Hiblot */ 772e5016fSJean-Jacques Hiblot 872e5016fSJean-Jacques Hiblot #ifndef __GENERIC_PHY_H 972e5016fSJean-Jacques Hiblot #define __GENERIC_PHY_H 1072e5016fSJean-Jacques Hiblot 1172e5016fSJean-Jacques Hiblot 1272e5016fSJean-Jacques Hiblot /** 1372e5016fSJean-Jacques Hiblot * struct phy - A handle to (allowing control of) a single phy port. 1472e5016fSJean-Jacques Hiblot * 1572e5016fSJean-Jacques Hiblot * Clients provide storage for phy handles. The content of the structure is 1672e5016fSJean-Jacques Hiblot * managed solely by the PHY API and PHY drivers. A phy struct is 1772e5016fSJean-Jacques Hiblot * initialized by "get"ing the phy struct. The phy struct is passed to all 1872e5016fSJean-Jacques Hiblot * other phy APIs to identify which PHY port to operate upon. 1972e5016fSJean-Jacques Hiblot * 2072e5016fSJean-Jacques Hiblot * @dev: The device which implements the PHY port. 2172e5016fSJean-Jacques Hiblot * @id: The PHY ID within the provider. 2272e5016fSJean-Jacques Hiblot * 2372e5016fSJean-Jacques Hiblot */ 2472e5016fSJean-Jacques Hiblot struct phy { 2572e5016fSJean-Jacques Hiblot struct udevice *dev; 2672e5016fSJean-Jacques Hiblot unsigned long id; 2772e5016fSJean-Jacques Hiblot }; 2872e5016fSJean-Jacques Hiblot 2972e5016fSJean-Jacques Hiblot /* 3072e5016fSJean-Jacques Hiblot * struct udevice_ops - set of function pointers for phy operations 3172e5016fSJean-Jacques Hiblot * @init: operation to be performed for initializing phy (optional) 3272e5016fSJean-Jacques Hiblot * @exit: operation to be performed while exiting (optional) 3372e5016fSJean-Jacques Hiblot * @reset: reset the phy (optional). 3472e5016fSJean-Jacques Hiblot * @power_on: powering on the phy (optional) 3572e5016fSJean-Jacques Hiblot * @power_off: powering off the phy (optional) 3672e5016fSJean-Jacques Hiblot */ 3772e5016fSJean-Jacques Hiblot struct phy_ops { 3872e5016fSJean-Jacques Hiblot /** 3972e5016fSJean-Jacques Hiblot * of_xlate - Translate a client's device-tree (OF) phy specifier. 4072e5016fSJean-Jacques Hiblot * 4172e5016fSJean-Jacques Hiblot * The PHY core calls this function as the first step in implementing 4272e5016fSJean-Jacques Hiblot * a client's generic_phy_get_by_*() call. 4372e5016fSJean-Jacques Hiblot * 4472e5016fSJean-Jacques Hiblot * If this function pointer is set to NULL, the PHY core will use a 4572e5016fSJean-Jacques Hiblot * default implementation, which assumes #phy-cells = <0> or 4672e5016fSJean-Jacques Hiblot * #phy-cells = <1>, and in the later case that the DT cell 4772e5016fSJean-Jacques Hiblot * contains a simple integer PHY port ID. 4872e5016fSJean-Jacques Hiblot * 4972e5016fSJean-Jacques Hiblot * @phy: The phy struct to hold the translation result. 5072e5016fSJean-Jacques Hiblot * @args: The phy specifier values from device tree. 5172e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code. 5272e5016fSJean-Jacques Hiblot */ 5323558bb6SSimon Glass int (*of_xlate)(struct phy *phy, struct ofnode_phandle_args *args); 5472e5016fSJean-Jacques Hiblot 5572e5016fSJean-Jacques Hiblot /** 5672e5016fSJean-Jacques Hiblot * init - initialize the hardware. 5772e5016fSJean-Jacques Hiblot * 5872e5016fSJean-Jacques Hiblot * Hardware intialization should not be done in during probe() but 5972e5016fSJean-Jacques Hiblot * should be implemented in this init() function. It could be starting 6072e5016fSJean-Jacques Hiblot * PLL, taking a controller out of reset, routing, etc. This function 6172e5016fSJean-Jacques Hiblot * is typically called only once per PHY port. 6272e5016fSJean-Jacques Hiblot * If power_on() is not implemented, it must power up the phy. 6372e5016fSJean-Jacques Hiblot * 6472e5016fSJean-Jacques Hiblot * @phy: the PHY port to initialize 6572e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code. 6672e5016fSJean-Jacques Hiblot */ 6772e5016fSJean-Jacques Hiblot int (*init)(struct phy *phy); 6872e5016fSJean-Jacques Hiblot 6972e5016fSJean-Jacques Hiblot /** 7072e5016fSJean-Jacques Hiblot * exit - de-initialize the PHY device 7172e5016fSJean-Jacques Hiblot * 7272e5016fSJean-Jacques Hiblot * Hardware de-intialization should be done here. Every step done in 7372e5016fSJean-Jacques Hiblot * init() should be undone here. 7472e5016fSJean-Jacques Hiblot * This could be used to suspend the phy to reduce power consumption or 7572e5016fSJean-Jacques Hiblot * to put the phy in a known condition before booting the OS (though it 7672e5016fSJean-Jacques Hiblot * is NOT called automatically before booting the OS) 7772e5016fSJean-Jacques Hiblot * If power_off() is not implemented, it must power down the phy. 7872e5016fSJean-Jacques Hiblot * 7972e5016fSJean-Jacques Hiblot * @phy: PHY port to be de-initialized 8072e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 8172e5016fSJean-Jacques Hiblot */ 8272e5016fSJean-Jacques Hiblot int (*exit)(struct phy *phy); 8372e5016fSJean-Jacques Hiblot 8472e5016fSJean-Jacques Hiblot /** 8572e5016fSJean-Jacques Hiblot * reset - resets a PHY device without shutting down 8672e5016fSJean-Jacques Hiblot * 8772e5016fSJean-Jacques Hiblot * @phy: PHY port to be reset 8872e5016fSJean-Jacques Hiblot * 8972e5016fSJean-Jacques Hiblot * During runtime, the PHY may need to be reset in order to 9072e5016fSJean-Jacques Hiblot * re-establish connection etc without being shut down or exit. 9172e5016fSJean-Jacques Hiblot * 9272e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 9372e5016fSJean-Jacques Hiblot */ 9472e5016fSJean-Jacques Hiblot int (*reset)(struct phy *phy); 9572e5016fSJean-Jacques Hiblot 9672e5016fSJean-Jacques Hiblot /** 9772e5016fSJean-Jacques Hiblot * power_on - power on a PHY device 9872e5016fSJean-Jacques Hiblot * 9972e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered on 10072e5016fSJean-Jacques Hiblot * 10172e5016fSJean-Jacques Hiblot * During runtime, the PHY may need to be powered on or off several 10272e5016fSJean-Jacques Hiblot * times. This function is used to power on the PHY. It relies on the 10372e5016fSJean-Jacques Hiblot * setup done in init(). If init() is not implemented, it must take care 10472e5016fSJean-Jacques Hiblot * of setting up the context (PLLs, ...) 10572e5016fSJean-Jacques Hiblot * 10672e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 10772e5016fSJean-Jacques Hiblot */ 10872e5016fSJean-Jacques Hiblot int (*power_on)(struct phy *phy); 10972e5016fSJean-Jacques Hiblot 11072e5016fSJean-Jacques Hiblot /** 11172e5016fSJean-Jacques Hiblot * power_off - power off a PHY device 11272e5016fSJean-Jacques Hiblot * 11372e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered off 11472e5016fSJean-Jacques Hiblot * 11572e5016fSJean-Jacques Hiblot * During runtime, the PHY may need to be powered on or off several 11672e5016fSJean-Jacques Hiblot * times. This function is used to power off the PHY. Except if 11772e5016fSJean-Jacques Hiblot * init()/deinit() are not implemented, it must not de-initialize 11872e5016fSJean-Jacques Hiblot * everything. 11972e5016fSJean-Jacques Hiblot * 12072e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 12172e5016fSJean-Jacques Hiblot */ 12272e5016fSJean-Jacques Hiblot int (*power_off)(struct phy *phy); 12372e5016fSJean-Jacques Hiblot }; 12472e5016fSJean-Jacques Hiblot 125d9fb7becSPatrice Chotard #ifdef CONFIG_PHY 12672e5016fSJean-Jacques Hiblot 12772e5016fSJean-Jacques Hiblot /** 12872e5016fSJean-Jacques Hiblot * generic_phy_init() - initialize the PHY port 12972e5016fSJean-Jacques Hiblot * 13072e5016fSJean-Jacques Hiblot * @phy: the PHY port to initialize 13172e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 13272e5016fSJean-Jacques Hiblot */ 13372e5016fSJean-Jacques Hiblot int generic_phy_init(struct phy *phy); 13472e5016fSJean-Jacques Hiblot 13572e5016fSJean-Jacques Hiblot /** 13672e5016fSJean-Jacques Hiblot * generic_phy_init() - de-initialize the PHY device 13772e5016fSJean-Jacques Hiblot * 13872e5016fSJean-Jacques Hiblot * @phy: PHY port to be de-initialized 13972e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 14072e5016fSJean-Jacques Hiblot */ 14172e5016fSJean-Jacques Hiblot int generic_phy_exit(struct phy *phy); 14272e5016fSJean-Jacques Hiblot 14372e5016fSJean-Jacques Hiblot /** 14472e5016fSJean-Jacques Hiblot * generic_phy_reset() - resets a PHY device without shutting down 14572e5016fSJean-Jacques Hiblot * 14672e5016fSJean-Jacques Hiblot * @phy: PHY port to be reset 14772e5016fSJean-Jacques Hiblot *@return 0 if OK, or a negative error code 14872e5016fSJean-Jacques Hiblot */ 14972e5016fSJean-Jacques Hiblot int generic_phy_reset(struct phy *phy); 15072e5016fSJean-Jacques Hiblot 15172e5016fSJean-Jacques Hiblot /** 15272e5016fSJean-Jacques Hiblot * generic_phy_power_on() - power on a PHY device 15372e5016fSJean-Jacques Hiblot * 15472e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered on 15572e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 15672e5016fSJean-Jacques Hiblot */ 15772e5016fSJean-Jacques Hiblot int generic_phy_power_on(struct phy *phy); 15872e5016fSJean-Jacques Hiblot 15972e5016fSJean-Jacques Hiblot /** 16072e5016fSJean-Jacques Hiblot * generic_phy_power_off() - power off a PHY device 16172e5016fSJean-Jacques Hiblot * 16272e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered off 16372e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 16472e5016fSJean-Jacques Hiblot */ 16572e5016fSJean-Jacques Hiblot int generic_phy_power_off(struct phy *phy); 16672e5016fSJean-Jacques Hiblot 16772e5016fSJean-Jacques Hiblot 16872e5016fSJean-Jacques Hiblot /** 16972e5016fSJean-Jacques Hiblot * generic_phy_get_by_index() - Get a PHY device by integer index. 17072e5016fSJean-Jacques Hiblot * 17172e5016fSJean-Jacques Hiblot * @user: the client device 17272e5016fSJean-Jacques Hiblot * @index: The index in the list of available PHYs 17372e5016fSJean-Jacques Hiblot * @phy: A pointer to the PHY port 17472e5016fSJean-Jacques Hiblot * 17572e5016fSJean-Jacques Hiblot * This looks up a PHY device for a client device based on its position in the 17672e5016fSJean-Jacques Hiblot * list of the possible PHYs. 17772e5016fSJean-Jacques Hiblot * 17872e5016fSJean-Jacques Hiblot * example: 17972e5016fSJean-Jacques Hiblot * usb1: usb_otg_ss@xxx { 18072e5016fSJean-Jacques Hiblot * compatible = "xxx"; 18172e5016fSJean-Jacques Hiblot * reg = <xxx>; 18272e5016fSJean-Jacques Hiblot * . 18372e5016fSJean-Jacques Hiblot * . 18472e5016fSJean-Jacques Hiblot * phys = <&usb2_phy>, <&usb3_phy>; 18572e5016fSJean-Jacques Hiblot * . 18672e5016fSJean-Jacques Hiblot * . 18772e5016fSJean-Jacques Hiblot * }; 18872e5016fSJean-Jacques Hiblot * the USB2 phy can be accessed by passing index '0' and the USB3 phy can 18972e5016fSJean-Jacques Hiblot * be accessed by passing index '1' 19072e5016fSJean-Jacques Hiblot * 19172e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 19272e5016fSJean-Jacques Hiblot */ 19372e5016fSJean-Jacques Hiblot int generic_phy_get_by_index(struct udevice *user, int index, 19472e5016fSJean-Jacques Hiblot struct phy *phy); 19572e5016fSJean-Jacques Hiblot 19672e5016fSJean-Jacques Hiblot /** 19772e5016fSJean-Jacques Hiblot * generic_phy_get_by_name() - Get a PHY device by its name. 19872e5016fSJean-Jacques Hiblot * 19972e5016fSJean-Jacques Hiblot * @user: the client device 20072e5016fSJean-Jacques Hiblot * @phy_name: The name of the PHY in the list of possible PHYs 20172e5016fSJean-Jacques Hiblot * @phy: A pointer to the PHY port 20272e5016fSJean-Jacques Hiblot * 20372e5016fSJean-Jacques Hiblot * This looks up a PHY device for a client device in the 20472e5016fSJean-Jacques Hiblot * list of the possible PHYs based on its name. 20572e5016fSJean-Jacques Hiblot * 20672e5016fSJean-Jacques Hiblot * example: 20772e5016fSJean-Jacques Hiblot * usb1: usb_otg_ss@xxx { 20872e5016fSJean-Jacques Hiblot * compatible = "xxx"; 20972e5016fSJean-Jacques Hiblot * reg = <xxx>; 21072e5016fSJean-Jacques Hiblot * . 21172e5016fSJean-Jacques Hiblot * . 21272e5016fSJean-Jacques Hiblot * phys = <&usb2_phy>, <&usb3_phy>; 21372e5016fSJean-Jacques Hiblot * phy-names = "usb2phy", "usb3phy"; 21472e5016fSJean-Jacques Hiblot * . 21572e5016fSJean-Jacques Hiblot * . 21672e5016fSJean-Jacques Hiblot * }; 21772e5016fSJean-Jacques Hiblot * the USB3 phy can be accessed using "usb3phy", and USB2 by using "usb2phy" 21872e5016fSJean-Jacques Hiblot * 21972e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 22072e5016fSJean-Jacques Hiblot */ 22172e5016fSJean-Jacques Hiblot int generic_phy_get_by_name(struct udevice *user, const char *phy_name, 22272e5016fSJean-Jacques Hiblot struct phy *phy); 22372e5016fSJean-Jacques Hiblot 224d9fb7becSPatrice Chotard #else /* CONFIG_PHY */ 225d9fb7becSPatrice Chotard 226d9fb7becSPatrice Chotard static inline int generic_phy_init(struct phy *phy) 227d9fb7becSPatrice Chotard { 228d9fb7becSPatrice Chotard return 0; 229d9fb7becSPatrice Chotard } 230d9fb7becSPatrice Chotard 231d9fb7becSPatrice Chotard static inline int generic_phy_exit(struct phy *phy) 232d9fb7becSPatrice Chotard { 233d9fb7becSPatrice Chotard return 0; 234d9fb7becSPatrice Chotard } 235d9fb7becSPatrice Chotard 236d9fb7becSPatrice Chotard static inline int generic_phy_reset(struct phy *phy) 237d9fb7becSPatrice Chotard { 238d9fb7becSPatrice Chotard return 0; 239d9fb7becSPatrice Chotard } 240d9fb7becSPatrice Chotard 241d9fb7becSPatrice Chotard static inline int generic_phy_power_on(struct phy *phy) 242d9fb7becSPatrice Chotard { 243d9fb7becSPatrice Chotard return 0; 244d9fb7becSPatrice Chotard } 245d9fb7becSPatrice Chotard 246d9fb7becSPatrice Chotard static inline int generic_phy_power_off(struct phy *phy) 247d9fb7becSPatrice Chotard { 248d9fb7becSPatrice Chotard return 0; 249d9fb7becSPatrice Chotard } 250d9fb7becSPatrice Chotard 251d9fb7becSPatrice Chotard static inline int generic_phy_get_by_index(struct udevice *user, int index, 252d9fb7becSPatrice Chotard struct phy *phy) 253d9fb7becSPatrice Chotard { 254d9fb7becSPatrice Chotard return 0; 255d9fb7becSPatrice Chotard } 256d9fb7becSPatrice Chotard 257d9fb7becSPatrice Chotard static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_name, 258d9fb7becSPatrice Chotard struct phy *phy) 259d9fb7becSPatrice Chotard { 260d9fb7becSPatrice Chotard return 0; 261d9fb7becSPatrice Chotard } 262d9fb7becSPatrice Chotard 263d9fb7becSPatrice Chotard #endif /* CONFIG_PHY */ 264d9fb7becSPatrice Chotard 265b94888b4SPatrice Chotard /** 266b94888b4SPatrice Chotard * generic_phy_valid() - check if PHY port is valid 267b94888b4SPatrice Chotard * 268b94888b4SPatrice Chotard * @phy: the PHY port to check 269b94888b4SPatrice Chotard * @return TRUE if valid, or FALSE 270b94888b4SPatrice Chotard */ 271b94888b4SPatrice Chotard static inline bool generic_phy_valid(struct phy *phy) 272b94888b4SPatrice Chotard { 273*1bac1f39SJean-Jacques Hiblot return phy && phy->dev; 274b94888b4SPatrice Chotard } 275b94888b4SPatrice Chotard 27672e5016fSJean-Jacques Hiblot #endif /*__GENERIC_PHY_H */ 277