1*72e5016fSJean-Jacques Hiblot /* 2*72e5016fSJean-Jacques Hiblot * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 3*72e5016fSJean-Jacques Hiblot * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> 4*72e5016fSJean-Jacques Hiblot * 5*72e5016fSJean-Jacques Hiblot * SPDX-License-Identifier: GPL-2.0+ 6*72e5016fSJean-Jacques Hiblot */ 7*72e5016fSJean-Jacques Hiblot 8*72e5016fSJean-Jacques Hiblot #ifndef __GENERIC_PHY_H 9*72e5016fSJean-Jacques Hiblot #define __GENERIC_PHY_H 10*72e5016fSJean-Jacques Hiblot 11*72e5016fSJean-Jacques Hiblot 12*72e5016fSJean-Jacques Hiblot /** 13*72e5016fSJean-Jacques Hiblot * struct phy - A handle to (allowing control of) a single phy port. 14*72e5016fSJean-Jacques Hiblot * 15*72e5016fSJean-Jacques Hiblot * Clients provide storage for phy handles. The content of the structure is 16*72e5016fSJean-Jacques Hiblot * managed solely by the PHY API and PHY drivers. A phy struct is 17*72e5016fSJean-Jacques Hiblot * initialized by "get"ing the phy struct. The phy struct is passed to all 18*72e5016fSJean-Jacques Hiblot * other phy APIs to identify which PHY port to operate upon. 19*72e5016fSJean-Jacques Hiblot * 20*72e5016fSJean-Jacques Hiblot * @dev: The device which implements the PHY port. 21*72e5016fSJean-Jacques Hiblot * @id: The PHY ID within the provider. 22*72e5016fSJean-Jacques Hiblot * 23*72e5016fSJean-Jacques Hiblot */ 24*72e5016fSJean-Jacques Hiblot struct phy { 25*72e5016fSJean-Jacques Hiblot struct udevice *dev; 26*72e5016fSJean-Jacques Hiblot unsigned long id; 27*72e5016fSJean-Jacques Hiblot }; 28*72e5016fSJean-Jacques Hiblot 29*72e5016fSJean-Jacques Hiblot /* 30*72e5016fSJean-Jacques Hiblot * struct udevice_ops - set of function pointers for phy operations 31*72e5016fSJean-Jacques Hiblot * @init: operation to be performed for initializing phy (optional) 32*72e5016fSJean-Jacques Hiblot * @exit: operation to be performed while exiting (optional) 33*72e5016fSJean-Jacques Hiblot * @reset: reset the phy (optional). 34*72e5016fSJean-Jacques Hiblot * @power_on: powering on the phy (optional) 35*72e5016fSJean-Jacques Hiblot * @power_off: powering off the phy (optional) 36*72e5016fSJean-Jacques Hiblot */ 37*72e5016fSJean-Jacques Hiblot struct phy_ops { 38*72e5016fSJean-Jacques Hiblot /** 39*72e5016fSJean-Jacques Hiblot * of_xlate - Translate a client's device-tree (OF) phy specifier. 40*72e5016fSJean-Jacques Hiblot * 41*72e5016fSJean-Jacques Hiblot * The PHY core calls this function as the first step in implementing 42*72e5016fSJean-Jacques Hiblot * a client's generic_phy_get_by_*() call. 43*72e5016fSJean-Jacques Hiblot * 44*72e5016fSJean-Jacques Hiblot * If this function pointer is set to NULL, the PHY core will use a 45*72e5016fSJean-Jacques Hiblot * default implementation, which assumes #phy-cells = <0> or 46*72e5016fSJean-Jacques Hiblot * #phy-cells = <1>, and in the later case that the DT cell 47*72e5016fSJean-Jacques Hiblot * contains a simple integer PHY port ID. 48*72e5016fSJean-Jacques Hiblot * 49*72e5016fSJean-Jacques Hiblot * @phy: The phy struct to hold the translation result. 50*72e5016fSJean-Jacques Hiblot * @args: The phy specifier values from device tree. 51*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code. 52*72e5016fSJean-Jacques Hiblot */ 53*72e5016fSJean-Jacques Hiblot int (*of_xlate)(struct phy *phy, 54*72e5016fSJean-Jacques Hiblot struct fdtdec_phandle_args *args); 55*72e5016fSJean-Jacques Hiblot 56*72e5016fSJean-Jacques Hiblot /** 57*72e5016fSJean-Jacques Hiblot * init - initialize the hardware. 58*72e5016fSJean-Jacques Hiblot * 59*72e5016fSJean-Jacques Hiblot * Hardware intialization should not be done in during probe() but 60*72e5016fSJean-Jacques Hiblot * should be implemented in this init() function. It could be starting 61*72e5016fSJean-Jacques Hiblot * PLL, taking a controller out of reset, routing, etc. This function 62*72e5016fSJean-Jacques Hiblot * is typically called only once per PHY port. 63*72e5016fSJean-Jacques Hiblot * If power_on() is not implemented, it must power up the phy. 64*72e5016fSJean-Jacques Hiblot * 65*72e5016fSJean-Jacques Hiblot * @phy: the PHY port to initialize 66*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code. 67*72e5016fSJean-Jacques Hiblot */ 68*72e5016fSJean-Jacques Hiblot int (*init)(struct phy *phy); 69*72e5016fSJean-Jacques Hiblot 70*72e5016fSJean-Jacques Hiblot /** 71*72e5016fSJean-Jacques Hiblot * exit - de-initialize the PHY device 72*72e5016fSJean-Jacques Hiblot * 73*72e5016fSJean-Jacques Hiblot * Hardware de-intialization should be done here. Every step done in 74*72e5016fSJean-Jacques Hiblot * init() should be undone here. 75*72e5016fSJean-Jacques Hiblot * This could be used to suspend the phy to reduce power consumption or 76*72e5016fSJean-Jacques Hiblot * to put the phy in a known condition before booting the OS (though it 77*72e5016fSJean-Jacques Hiblot * is NOT called automatically before booting the OS) 78*72e5016fSJean-Jacques Hiblot * If power_off() is not implemented, it must power down the phy. 79*72e5016fSJean-Jacques Hiblot * 80*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be de-initialized 81*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 82*72e5016fSJean-Jacques Hiblot */ 83*72e5016fSJean-Jacques Hiblot int (*exit)(struct phy *phy); 84*72e5016fSJean-Jacques Hiblot 85*72e5016fSJean-Jacques Hiblot /** 86*72e5016fSJean-Jacques Hiblot * reset - resets a PHY device without shutting down 87*72e5016fSJean-Jacques Hiblot * 88*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be reset 89*72e5016fSJean-Jacques Hiblot * 90*72e5016fSJean-Jacques Hiblot * During runtime, the PHY may need to be reset in order to 91*72e5016fSJean-Jacques Hiblot * re-establish connection etc without being shut down or exit. 92*72e5016fSJean-Jacques Hiblot * 93*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 94*72e5016fSJean-Jacques Hiblot */ 95*72e5016fSJean-Jacques Hiblot int (*reset)(struct phy *phy); 96*72e5016fSJean-Jacques Hiblot 97*72e5016fSJean-Jacques Hiblot /** 98*72e5016fSJean-Jacques Hiblot * power_on - power on a PHY device 99*72e5016fSJean-Jacques Hiblot * 100*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered on 101*72e5016fSJean-Jacques Hiblot * 102*72e5016fSJean-Jacques Hiblot * During runtime, the PHY may need to be powered on or off several 103*72e5016fSJean-Jacques Hiblot * times. This function is used to power on the PHY. It relies on the 104*72e5016fSJean-Jacques Hiblot * setup done in init(). If init() is not implemented, it must take care 105*72e5016fSJean-Jacques Hiblot * of setting up the context (PLLs, ...) 106*72e5016fSJean-Jacques Hiblot * 107*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 108*72e5016fSJean-Jacques Hiblot */ 109*72e5016fSJean-Jacques Hiblot int (*power_on)(struct phy *phy); 110*72e5016fSJean-Jacques Hiblot 111*72e5016fSJean-Jacques Hiblot /** 112*72e5016fSJean-Jacques Hiblot * power_off - power off a PHY device 113*72e5016fSJean-Jacques Hiblot * 114*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered off 115*72e5016fSJean-Jacques Hiblot * 116*72e5016fSJean-Jacques Hiblot * During runtime, the PHY may need to be powered on or off several 117*72e5016fSJean-Jacques Hiblot * times. This function is used to power off the PHY. Except if 118*72e5016fSJean-Jacques Hiblot * init()/deinit() are not implemented, it must not de-initialize 119*72e5016fSJean-Jacques Hiblot * everything. 120*72e5016fSJean-Jacques Hiblot * 121*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 122*72e5016fSJean-Jacques Hiblot */ 123*72e5016fSJean-Jacques Hiblot int (*power_off)(struct phy *phy); 124*72e5016fSJean-Jacques Hiblot }; 125*72e5016fSJean-Jacques Hiblot 126*72e5016fSJean-Jacques Hiblot 127*72e5016fSJean-Jacques Hiblot /** 128*72e5016fSJean-Jacques Hiblot * generic_phy_init() - initialize the PHY port 129*72e5016fSJean-Jacques Hiblot * 130*72e5016fSJean-Jacques Hiblot * @phy: the PHY port to initialize 131*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 132*72e5016fSJean-Jacques Hiblot */ 133*72e5016fSJean-Jacques Hiblot int generic_phy_init(struct phy *phy); 134*72e5016fSJean-Jacques Hiblot 135*72e5016fSJean-Jacques Hiblot /** 136*72e5016fSJean-Jacques Hiblot * generic_phy_init() - de-initialize the PHY device 137*72e5016fSJean-Jacques Hiblot * 138*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be de-initialized 139*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 140*72e5016fSJean-Jacques Hiblot */ 141*72e5016fSJean-Jacques Hiblot int generic_phy_exit(struct phy *phy); 142*72e5016fSJean-Jacques Hiblot 143*72e5016fSJean-Jacques Hiblot /** 144*72e5016fSJean-Jacques Hiblot * generic_phy_reset() - resets a PHY device without shutting down 145*72e5016fSJean-Jacques Hiblot * 146*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be reset 147*72e5016fSJean-Jacques Hiblot *@return 0 if OK, or a negative error code 148*72e5016fSJean-Jacques Hiblot */ 149*72e5016fSJean-Jacques Hiblot int generic_phy_reset(struct phy *phy); 150*72e5016fSJean-Jacques Hiblot 151*72e5016fSJean-Jacques Hiblot /** 152*72e5016fSJean-Jacques Hiblot * generic_phy_power_on() - power on a PHY device 153*72e5016fSJean-Jacques Hiblot * 154*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered on 155*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 156*72e5016fSJean-Jacques Hiblot */ 157*72e5016fSJean-Jacques Hiblot int generic_phy_power_on(struct phy *phy); 158*72e5016fSJean-Jacques Hiblot 159*72e5016fSJean-Jacques Hiblot /** 160*72e5016fSJean-Jacques Hiblot * generic_phy_power_off() - power off a PHY device 161*72e5016fSJean-Jacques Hiblot * 162*72e5016fSJean-Jacques Hiblot * @phy: PHY port to be powered off 163*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 164*72e5016fSJean-Jacques Hiblot */ 165*72e5016fSJean-Jacques Hiblot int generic_phy_power_off(struct phy *phy); 166*72e5016fSJean-Jacques Hiblot 167*72e5016fSJean-Jacques Hiblot 168*72e5016fSJean-Jacques Hiblot /** 169*72e5016fSJean-Jacques Hiblot * generic_phy_get_by_index() - Get a PHY device by integer index. 170*72e5016fSJean-Jacques Hiblot * 171*72e5016fSJean-Jacques Hiblot * @user: the client device 172*72e5016fSJean-Jacques Hiblot * @index: The index in the list of available PHYs 173*72e5016fSJean-Jacques Hiblot * @phy: A pointer to the PHY port 174*72e5016fSJean-Jacques Hiblot * 175*72e5016fSJean-Jacques Hiblot * This looks up a PHY device for a client device based on its position in the 176*72e5016fSJean-Jacques Hiblot * list of the possible PHYs. 177*72e5016fSJean-Jacques Hiblot * 178*72e5016fSJean-Jacques Hiblot * example: 179*72e5016fSJean-Jacques Hiblot * usb1: usb_otg_ss@xxx { 180*72e5016fSJean-Jacques Hiblot * compatible = "xxx"; 181*72e5016fSJean-Jacques Hiblot * reg = <xxx>; 182*72e5016fSJean-Jacques Hiblot * . 183*72e5016fSJean-Jacques Hiblot * . 184*72e5016fSJean-Jacques Hiblot * phys = <&usb2_phy>, <&usb3_phy>; 185*72e5016fSJean-Jacques Hiblot * . 186*72e5016fSJean-Jacques Hiblot * . 187*72e5016fSJean-Jacques Hiblot * }; 188*72e5016fSJean-Jacques Hiblot * the USB2 phy can be accessed by passing index '0' and the USB3 phy can 189*72e5016fSJean-Jacques Hiblot * be accessed by passing index '1' 190*72e5016fSJean-Jacques Hiblot * 191*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 192*72e5016fSJean-Jacques Hiblot */ 193*72e5016fSJean-Jacques Hiblot int generic_phy_get_by_index(struct udevice *user, int index, 194*72e5016fSJean-Jacques Hiblot struct phy *phy); 195*72e5016fSJean-Jacques Hiblot 196*72e5016fSJean-Jacques Hiblot /** 197*72e5016fSJean-Jacques Hiblot * generic_phy_get_by_name() - Get a PHY device by its name. 198*72e5016fSJean-Jacques Hiblot * 199*72e5016fSJean-Jacques Hiblot * @user: the client device 200*72e5016fSJean-Jacques Hiblot * @phy_name: The name of the PHY in the list of possible PHYs 201*72e5016fSJean-Jacques Hiblot * @phy: A pointer to the PHY port 202*72e5016fSJean-Jacques Hiblot * 203*72e5016fSJean-Jacques Hiblot * This looks up a PHY device for a client device in the 204*72e5016fSJean-Jacques Hiblot * list of the possible PHYs based on its name. 205*72e5016fSJean-Jacques Hiblot * 206*72e5016fSJean-Jacques Hiblot * example: 207*72e5016fSJean-Jacques Hiblot * usb1: usb_otg_ss@xxx { 208*72e5016fSJean-Jacques Hiblot * compatible = "xxx"; 209*72e5016fSJean-Jacques Hiblot * reg = <xxx>; 210*72e5016fSJean-Jacques Hiblot * . 211*72e5016fSJean-Jacques Hiblot * . 212*72e5016fSJean-Jacques Hiblot * phys = <&usb2_phy>, <&usb3_phy>; 213*72e5016fSJean-Jacques Hiblot * phy-names = "usb2phy", "usb3phy"; 214*72e5016fSJean-Jacques Hiblot * . 215*72e5016fSJean-Jacques Hiblot * . 216*72e5016fSJean-Jacques Hiblot * }; 217*72e5016fSJean-Jacques Hiblot * the USB3 phy can be accessed using "usb3phy", and USB2 by using "usb2phy" 218*72e5016fSJean-Jacques Hiblot * 219*72e5016fSJean-Jacques Hiblot * @return 0 if OK, or a negative error code 220*72e5016fSJean-Jacques Hiblot */ 221*72e5016fSJean-Jacques Hiblot int generic_phy_get_by_name(struct udevice *user, const char *phy_name, 222*72e5016fSJean-Jacques Hiblot struct phy *phy); 223*72e5016fSJean-Jacques Hiblot 224*72e5016fSJean-Jacques Hiblot #endif /*__GENERIC_PHY_H */ 225