1*86322f59SJean-Jacques Hiblot /* 2*86322f59SJean-Jacques Hiblot * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 3*86322f59SJean-Jacques Hiblot * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> 4*86322f59SJean-Jacques Hiblot * 5*86322f59SJean-Jacques Hiblot * SPDX-License-Identifier: GPL-2.0+ 6*86322f59SJean-Jacques Hiblot */ 7*86322f59SJean-Jacques Hiblot 8*86322f59SJean-Jacques Hiblot #include <common.h> 9*86322f59SJean-Jacques Hiblot #include <dm.h> 10*86322f59SJean-Jacques Hiblot #include <generic-phy.h> 11*86322f59SJean-Jacques Hiblot 12*86322f59SJean-Jacques Hiblot DECLARE_GLOBAL_DATA_PTR; 13*86322f59SJean-Jacques Hiblot 14*86322f59SJean-Jacques Hiblot struct sandbox_phy_priv { 15*86322f59SJean-Jacques Hiblot bool initialized; 16*86322f59SJean-Jacques Hiblot bool on; 17*86322f59SJean-Jacques Hiblot bool broken; 18*86322f59SJean-Jacques Hiblot }; 19*86322f59SJean-Jacques Hiblot 20*86322f59SJean-Jacques Hiblot static int sandbox_phy_power_on(struct phy *phy) 21*86322f59SJean-Jacques Hiblot { 22*86322f59SJean-Jacques Hiblot struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); 23*86322f59SJean-Jacques Hiblot 24*86322f59SJean-Jacques Hiblot if (!priv->initialized) 25*86322f59SJean-Jacques Hiblot return -EIO; 26*86322f59SJean-Jacques Hiblot 27*86322f59SJean-Jacques Hiblot if (priv->broken) 28*86322f59SJean-Jacques Hiblot return -EIO; 29*86322f59SJean-Jacques Hiblot 30*86322f59SJean-Jacques Hiblot priv->on = true; 31*86322f59SJean-Jacques Hiblot 32*86322f59SJean-Jacques Hiblot return 0; 33*86322f59SJean-Jacques Hiblot } 34*86322f59SJean-Jacques Hiblot 35*86322f59SJean-Jacques Hiblot static int sandbox_phy_power_off(struct phy *phy) 36*86322f59SJean-Jacques Hiblot { 37*86322f59SJean-Jacques Hiblot struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); 38*86322f59SJean-Jacques Hiblot 39*86322f59SJean-Jacques Hiblot if (!priv->initialized) 40*86322f59SJean-Jacques Hiblot return -EIO; 41*86322f59SJean-Jacques Hiblot 42*86322f59SJean-Jacques Hiblot if (priv->broken) 43*86322f59SJean-Jacques Hiblot return -EIO; 44*86322f59SJean-Jacques Hiblot 45*86322f59SJean-Jacques Hiblot /* 46*86322f59SJean-Jacques Hiblot * for validation purpose, let's says that power off 47*86322f59SJean-Jacques Hiblot * works only for PHY 0 48*86322f59SJean-Jacques Hiblot */ 49*86322f59SJean-Jacques Hiblot if (phy->id) 50*86322f59SJean-Jacques Hiblot return -EIO; 51*86322f59SJean-Jacques Hiblot 52*86322f59SJean-Jacques Hiblot priv->on = false; 53*86322f59SJean-Jacques Hiblot 54*86322f59SJean-Jacques Hiblot return 0; 55*86322f59SJean-Jacques Hiblot } 56*86322f59SJean-Jacques Hiblot 57*86322f59SJean-Jacques Hiblot static int sandbox_phy_init(struct phy *phy) 58*86322f59SJean-Jacques Hiblot { 59*86322f59SJean-Jacques Hiblot struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); 60*86322f59SJean-Jacques Hiblot 61*86322f59SJean-Jacques Hiblot priv->initialized = true; 62*86322f59SJean-Jacques Hiblot priv->on = true; 63*86322f59SJean-Jacques Hiblot 64*86322f59SJean-Jacques Hiblot return 0; 65*86322f59SJean-Jacques Hiblot } 66*86322f59SJean-Jacques Hiblot 67*86322f59SJean-Jacques Hiblot static int sandbox_phy_exit(struct phy *phy) 68*86322f59SJean-Jacques Hiblot { 69*86322f59SJean-Jacques Hiblot struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); 70*86322f59SJean-Jacques Hiblot 71*86322f59SJean-Jacques Hiblot priv->initialized = false; 72*86322f59SJean-Jacques Hiblot priv->on = false; 73*86322f59SJean-Jacques Hiblot 74*86322f59SJean-Jacques Hiblot return 0; 75*86322f59SJean-Jacques Hiblot } 76*86322f59SJean-Jacques Hiblot 77*86322f59SJean-Jacques Hiblot static int sandbox_phy_probe(struct udevice *dev) 78*86322f59SJean-Jacques Hiblot { 79*86322f59SJean-Jacques Hiblot struct sandbox_phy_priv *priv = dev_get_priv(dev); 80*86322f59SJean-Jacques Hiblot 81*86322f59SJean-Jacques Hiblot priv->initialized = false; 82*86322f59SJean-Jacques Hiblot priv->on = false; 83*86322f59SJean-Jacques Hiblot priv->broken = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), 84*86322f59SJean-Jacques Hiblot "broken"); 85*86322f59SJean-Jacques Hiblot 86*86322f59SJean-Jacques Hiblot return 0; 87*86322f59SJean-Jacques Hiblot } 88*86322f59SJean-Jacques Hiblot 89*86322f59SJean-Jacques Hiblot static struct phy_ops sandbox_phy_ops = { 90*86322f59SJean-Jacques Hiblot .power_on = sandbox_phy_power_on, 91*86322f59SJean-Jacques Hiblot .power_off = sandbox_phy_power_off, 92*86322f59SJean-Jacques Hiblot .init = sandbox_phy_init, 93*86322f59SJean-Jacques Hiblot .exit = sandbox_phy_exit, 94*86322f59SJean-Jacques Hiblot }; 95*86322f59SJean-Jacques Hiblot 96*86322f59SJean-Jacques Hiblot static const struct udevice_id sandbox_phy_ids[] = { 97*86322f59SJean-Jacques Hiblot { .compatible = "sandbox,phy" }, 98*86322f59SJean-Jacques Hiblot { } 99*86322f59SJean-Jacques Hiblot }; 100*86322f59SJean-Jacques Hiblot 101*86322f59SJean-Jacques Hiblot U_BOOT_DRIVER(phy_sandbox) = { 102*86322f59SJean-Jacques Hiblot .name = "phy_sandbox", 103*86322f59SJean-Jacques Hiblot .id = UCLASS_PHY, 104*86322f59SJean-Jacques Hiblot .of_match = sandbox_phy_ids, 105*86322f59SJean-Jacques Hiblot .ops = &sandbox_phy_ops, 106*86322f59SJean-Jacques Hiblot .probe = sandbox_phy_probe, 107*86322f59SJean-Jacques Hiblot .priv_auto_alloc_size = sizeof(struct sandbox_phy_priv), 108*86322f59SJean-Jacques Hiblot }; 109